【问题标题】:Using components from an external directory in a Electron project with Webpack使用 Webpack 在 Electron 项目中使用外部目录中的组件
【发布时间】:2020-10-13 03:26:50
【问题描述】:

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

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

这些组件是在 React/JSX 中开发的,它们并没有什么花哨的地方。也就是说,我正在使用钩子 (useXXX)。

我尝试了很多方法来包含这些组件(理想情况下,我想使用 Yarn Workspaces,但它只会增加问题的数量),但都失败了。这就是为什么我想避免使用纱线链接或工作区或使公共库成为库等的原因。我只希望我的 Electron 项目的行为就像文件在 ./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

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

提前感谢您的帮助:)

【问题讨论】:

    标签: reactjs webpack electron react-hooks webpack-4


    【解决方案1】:

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

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

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

    这是由以下事实造成的:

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

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

    我尝试了任意数量的别名,但这并不能解决问题,因为别名只能说明在哪里可以找到模块代码的问题。对多模块缓存的问题无能为力!

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

    【讨论】:

      【解决方案2】:

      我找到了解决方案。这是因为 /common 和 /electron 的 React 实例不同。

      想法是添加一个别名,像这样:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-12
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 2017-05-15
        • 1970-01-01
        • 1970-01-01
        • 2017-11-29
        相关资源
        最近更新 更多