开发时如何避免 React 使用 Webpack 加载两次
How to avoid React loading twice with Webpack when developing
给定以下目录结构:
my-project
|
|-- node_modules
|
|-- react
|-- module-x
|
|--node_modules
|
|--react
你可以看到 my-project 和 module-x 都需要 React。我遇到了与 this question 中所述相同的问题,但建议是从 package.json 依赖项中删除 react。我这样做并且它工作正常,只要 module-x 中没有安装 node_modules,因为 Webpack 将使用来自 my-project[= 的 React 35=]。但是,如果我正在开发 module-x 并且安装了 node_modules,Webpack 使用来自 my-project[=35= 的 React ] 和 module-x.
有没有一种方法可以让 Webpack 确保只使用一个 React 实例,即使它在两个不同的级别上是必需的?
我知道我可以在开发时将 module-x 保存在一个单独的目录中,但似乎我必须发布它然后将其安装在 my-project 进行测试,效率不高。我考虑过 npm link
,但没有成功,因为它仍然在 module-x.
中安装了 node_modules
This here 听起来很像我面临的挑战,但似乎 npm dedupe
或 Webpack 的重复数据删除选项不起作用。我可能没有理解一些重要的细节。
此问题通常在使用 npm link
时出现。链接模块将在其自己的模块树中解析其依赖关系,这与需要它的模块不同。因此,npm link
命令安装 peerDependencies
以及 dependencies
。
您可以使用 resolve.alias
强制 require('react')
解析为您本地版本的 React。
resolve: {
alias: {
react: path.resolve('./node_modules/react'),
},
},
如果您不想(或不能)修改项目配置,有一个更直接的解决方案:只需npm link
将自身反应回您的项目:
# link the component
cd my-app
npm link ../my-react-component
# link its copy of React back to the app's React
cd ../my-react-component
npm link ../my-app/node_modules/react
以防万一它对其他人有用,上面建议的解决方案对我不起作用,我必须执行以下步骤来解决它:
在图书馆:
- 将生成问题的库设置为
package.json
中的 peerDependencies
而不是 dependencies
或 devDependencies
,例如在我的例子中 react
:
"peerDependencies": {
"react": "^16.8.6",
...
}
- 运行
npm install
- 构建库(在我的例子中,使用
rollup -c
npm 脚本
在我的主应用程序中:
- 更改我的库的版本以指向我在
package.json
中具有相对路径的本地项目,例如
"dependencies": {
"my-library": "file:../../libraries/my-library",
...
}
将 resolve.symlinks = false
添加到我的主应用程序的 webpack 配置中
将 --preserve-symlinks-main
和 --preserve-symlinks
添加到我的 package.json
启动脚本中,例如:
"scripts": {
"build": "set WEBPACK_CONFIG_FILE=all&& webpack",
"start": "set WEBPACK_CONFIG_FILE=all&& webpack && node --preserve-symlinks-main --preserve-symlinks dist/server.js",
}
- 运行
npm install
- 运行
npm run start
与 here's how you can achieve the desired outcome with Craco一脉相承:
const path = require('path')
module.exports = {
webpack: {
configure: config => {
config = {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
'react': path.resolve('./node_modules/react'),
},
},
}
// console.log(config)
return config
},
},
}
请务必注意,您不能只将 resolve
作为键传递,您必须使用 configure
回调进行自己的深度合并。
给定以下目录结构:
my-project
|
|-- node_modules
|
|-- react
|-- module-x
|
|--node_modules
|
|--react
你可以看到 my-project 和 module-x 都需要 React。我遇到了与 this question 中所述相同的问题,但建议是从 package.json 依赖项中删除 react。我这样做并且它工作正常,只要 module-x 中没有安装 node_modules,因为 Webpack 将使用来自 my-project[= 的 React 35=]。但是,如果我正在开发 module-x 并且安装了 node_modules,Webpack 使用来自 my-project[=35= 的 React ] 和 module-x.
有没有一种方法可以让 Webpack 确保只使用一个 React 实例,即使它在两个不同的级别上是必需的?
我知道我可以在开发时将 module-x 保存在一个单独的目录中,但似乎我必须发布它然后将其安装在 my-project 进行测试,效率不高。我考虑过 npm link
,但没有成功,因为它仍然在 module-x.
This here 听起来很像我面临的挑战,但似乎 npm dedupe
或 Webpack 的重复数据删除选项不起作用。我可能没有理解一些重要的细节。
此问题通常在使用 npm link
时出现。链接模块将在其自己的模块树中解析其依赖关系,这与需要它的模块不同。因此,npm link
命令安装 peerDependencies
以及 dependencies
。
您可以使用 resolve.alias
强制 require('react')
解析为您本地版本的 React。
resolve: {
alias: {
react: path.resolve('./node_modules/react'),
},
},
如果您不想(或不能)修改项目配置,有一个更直接的解决方案:只需npm link
将自身反应回您的项目:
# link the component
cd my-app
npm link ../my-react-component
# link its copy of React back to the app's React
cd ../my-react-component
npm link ../my-app/node_modules/react
以防万一它对其他人有用,上面建议的解决方案对我不起作用,我必须执行以下步骤来解决它:
在图书馆:
- 将生成问题的库设置为
package.json
中的peerDependencies
而不是dependencies
或devDependencies
,例如在我的例子中react
:
"peerDependencies": {
"react": "^16.8.6",
...
}
- 运行
npm install
- 构建库(在我的例子中,使用
rollup -c
npm 脚本
在我的主应用程序中:
- 更改我的库的版本以指向我在
package.json
中具有相对路径的本地项目,例如
"dependencies": {
"my-library": "file:../../libraries/my-library",
...
}
将
resolve.symlinks = false
添加到我的主应用程序的 webpack 配置中将
--preserve-symlinks-main
和--preserve-symlinks
添加到我的package.json
启动脚本中,例如:
"scripts": {
"build": "set WEBPACK_CONFIG_FILE=all&& webpack",
"start": "set WEBPACK_CONFIG_FILE=all&& webpack && node --preserve-symlinks-main --preserve-symlinks dist/server.js",
}
- 运行
npm install
- 运行
npm run start
与
const path = require('path')
module.exports = {
webpack: {
configure: config => {
config = {
...config,
resolve: {
...config.resolve,
alias: {
...config.resolve.alias,
'react': path.resolve('./node_modules/react'),
},
},
}
// console.log(config)
return config
},
},
}
请务必注意,您不能只将 resolve
作为键传递,您必须使用 configure
回调进行自己的深度合并。