麻烦前端大佬看看
原来有一个 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-09-04 11:53:12 +08:00 via iPhone
你应该想说用 es6 模块的方式来写吧?不需要 window.three = three 吧
|
3
bhbhxy 2023-09-04 11:59:42 +08:00
不建议用 window.xxx 来挂载全局对象,用模块化的方式,哪里需要就哪里导入,共享数据自己实现一个简易的 vuex
|
4
okakuyang 2023-09-04 12:04:51 +08:00 via iPhone
import { vector3 } from “three”
|
5
okakuyang 2023-09-04 12:06:36 +08:00 via iPhone
你要看你引入的版本是不是按模块导出的,如果不是,去找模块导出的版本,如果没有需要自己改导出
|
6
johnman OP @okakuyang
我尝试理解一下,如果 THREE.JS 是按照模块导出的。 我在文件 A 对 THREE 模块 import 之后,增加函数 C 和变量 D 。 其他文件 B 再次 import THREE 模块之后,可以执行函数 C 和读取/修改 D ? |
7
kongkx 2023-09-04 12:51:31 +08:00 via iPhone
import 不配 打包工具?
|
8
tangchi695 2023-09-04 13:44:16 +08:00
threejs 本身就打包了 esm 的版本啊
|
9
itbeihe 2023-09-04 14:17:08 +08:00
多看看官方文档啊,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-09-04 16:07:38 +08:00
你为啥要给 THREE 添加新方法
|
13
itbeihe 2023-09-04 16:33:18 +08:00
@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-09-04 16:34:50 +08:00
1. `打算用 node 改写`,nodejs 是无浏览器环境的运行时,肯定不能这样改写,因为没有 window 对象,threejs 包内部也包含一些浏览器环境的变量和函数
2. 猜测你是想用 import 写法,既然已经看到 import 了,不妨重新组织下代码,对 EVALoader 这样的东西统一放置到 loaders 文件夹,不要修改 threejs 导出的对象,使用 import 来导入 EVALoader 和上述的 AAA 、BBB 3. 打包工具问题,如果是体量较大,要工程化,那么建议是上个打包工具的,好处是无脑 install threejs 就完了,倘若代码量不高,浏览器也是支持 script type=module 形式导入的,threejs 同样提供了对应格式的 min 包 |
15
horizon 2023-09-04 16:36:59 +08:00
|
17
johnman OP |
18
nsjs 2023-09-04 17:30:00 +08:00
#13 13 楼的方法是对的
|
19
johnman OP |
20
nsjs 2023-09-04 17:47:02 +08:00
@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 ``` |
21
kongkx 2023-09-04 18:16:39 +08:00 via iPhone
@johnman #17 建议多看看 three.js 的文档,以及示例。 估计有不少是 官方 addon
|
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 |