警告:正在导入 Three.js 的多个实例

sxk*_*xkx 6 javascript three.js reactjs create-react-app react-three-fiber

当我尝试在同一项目中使用@react-three/fiber和时,我收到以下警告。@react-three/drei

在此输入图像描述

重现步骤

npx create-react-app reproduced-warning
cd reproduced-warning
npm install three @react-three/fiber @react-three/drei
Run Code Online (Sandbox Code Playgroud)

我的src/App.js文件如下所示:

import React from 'react';
import { Canvas } from '@react-three/fiber';
import { Stats } from '@react-three/drei';

import './App.css';

const App = (props) => {
  return (
    <div className="App">
      <Canvas />
    </div>
  );  
};

export default App;
Run Code Online (Sandbox Code Playgroud)

要启动应用程序运行npm run start

模块信息

  • three^0.128.0
  • @react-three/fiber^6.0.16
  • @react-three/drei^4.2.0

更新(2021 年 5 月 4 日)

附加信息

进行了bundle分析,得到以下结果:

// Used these imports
import React from 'react';
import { Canvas } from '@react-three/fiber';
import { Stats } from '@react-three/drei';
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

// Used these imports
import React from 'react';
import { Canvas } from '@react-three/fiber';
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在生产版本中尝试了相同的操作,但似乎没有重复的three.module.js条目。看起来这只发生在开发中,知道为什么吗?

小智 1

您在生产中看不到该警告的原因是,也许在生产中您已禁用这些警告。如果您不使用它,请考虑<React.StrictMode>在应用程序代码的任何部分包含该标记,并检查您的 StrictMode 设置。

更多信息请访问:https://www.knowledgehut.com/blog/web-development/react-strict-mode

关于警告"WARNING: Multiple instances of Three.js being imported."。当网页或应用程序多次导入 Three.js 库时(这意味着库代码被加载多次),通常会显示此警告。发生这种情况的原因有多种,例如:

  1. 多个脚本标签:如果您使用多个脚本标签在 HTML 中包含 Three.js 库,它将被导入多次。

  2. 模块捆绑问题:如果您使用Webpack或Rollup等捆绑器来捆绑应用程序代码,并且没有正确配置它,则可能会多次导入Three.js库。

  3. 外部依赖项:如果您的应用程序依赖于也导入 Three.js 的外部依赖项,则可能会导致加载该库的多个实例。

  4. 根据我的经验,这是最常见的。拥有 Three.js 库的多个实例可能会导致内存泄漏、意外行为和性能下降等问题。为了避免这些问题,您应该确保在应用程序中只导入一次库。检查您有多少个 Three.js 导入。为了避免由于外部依赖而在 React 应用程序中导入 Three.js 的多个实例,您可以按照以下步骤操作:

4.1. 使用 npm 或yarn 等包管理器来管理项目依赖项。

4.2. 检查应用程序的依赖关系,看看它们是否依赖于 Three.js。

4.3. 如果您发现任何使用 Three.js 的依赖项,请检查其文档,看看它们是否提供了使用特定版本 Three.js 或禁用其内部使用的选项。

4.4. 如果没有这样的选项,您可以尝试使用不依赖 Three.js 的依赖项,或者找到提供类似功能的替代库。

4.5. 如果没有可用的替代方案,您可以尝试使用“npm-link”或“yarn link”之类的包将您的应用程序与使用 Three.js 的依赖项链接起来,并修改其代码以使用该 Three.js 实例您的应用程序已经在使用。

4.6. 最后,如果上述选项均不起作用,则在大多数情况下,您已在多个组件、服务、应用程序模块或它们的组合中导入了 Three.js。然后,您应该执行以下操作:

4.6.1. 尝试在应用程序中使用 Three.js 库的别名,以便外部依赖项也将使用应用程序已在使用的库的同一实例。如果您的代码中多次导入此类依赖项,这应该可以解决警告问题。如果这是在第三方依赖项的代码中,我不建议更改此类代码,因为这不是破坏外部库的连续性的最佳实践。否则,每次安装和/或更新这些库时,您将被迫手动更新这些更改。根本不推荐Tha。

  1. 另一个选项(也是推荐的)是使用节点包管理器(npm)甚至纱线安装三个类似的类型。在 npm 中,有两个命令可以正确安装它:
npm install three
npm install @types/three
Run Code Online (Sandbox Code Playgroud)

然后,您应该在 tsconfig.app.json 的“compilerOptions”设置中添加这些选项并重新启动编译:

"typeRoots": ["node_modules/@types"],
"types": ["three"] 
Run Code Online (Sandbox Code Playgroud)

请记住,您还可以定义要安装的 Three.js 版本:

npm install [package-name]@[version-number]
Run Code Online (Sandbox Code Playgroud)
  1. 最后,检查构建器选项并在“脚本”部分中包含对 Three.js 模块的引用
"scripts": [
  "node_modules/three/build/three.min.js"
]
Run Code Online (Sandbox Code Playgroud)

我希望这能为您提供一些帮助。