如何在Electron中编译带webpack的预加载脚本?

时间:2017-05-05 04:08:25

标签: javascript webpack electron

Electron 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}
      />

问题是我的网站设置没有转换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错误,这让我相信这是不正确的。

另外:这种方法不会在electron文件夹中复制./dist,因为它require()preload.js都是index.js return redirect("/login")

4 个答案:

答案 0 :(得分:2)

您可以使用webpack的电子主和电子预载配置:

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,但不适用于我)。

答案 1 :(得分:0)

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

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

您可以找到参考文献here

答案 2 :(得分:0)

我们有一个类似的问题,我们有几个预加载脚本而不是一个。我们的解决方案是使用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 :(得分:0)

我遇到了同样的问题,这是对我有用的解决方案:
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将为您提供使其正常工作所需的绝对路径。