Javascript 从CreateReact应用程序转换到NextJS,ThreeJS出现问题
我在react中有一个工作的3d模型查看器,我现在正尝试将其移植到下一个。我需要GLTFLoader和OrbitControls,它们在我加载的react中给了我问题,如下所示: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' 无法执行此操作,因为我将在下一
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:错,
}非常感谢你建设性的回答,你不知道我有多感激。我将看一看动态导入,这似乎是最简单和最有意义的。我让它工作。。。你的评论帮了我很大的忙,作为一个新手,要想涉过一半的信息真的很难。这个解决方案出人意料地简单。非常感谢你的建设性回答,你不知道我对它的评价有多高。我将看一看动态导入,这似乎是最简单和最有意义的。我让它工作。。。你的评论帮了我很大的忙,作为一个新手,要想涉过一半的信息真的很难。解决办法出人意料地简单。