【问题标题】:How do I compile a preload script w/ webpack in Electron?如何在 Electron 中编译带有 webpack 的预加载脚本?
【发布时间】:2017-10-03 10:17:14
【问题描述】:

电子 1.6.5、Webpack 2.4.1

我将electron-react-boilerplatewebview 组件一起使用。我在webview 中注入了一个预加载脚本,它执行以下操作:

const { ipcRenderer } = require('electron');
const doSomething = require('./utils/do-some-thing.js');

document.addEventListener('DOMContentLoaded', event => {
   doSomeThing()

  // tell scraper to get started
  ipcRenderer.sendToHost('THING IS DONE', [{ url: document.URL }]);
});

webview 需要将此脚本作为file:// 路径传递,如下所示:

       <webview
        preload={'./some/folder/preload.js''}
        {...props}
      />

问题是我的 webpack 设置没有转换 preload.js,因为它没有通过 require() 显式调用。然后,当我构建应用程序时,路径 ./some/folder/ 不存在。

我尝试设置 webpack 来创建第二个编译脚本,如下所示:

entry: [
    'babel-polyfill',
    './app/index',
    './some/folder/preload.js'
  ],

  output: {
    path: path.join(__dirname, 'app/dist'),
    publicPath: '../dist/'
  },

但这会导致JavaScript heap out of memory 错误,这让我相信这是不正确的。

另外:这种方法不会在./dist 文件夹中复制electron,因为它是require()preload.jsindex.js 所创建的吗?

【问题讨论】:

  • 你最后得到preload.js被babel转译了吗?
  • 问题解决了吗?

标签: javascript webpack electron


【解决方案1】:

Electron 提供了在 DOM 中执行任何其他操作之前加载脚本的选项。

您必须在创建浏览器窗口时提供您的预加载脚本文件路径,并且脚本的文件路径应该是绝对的。

你可以找到参考here

【讨论】:

    【解决方案2】:

    我们有一个类似的问题,我们有几个预加载脚本而不是一个。我们的解决方案是使用CopyPlugin。所以对我们来说,配置看起来像这样:

    const CopyPlugin = require("copy-webpack-plugin");
    
    plugins.push(new CopyPlugin([{ from: "src/container-with-scripts/", to: "preloadScripts/" }]));
    
    module.exports = {
      module: { rules }, // imported from elsewhere
      target: "electron-renderer",
      node: { global: true },
      plugins,
      resolve: {
        extensions: [".js", ".ts", ".jsx", ".tsx", ".css", ".scss"]
      }
    };
    

    所以我们只需将包含所有脚本的文件夹复制到自动生成的 .webpack 文件夹中。

    【讨论】:

      【解决方案3】:

      你可以使用 webpack 的 electron-main 和 electron-preload 配置:

      const path = require('path');
      
      module.exports = [
        {
          entry: './src/index.js',
          target: 'electron-main',
          output: {
            path: path.join(__dirname, 'dist'),
            filename: 'index.bundled.js'
          },
          node: {
              __dirname: false,
          }
        },
        {
          entry: './src/preload.js',
          target: 'electron-preload',
          output: {
            path: path.join(__dirname, 'dist'),
            filename: 'preload.bundled.js'
          }
        },
      ]
      

      构建后你会得到两个包,但 Electron 不在其中,所以没有重复。

      注意__dirname: false,这是必需的,否则 webpack 替换 __dirname 总是被 webpack 替换为 /,在几乎所有情况下都会导致意外行为(有关更多信息,请参阅 here,应该为 false默认,但不适合我)。

      【讨论】:

      • 我无法正常工作。 webview preload attr中如何指定路径?
      • 我可以确认此答案适用于带有 Electron v12.0 的 WebPack v5.24
      【解决方案4】:

      我遇到了同样的问题,这里的解决方案对我有用:
      Electron-webpack 文档现在包含如何添加 additional entries 的示例。

      "electronWebpack": {
        "main": {
          "extraEntries": ["@/preload.js"]
        }
      }
      

      请注意,您可以使用 @ 别名来引用您的 main.sourceDirectory
      在这种情况下,它是您的主进程脚本的路径,默认情况下为 src/main

      这会将来自 src/main/preload.js 的预加载脚本添加到 webpack 条目中。
      然后你需要将预加载脚本添加到窗口中

      new BrowserWindow({
          webPreferences: {
            nodeIntegration: true,
            preload: path.resolve(path.join(__dirname, "preload.js")),
          }
      })
      

      就是这样。 __dirname 给了我相对路径,而电子需要预加载脚本的绝对路径,所以它失败了。 path.resolve 将为您提供使其工作所需的绝对路径。

      【讨论】:

      • 有用的分享,但不是特定问题的答案,因为它依赖于 Electron-Webpack,它是一个完整的样板,而不是 OP 可以切换到的东西。
      猜你喜欢
      • 2019-10-21
      • 2020-07-29
      • 2017-09-28
      • 1970-01-01
      • 2021-06-18
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      相关资源
      最近更新 更多