
麻烦前端大佬看看
原来有一个 THREE.JS 项目是一个 index.html 直接包含了 three.min.js 和一堆 js 文件。 包含 three.min.js 之后,有了一个全局的 THREE 对象 后面那一堆 js 便对 THREE 这个对象增加了一系列的函数与变量,并且互相引用
示例 EVALoader.js THREE.EVALoader = function(onLoad, url, options){ // todo something } THREE.AAA = function(){ // todo something } THREE.BBB = function(){ // todo something } 打算用 node 改写, 我能想到的方法: 就是也导出一个对象 THREE ,然后每个 js 改写 THREE 的地方,直接引用这个对象并增加函数和变量
这样可行吗?
globals.js 文件 import * as THREE from "three"; window.THREE = THREE; export default THREE; EVALoader.js 文件 import * as THREE from "globals" THREE.EVALoader = function(onLoad, url, options){ // todo something } THREE.AAA = function(){ // todo something } THREE.BBB = function(){ // todo something } 如果可行,其他文件直接从 globals 引入 THREE 就可以使用 EVALoader 这个函数?
1 okakuyang 2023 年 9 月 4 日 via iPhone 你应该想说用 es6 模块的方式来写吧?不需要 window.three = three 吧 |
3 bhbhxy 2023 年 9 月 4 日 不建议用 window.xxx 来挂载全局对象,用模块化的方式,哪里需要就哪里导入,共享数据自己实现一个简易的 vuex |
4 okakuyang 2023 年 9 月 4 日 via iPhone import { vector3 } from “three” |
5 okakuyang 2023 年 9 月 4 日 via iPhone 你要看你引入的版本是不是按模块导出的,如果不是,去找模块导出的版本,如果没有需要自己改导出 |
6 johnman OP @okakuyang 我尝试理解一下,如果 THREE.JS 是按照模块导出的。 我在文件 A 对 THREE 模块 import 之后,增加函数 C 和变量 D 。 其他文件 B 再次 import THREE 模块之后,可以执行函数 C 和读取/修改 D ? |
7 kongkx 2023 年 9 月 4 日 via iPhone import 不配 打包工具? |
8 tangchi695 2023 年 9 月 4 日 threejs 本身就打包了 esm 的版本啊 |
9 itbeihe 2023 年 9 月 4 日 多看看官方文档啊,three.js 官方支持 import 导入的。 另外扩展 three 方法看看这个: https://discourse.threejs.org/t/extending-three-objects-in-r121-module-version/20197/4 ``` import { Mesh } from 'three'; // extending an existing function 覆盖已存在方法 const originalRaycast = Mesh.prototype.raycast; Mesh.prototype.raycast = function(...args) { const result = originalRaycast.apply( this, args ); // custom logic... return result; }; // Or you can add an entirely new function like this 新增方法 Mesh.prototype.customFunction = function() {}; ``` |
10 johnman OP @itbeihe 还是不太懂 实际上我想对 import * as THREE from 'three' 这个 THREE 添加新方法 而非对 import { Mesh } from 'three'; 中的 Mesh 添加新方法 |
11 horizon 2023 年 9 月 4 日 你为啥要给 THREE 添加新方法 |
13 itbeihe 2023 年 9 月 4 日 @johnman 是想这样么? ```` //myThree.js import * as Three from 'three' console.log('start',Three); // Three 不可扩展,只能用新对象承接 const newThree = {...Three} newThree.test = function(){ console.log('test'); } export const three = newThree ```` ```` // 调用处 import {three} from "./src/myThree.js" three.test() ```` |
14 jspatrick 2023 年 9 月 4 日 1. `打算用 node 改写`,nodejs 是无浏览器环境的运行时,肯定不能这样改写,因为没有 window 对象,threejs 包内部也包含一些浏览器环境的变量和函数 2. 猜测你是想用 import 写法,既然已经看到 import 了,不妨重新组织下代码,对 EVALoader 这样的东西统一放置到 loaders 文件夹,不要修改 threejs 导出的对象,使用 import 来导入 EVALoader 和上述的 AAA 、BBB 3. 打包工具问题,如果是体量较大,要工程化,那么建议是上个打包工具的,好处是无脑 install threejs 就完了,倘若代码量不高,浏览器也是支持 script type=module 形式导入的,threejs 同样提供了对应格式的 min 包 |
17 johnman OP |
18 nsjs 2023 年 9 月 4 日 #13 13 楼的方法是对的 |
19 johnman OP |
20 nsjs 2023 年 9 月 4 日 @johnman 你这个问题和 node 完全没有关系,就是 js 的模块封装问题 就按 13 楼的方法就可以了。three.js 相当于一个 base module ,其它的如 EVALoader 都是 injector module ,你写一个自己的重导出的 module 就行了,如 my_three.js ```js import base module // 导入所有注入 import EVALoader module import A module import B module ... import Z module // 导出 export default xxx ``` |
22 johnman OP @nsjs 用了最土的办法 globals.js import * as MYTHREE from "three"; global.THREE = MYTHREE; global.EVA= EVA; console.log("start THREE", global.THREE); console.log("start THREE", global.EVA); export default MYTHREE; 在 main.js 里面 import 了 globals/EVALoader/EVAOptions/EVAPreviews....等等一大堆相互注入依赖的 js ,就搞定了。 然后在全局暴露了 THREE 和 EVA |