Javascript 从CreateReact应用程序转换到NextJS,ThreeJS出现问题

Javascript 从CreateReact应用程序转换到NextJS,ThreeJS出现问题,javascript,reactjs,three.js,next.js,Javascript,Reactjs,Three.js,Next.js,我在react中有一个工作的3d模型查看器,我现在正尝试将其移植到下一个。我需要GLTFLoader和OrbitControls,它们在我加载的react中给了我问题,如下所示: import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' 无法执行此操作,因为我将在下一

我在react中有一个工作的3d模型查看器,我现在正尝试将其移植到下一个。我需要GLTFLoader和OrbitControls,它们在我加载的react中给了我问题,如下所示:

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
无法执行此操作,因为我将在下一步中获取此错误:

SyntaxError: Cannot use import statement outside a module
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Source

.next\server\pages\index.js (1:0) @ Object.three/examples/jsm/loaders/GLTFLoader

> 1 | module.exports = require("three/examples/jsm/loaders/GLTFLoader");
然后我尝试使用三个std库,并从那里导入控件和加载程序。同样的错误。然后我尝试使用require来导入它,但再次出现相同的错误。我在谷歌上发现了一些几乎相似的问题,但没有一个简单易懂的解决方案

完整代码: 将*从“三”导入为三 从'three/examples/jsm/loaders/GLTFLoader'导入{GLTFLoader} 从'three/examples/jsm/controls/OrbitControls.js'导入{OrbitControls} //从“../assets/centered.gltf”导入Model3d //从“../assets/3dmodel.gltf”导入Model3d 从“../assets/images/3d.svg”导入D3d 从“React”导入React //让GLTFLoader //让轨道控制 const VisA==>{ //GLTFLoader=require'three/examples/jsm/loaders/GLTFLoader'.GLTFLoader //OrbitControls=需要“三个/examples/js/controls/OrbitControls” //.轨道控制 const{useRef,useffect}=React const mount=useRefnull const hitbox=useRefnull const controls=useRefnull useEffect=>{ let width=mount.current.clientWidth 让高度=mount.current.clientHeight 让frameId const scene=新的三个场景 常数照相机=新的三透视照相机75,宽/高,0.11000 const renderer=new THREE.WebGLRenderer{antialas:true,alpha:true} const loader=新的GLTFLoader const camcontrols=new OrbitControlscamera,hitbox.current //loader.loadModel3d,函数gltf{ loader.load./3dmodel/3dmodel.gltf',函数gltf{ gltf.scene.scale.set14,14,14 var box=new THREE.Box3.setFromObjectgltf.scene 变量中心=新的三个向量3 box.getCentercenter gltf.scene.position.subcenter scene.addgltf.scene } 恒半球光=新的三个半球光0xFFEEB1、0x80820、20 const light2=新的3.DirectionalLight0xfdeee1,20 常量聚光灯=新的三个聚光灯0xFDEE1,4 常量spotLight2=新的三个。spotlight0xfdee1,4 场景半光 scene.addspotLight scene.addspotLight2 light2.position.set10,-50500 场景2.addlight2 scene.rotation.y=-1.65 摄像机位置z=4 //scene.addcube //renderer.setClearColor'FFFFFF' renderer.setSizewidth,高度 const renderScene==>{ renderer.renderscene,摄影机 } 常量handleResize==>{ 宽度=mount.current.clientWidth 高度=mount.current.clientHeight renderer.setSizewidth,高度 camera.aspect=宽度/高度 camera.updateProjectionMatrix 渲染场景 } 常量动画==>{ spotLight.position.set 摄像机。位置。x+10, 摄像机。位置。y+10, 摄像机。位置。z+10 聚光灯2.position.set 摄像机,位置,x-10, 摄像机,位置,y-10, 摄像机,位置,z-10 渲染场景 frameId=window.requestAnimationFrameanimate } 常量开始==>{ 如果!帧ID{ frameId=requestAnimationFrameanimate } } 常数停止==>{ 取消动画帧ID frameId=null } mount.current.appendChildrenderer.doElement window.addEventListener'resize',handleResize 开始 controls.current={start,stop} 返回=>{ 停止 window.removeEventListener'resize',handleResize mount.current.removeChildrenderer.doElement } }, [] 回来 设置动画!设置动画} > } 导出默认visath问题 您正在导入以ESM格式编写的模块,当NextJS尝试在服务器端呈现代码时,您的代码节点不理解ESM-node.js通常需要CJS CommonJS

解决方案 视情况而定

1.您希望您的代码使用3来运行服务器端吗? 这假设三个节点可以在节点中运行,我不能说这是一种方式还是另一种方式

我认为这里有两种选择:

a使用与Node.js和浏览器兼容的三个版本。 浏览一下,你可以考虑试一下我没有用过。< /P> b自定义您的网页行为,以便将这三个代码捆绑并传输到服务器的CJS中。就个人而言,我不建议将此作为第一步。定制网页包可能会很快变得非常复杂,在NextJS中这样做也会带来额外的复杂性

2.使用三个选项修改代码,使其仅在客户端运行。 使用一个。根据该参考:

您可能并不总是希望在服务器端包含模块。例如,当模块包含仅在浏览器中工作的库时

附加反馈 请注意,上面的答案是概念性的。如果您能够通过存储库提供复制品 否则我可能会给出一个更具体的解决方案。

这个问题 您正在导入以ESM格式编写的模块,当NextJS尝试在服务器端呈现代码时,您的代码节点不理解ESM-node.js通常需要CJS CommonJS

解决方案 视情况而定

1.您希望您的代码使用3来运行服务器端吗? 这假设三个节点可以在节点中运行,我不能说这是一种方式还是另一种方式

我认为这里有两种选择:

a使用与Node.js和浏览器兼容的三个版本。 浏览一下,你可以考虑试一下我没有用过。< /P> b自定义您的网页行为,以便将这三个代码捆绑并传输到服务器的CJS中。就个人而言,我不建议将此作为第一步。定制网页包可能会很快变得非常复杂,在NextJS中这样做也会带来额外的复杂性

2.使用三个选项修改代码,使其仅在客户端运行。 使用一个。根据该参考:

您可能并不总是希望在服务器端包含模块。例如,当模块包含仅在浏览器中工作的库时

附加反馈
请注意,上面的答案是概念性的。如果您能够通过存储库或其他方式提供复制,我可能能够给出更具体的解决方案。

在Mcy的帮助下,我发现在我的情况下添加动态导入将是最简单的。这非常简单,我没有更改react中的查看器组件中的任何内容,而是在pages/index.js中加载了该组件:

从“下一个/动态”导入动态 const Dynamic3dViewr=dynamic=>import'../components/Viewer3d.js'{ ssr:错,
} 在Mcy的帮助下,我发现在我的例子中添加动态导入是最简单的。这非常简单,我没有更改react中的查看器组件中的任何内容,而是在pages/index.js中加载了该组件:

从“下一个/动态”导入动态 const Dynamic3dViewr=dynamic=>import'../components/Viewer3d.js'{ ssr:错,
}非常感谢你建设性的回答,你不知道我有多感激。我将看一看动态导入,这似乎是最简单和最有意义的。我让它工作。。。你的评论帮了我很大的忙,作为一个新手,要想涉过一半的信息真的很难。这个解决方案出人意料地简单。非常感谢你的建设性回答,你不知道我对它的评价有多高。我将看一看动态导入,这似乎是最简单和最有意义的。我让它工作。。。你的评论帮了我很大的忙,作为一个新手,要想涉过一半的信息真的很难。解决办法出人意料地简单。