在 next.js 中加载 GLTF 模型/错误:无法加载 <url> response.body.getReader 不是函数

Ale*_*lex 3 webgl three.js reactjs next.js react-three-fiber

如何在 next.js 中加载模型 GLTF 模型?

我花了几个小时寻找这个。没有任何效果:(


到目前为止我尝试过的:

  • 使用不同的加载器(useLoader(GLTFLoader,url) / useGLTF(url) and some more
  • 将组件包装在next/dynamic组件中/不这样做
  • suspense通过使用 React 18 安装 next 来解决与不支持相关的错误
  • 尝试了这个入门模板
  • 使用three-stdlib
  • 尝试编写自定义加载程序next.config.js

阅读我能找到的关于该问题的每个问题和论坛帖子


我目前得到的错误是:

Server Error
Error: Could not load  <url> response.body.getReader is not a function
Run Code Online (Sandbox Code Playgroud)

组件如下所示:

import React from 'react'
import { useGLTF } from '@react-three/drei'
import { Canvas, } from '@react-three/fiber'
import { Suspense } from 'react/cjs/react.production.min';

export default function Spinner({ ...props }) {
  const model = useGLTF("http://localhost:3000/spinner.glb")
  return (
    <Suspense fallback={"loading"}>
      <Canvas
        camera={{ position: [1, 1, 1] }}
      >
        <primitive object={model.scene} />
        <color attach="background" args={["hotpink"]} />
      </Canvas>
    </Suspense>
  )
}
Run Code Online (Sandbox Code Playgroud)

包.json:

  },
  "dependencies": {
    "@react-three/drei": "^7.27.3",
    "@react-three/fiber": "^7.0.21",
    "axios": "^0.24.0",
    "next": "^12.0.7",
    "react": "^18.0.0-beta-24dd07bd2-20211208",
    "react-dom": "^18.0.0-beta-24dd07bd2-20211208",
    "three": "^0.135.0",
    "three-stdlib": "^2.6.1"
  },
  "devDependencies": {
    "eslint": "8.4.1",
    "eslint-config-next": "12.0.7",
    "file-loader": "^6.2.0"
  }
}
Run Code Online (Sandbox Code Playgroud)

节点版本:

16 LTS
Run Code Online (Sandbox Code Playgroud)

小智 8

用父级包装模型组件并使用延迟导入解决了这个问题,例如

模型组件

import React from 'react'
import { useGLTF } from '@react-three/drei'

export default function Model() {
  const model = useGLTF("http://localhost:3000/spinner.glb")
  return (
     <primitive object={model.scene} />
  )
}
Run Code Online (Sandbox Code Playgroud)

使用lazy()导入的场景组件

import { lazy, Suspense } from 'react'
import { Canvas, } from '@react-three/fiber'

const ModelComponent = lazy(() => import("./model"));

export default function Spinner({ ...props }) {
  return (
    <Suspense fallback={"loading"}>
      <Canvas
        camera={{ position: [1, 1, 1] }}
      >
        <ModelComponent />
        <color attach="background" args={["hotpink"]} />
      </Canvas>
    </Suspense>
  )
}
Run Code Online (Sandbox Code Playgroud)

这似乎与SSR有关。Next 中的TextureLoaders 也存在类似的问题,并且修复它也遇到了类似的困难,最终找到了使用lazy() 导入的解决方案。我刚刚尝试过模型加载,效果很好。现在无法跟踪这个原始线程,但会尝试跟踪并将其添加到此处。

  • 是的,对我来说,导入拆分组件就足够了,这样带有加载器的组件就位于画布和悬念中。我认为加载程序也包含在悬念组件中并且表现良好 - ssr 没有压力。我想知道为什么动态导入还不够 (2认同)