Reactjs 加载错误>;module.exports=Nextjs中的require(";三个/examples/jsm/loaders/GLTFLoader";)
我正在使用Reactjs 加载错误>;module.exports=Nextjs中的require(";三个/examples/jsm/loaders/GLTFLoader";),reactjs,three.js,next.js,react-three-fiber,Reactjs,Three.js,Next.js,React Three Fiber,我正在使用react three fiber、three和nextjs来显示一些鸟类,这是threejs中的常见示例!这是我的一个nextjsapp的索引文件: import React, { useRef, useState, useEffect } from 'react'; import * as THREE from 'three'; import { Canvas, useFrame, useLoader } from 'react-three-fiber'; import { GLT
react three fiber
、three
和nextjs
来显示一些鸟类,这是threejs
中的常见示例!这是我的一个nextjs
app的索引文件:
import React, { useRef, useState, useEffect } from 'react';
import * as THREE from 'three';
import { Canvas, useFrame, useLoader } from 'react-three-fiber';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
function Box(props) {
// This reference will give us direct access to the mesh
const mesh = useRef();
// Set up state for the hovered and active state
const [hovered, setHover] = useState(false);
const [active, setActive] = useState(false);
// Rotate mesh every frame, this is outside of React without overhead
// eslint-disable-next-line no-return-assign,no-multi-assign
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01));
return (
<mesh
{...props}
ref={mesh}
scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
onClick={e => setActive(!active)}
onPointerOver={e => setHover(true)}
onPointerOut={e => setHover(false)}
>
<boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
<meshStandardMaterial
attach="material"
color={hovered ? 'hotpink' : 'orange'}
/>
</mesh>
);
}
// This component was auto-generated from GLTF by: https://github.com/react-spring/gltfjsx
function Bird({ speed, factor, url, ...props }) {
const gltf = useLoader(GLTFLoader, url);
const group = useRef();
const [mixer] = useState(() => new THREE.AnimationMixer());
useEffect(
() => void mixer.clipAction(gltf.animations[0], group.current).play(),
[gltf.animations, mixer],
);
useFrame((state, delta) => {
group.current.rotation.y +=
Math.sin((delta * factor) / 2) * Math.cos((delta * factor) / 2) * 1.5;
mixer.update(delta * speed);
});
return (
<group ref={group}>
<scene name="Scene" {...props}>
<mesh
name="Object_0"
morphTargetDictionary={gltf.__$[1].morphTargetDictionary}
morphTargetInfluences={gltf.__$[1].morphTargetInfluences}
rotation={[1.5707964611537577, 0, 0]}
>
<bufferGeometry attach="geometry" {...gltf.__$[1].geometry} />
<meshStandardMaterial
attach="material"
{...gltf.__$[1].material}
name="Material_0_COLOR_0"
/>
</mesh>
</scene>
</group>
);
}
function Birds() {
return new Array(2).fill().map((_, i) => {
const x = (15 + Math.random() * 30) * (Math.round(Math.random()) ? -1 : 1);
const y = -10 + Math.random() * 20;
const z = -5 + Math.random() * 10;
const bird = ['stork', 'parrot', 'flamingo'][Math.round(Math.random() * 2)];
const speed = bird === 'stork' ? 0.5 : bird === 'flamingo' ? 2 : 5;
const factor =
bird === 'stork'
? 0.5 + Math.random()
: bird === 'flamingo'
? 0.25 + Math.random()
: 1 + Math.random() - 0.5;
return (
<Bird
key={i}
position={[x, y, z]}
rotation={[0, x > 0 ? Math.PI : 0, 0]}
speed={speed}
factor={factor}
url={`/static/glb/${bird}.glb`}
/>
);
});
}
const MyComponent = props => {
return (
<Canvas>
<ambientLight />
<pointLight position={[10, 0, 10]} />
<Box position={[-1.2, 2, 0]} />
<Box position={[1.2, 0, 0]} />
<Box position={[3, -2, 0]} />
<Birds />
</Canvas>
);
};
export default MyComponent;
import React,{useRef,useState,useffect}来自'React';
从“三”中导入*作为三;
从“react three fiber”导入{Canvas,useFrame,useLoader};
从'three/examples/jsm/loaders/GLTFLoader'导入{GLTFLoader};
功能盒(道具){
//此参考将使我们能够直接访问网格
const mesh=useRef();
//设置悬停和活动状态的状态
const[hover,setHover]=useState(false);
const[active,setActive]=useState(false);
//每帧旋转一次网格,这是在React之外,没有开销
//eslint禁用下一行无返回分配,无多重分配
useFrame(()=>(mesh.current.rotation.x=mesh.current.rotation.y+=0.01));
返回(
setActive(!active)}
onPointerOver={e=>setHover(true)}
onPointerOut={e=>setHover(false)}
>
);
}
//此组件是由GLTF自动生成的:https://github.com/react-spring/gltfjsx
函数Bird({speed,factor,url,…props}){
const gltf=useLoader(GLTFLoader,url);
const group=useRef();
const[mixer]=useState(()=>newthree.AnimationMixer());
使用效果(
()=>void mixer.clipAction(gltf.animations[0],group.current.play(),
[gltf.animations,mixer],
);
useFrame((状态,增量)=>{
组。当前。旋转。y+=
数学sin((δ*因子)/2)*数学cos((δ*因子)/2)*1.5;
混合器更新(增量*速度);
});
返回(
);
}
功能鸟(){
返回新数组(2).fill().map((\ux,i)=>{
常数x=(15+Math.random()*30)*(Math.round(Math.random())?-1:1);
常数y=-10+数学随机()*20;
常数z=-5+数学随机()*10;
const bird=['stork','parrot','flamingo'][Math.round(Math.random()*2)];
恒速=鸟=='鹳'?0.5:鸟=='火烈鸟'?2:5;
常数因子=
鸟==‘鹳’
?0.5+数学随机()
:伯德===‘火烈鸟’
?0.25+数学随机()
:1+Math.random()-0.5;
返回(
0?Math.PI:0,0]}
速度={speed}
因子={factor}
url={`/static/glb/${bird}.glb`}
/>
);
});
}
常量MyComponent=props=>{
返回(
);
};
导出默认MyComponent;
我的文件在静态/glb/…
文件夹中!问题在于GLTFLoader加载器。我尝试了扩展的方法“反应三根纤维”
,但没有帮助
我想可能是因为SSR的缘故。你这样认为吗?嗯,我晚了大约3个月,但我希望这能解决任何疑问,以防有人发现这个问题
首先,您需要导入GLB渲染,您的应用程序当前不知道您正在尝试渲染哪个GLB文件。
这样做应该可以:
从'src/static/glb/an\u awesome\u bird.glb'导入MyCustomRender
然后,每次实例化bird组件时,都可以将其作为道具传递,如中所示
0?Math.PI:0,0]}
速度={speed}
因子={factor}
url={MyCustomRender}
/>
现在,由于您使用的是NextJS,这意味着您当前正在使用WebPack捆绑您的应用程序
问题是,WebPack从一开始就不知道什么是glb
或GLTF
文件,您必须让这个小模块知道在导入具有所述扩展名的文件时如何操作
您可以通过如下方式更新next.config.js
文件来实现这一点:
module.exports = withCSS(withSass({
webpack (config, options) {
config.module.rules.push({
test: /\.(glb|gltf)$/,
use: {
loader: 'file-loader',
}
})
return config
}
}))
这本质上意味着你告诉Webpack“嘿,如果你看到我导入任何.gltf或.glb文件,这意味着我想要它们的路径,所以给我它们的URL”
如果您没有安装Webpack的文件加载器,您可以随时安装
npm安装文件加载器--保存开发
几天前,我使用完全相同的堆栈进行了回购:
(除了我没有使用NextJS,所以我的next.config.js
实际上是webpack.config.js
)
希望它能帮助你消除任何疑虑 好吧,我大约晚了3个月,但我希望这能解决任何疑问,以防有人发现这个问题
首先,您需要导入GLB渲染,您的应用程序当前不知道您正在尝试渲染哪个GLB文件。
这样做应该可以:
从'src/static/glb/an\u awesome\u bird.glb'导入MyCustomRender
然后,每次实例化bird组件时,都可以将其作为道具传递,如中所示
0?Math.PI:0,0]}
速度={speed}
因子={factor}
url={MyCustomRender}
/>
现在,由于您使用的是NextJS,这意味着您当前正在使用WebPack捆绑您的应用程序
问题是,WebPack从一开始就不知道什么是glb
或GLTF
文件,您必须让这个小模块知道在导入具有所述扩展名的文件时如何操作
您可以通过如下方式更新next.config.js
文件来实现这一点:
module.exports = withCSS(withSass({
webpack (config, options) {
config.module.rules.push({
test: /\.(glb|gltf)$/,
use: {
loader: 'file-loader',
}
})
return config
}
}))
这本质上意味着你告诉Webpack“嘿,如果你看到我导入任何.gltf或.glb文件,这意味着我想要它们的路径,所以给我它们的URL”
如果您没有安装Webpack的文件加载器,您可以随时安装
npm安装文件加载器--保存开发
几天前,我使用完全相同的堆栈进行了回购:
(除了我没有使用NextJS,所以我的next.config.js
实际上是webpack.config.js
)
希望它能帮助你消除任何疑虑 谢谢,我必须测试你的解决方案,看看它有什么帮助,但我