在 Electron 项目中使用外部目录中的组件与 Webpack



我试图尽可能简单地做到这一点,我研究了一段时间的纱线工作区,但这是一个目前不适用于Electron的解决方案,问题太多了。

  • 我在这里有电子项目:./electron/
  • 我这里有一个包含组件的目录:./common/

这些组件是用 React/JSX 开发的,没有什么特别的。也就是说,我正在使用钩子(useXXX(。

我尝试了很多方法来包含这些组件(理想情况下,我想使用 Yarn 工作区,但它只会增加问题的数量(,但它们都失败了。这就是为什么我想避免使用纱线链接或工作区或使公共库等。我只是希望我的 Electron 项目表现得好像文件在 ./electron 下一样。就是这样。

我最接近解决方案的是使用电子webpack,并用这个配置覆盖它:

module.exports = function(config) {
config = merge.smart(config, {
module: {
rules: [
{
test: /.jsx?$/,
//include: /node_modules/,
include: Path.resolve(__dirname, '../common'),
loaders: ['react-hot-loader/webpack', 'babel-loader?presets[]=@babel/preset-react']
},
]
},
resolve: {
alias: {
'@common': Path.resolve(__dirname, '../common')
}
}
})
return config
}

我可以导入模块,它们可以工作...除非我使用钩子。我收到"无效的钩子调用警告":https://reactjs.org/warnings/invalid-hook-call-warning.html。

我觉得 babel 没有正确编译/common 文件夹,但现实是我不知道在哪里查找或尝试什么。我想有一个解决方案,通过那个 webpack 配置。

提前感谢您的帮助:)

我找到了解决方案。发生这种情况是因为 React 的实例在/common 和/electron 之间是不同的。

这个想法是添加一个别名,如下所示:

'react': Path.resolve('./node_modules/react')

当然,对于需要完全位于同一实例上的其他模块也可以这样做。如果这个答案不完全正确,请不要犹豫,对此发表评论。

我为类似的问题摔跤了一天多。我的项目依赖于一个模块 A,该模块本身由 Webpack(我自己创作的模块(捆绑在一起。我从 A 外部化了 React(声明它是一个 commonjs2 模块(。这将从库捆绑包中排除 React 文件。

我的主要程序,在 Electron Renderer 进程中运行,也使用 React。我让 Webpack 将 React 包含在捆绑包中(没有特殊配置(。

但是,由于运行时环境中有两个 React 实例,这产生了"钩子"问题。

这是由以下事实引起的:

  • 模块 A "需要"React,这由 Electron 的模块系统解决。所以电子从node_modules中获取了反应;
  • 主程序依赖于 Webpack 运行时从捆绑包本身"加载"React。
  • Electron和Webpack运行时都有自己的模块缓存...

我的解决方案是从主程序外部化 React。这样,主程序和模块 A 都从 Electron 获取它们的 React - 内存中的单个实例。

我尝试了任意数量的别名,但这并不能解决问题,因为别名只能为在哪里找到模块代码的问题提供方向。它对多模块缓存的问题没有任何作用!

如果您在无法控制的模块中遇到此问题,请了解 React 是否以及如何外部化。如果它没有被外部化,我认为你不能在电子的背景下解决这个问题。如果它被外部化为全局,请将 React 放入您的 .html 文件中,并使您的主程序也依赖于它。

最新更新