麻烦前端大佬看看, THREE 项目重写 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
johnman
V2EX    程序员

麻烦前端大佬看看, THREE 项目重写

  johnman 2023 年 9 月 4 日 2980 次点击
这是一个创建于 911 天前的主题,其中的信息可能已经有所发展或是发生改变。

麻烦前端大佬看看

原来有一个 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 这个函数?

22 条回复    2023-09-04 22:38:45 +08:00
okakuyang
    1
okakuyang  
   2023 年 9 月 4 日 via iPhone
你应该想说用 es6 模块的方式来写吧?不需要 window.three = three 吧
johnman
    2
johnman  
OP
   2023 年 9 月 4 日
@okakuyang 是。引用再导出就可以了吗?
貌似原来的 THREE.Vector3 等方法就无法使用了?
bhbhxy
    3
bhbhxy  
   2023 年 9 月 4 日
不建议用 window.xxx 来挂载全局对象,用模块化的方式,哪里需要就哪里导入,共享数据自己实现一个简易的 vuex
okakuyang
    4
okakuyang  
   2023 年 9 月 4 日 via iPhone
import { vector3 } from “three”
okakuyang
    5
okakuyang  
   2023 年 9 月 4 日 via iPhone
你要看你引入的版本是不是按模块导出的,如果不是,去找模块导出的版本,如果没有需要自己改导出
johnman
    6
johnman  
OP
   2023 年 9 月 4 日
@okakuyang

我尝试理解一下,如果 THREE.JS 是按照模块导出的。

我在文件 A 对 THREE 模块 import 之后,增加函数 C 和变量 D 。

其他文件 B 再次 import THREE 模块之后,可以执行函数 C 和读取/修改 D ?
kongkx
    7
kongkx  
   2023 年 9 月 4 日 via iPhone
import 不配 打包工具?
tangchi695
    8
tangchi695  
   2023 年 9 月 4 日
threejs 本身就打包了 esm 的版本啊
itbeihe
    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() {};
```
johnman
    10
johnman  
OP
   2023 年 9 月 4 日
@itbeihe

还是不太懂

实际上我想对
import * as THREE from 'three' 这个 THREE 添加新方法

而非对
import { Mesh } from 'three'; 中的 Mesh 添加新方法
horizon
    11
horizon  
   2023 年 9 月 4 日
你为啥要给 THREE 添加新方法
johnman
    12
johnman  
OP
   2023 年 9 月 4 日
@horizon 因为原项目存在大量此类操作并且文件之间互相引用。希望可以尽量减少改动
itbeihe
    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()

````
jspatrick
    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 包
horizon
    15
horizon  
   2023 年 9 月 4 日
@johnman #12
那你要看下原来添加的方法里用了啥啊,可以改成依赖注入的方式,把 THREE 当作参数传入到新方法内。
这样可能比较简单?
johnman
    16
johnman  
OP
   2023 年 9 月 4 日
@kongkx webpack
nsjs
    18
nsjs  
   2023 年 9 月 4 日
#13 13 楼的方法是对的
johnman
    19
johnman  
OP
   2023 年 9 月 4 日
@jspatrick EVALoader.js 只是其中一个文件示例。原来项目代码有很多 JS 文件,每个 JS 都在 THREE 对象上加了自己的私活,并且 JS 文件之间直接引用其他文件创建的 THREE.xxx 方法。不知道如何快捷处理这种问题
nsjs
    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
```
kongkx
    21
kongkx  
   2023 年 9 月 4 日 via iPhone
@johnman #17 建议多看看 three.js 的文档,以及示例。 估计有不少是 官方 addon
johnman
    22
johnman  
OP
   2023 年 9 月 4 日
@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
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5501 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 28ms UTC 08:29 PVG 16:29 LAX 00:29 JFK 03:29
Do have faith in what you're doing.
ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86