简体   繁体   中英

How do I compile a preload script w/ webpack in Electron?

Electron 1.6.5, Webpack 2.4.1

I'm using electron-react-boilerplate with a webview component. I inject a preload script into the webview that does something like this:

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 needs this script passed as a file:// path like so:

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

The problem is that my webpack setup doesn't transpile preload.js because it isn't explicitly called via require() . Then, when I build the app, the path ./some/folder/ doesn't exist.

I've tried setting webpack to create a second compiled script like so:

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

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

But this leads to a JavaScript heap out of memory error, which leads me to believe this isn't correct.

Also: wouldn't this approach duplicate electron in the ./dist folder since it's require() 'd by both preload.js and index.js ?

You could use the electron-main and electron-preload configurations of 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'
    }
  },
]

You get two bundles after building, but Electron is not in either of them, so no duplicates.

Notice the __dirname: false , which is required since otherwise webpack replaces __dirname always replaced by / by webpack, leading to an unexpected behaviour in almost all cases (see here for further information, should be false by default, but wasn't for me).

We had a similar issue where we had several preload scripts instead of one. Our solution was to use the CopyPlugin . So for us, the config looks like this:

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"]
  }
};

So we just take the folder containing all our scripts and copy them to the autogenerated .webpack folder.

I was having the same problem and here's solution that worked for me:
Electron-webpack documentation now contains example how to add additional entries .

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

Note that you can use the @ alias to reference your main.sourceDirectory
in this case it's path to your main process script which will be src/main by default

This adds preload script from src/main/preload.js into webpack entries.
Then you need to add preload script into window with

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

That's all. __dirname was giving me relative path and electron requires absolute path for preload script so it was failing. path.resolve will get you absolute path needed to make it work.

Electron provides an option to load a script before any other execution in your DOM.

You have to provide your pre-load script file path while creating a browser window and file path of the script should be the absolute.

You can find reference here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM