dtolstyi / node-chromium

Node.js package that downloads and provides Chromium for your project
101 stars 33 forks source link

Bundling node-chromium with Webpack #35

Closed karlitos closed 4 years ago

karlitos commented 4 years ago

Hello, I'd like to use node-chromium in my project I use Webpack to bundle my JavaScript.

Chromium executable is probably not bundled automatically, since chrome.path gives me undefined. I could use something like copy-webpack-plugin to add the chromium to my assets, indeed logging chrome.path in the webpack.plugins.js returns __/Users/user1/Dev/myproject/node_modules/chromium/lib/chromium/chrome-mac/Chromium.app/Contents/MacOS/Chromium on MacOS. So using chromium.path.split('/lib')[0] I am able to get the path to the whole chromium directory, which I can copy to e.g. dist/asstes/chromium__

The question remains how to access the relative path to the executable in the bundle platform independently. I guess using chrome.path in the bundled JavaScript would give me undefined again

karlitos commented 4 years ago

I found a solution and was able to bundle chromium with my electron app. The solution is a combination of copy-webpack-plugin, webpack.DefinePlugin and shell script in the AfterEmitPlugin from the EmitHook

...
plugins: [
  new CopyPlugin({
    patterns: [
      {
        from: path.resolve(__dirname, chromium.path.split('/lib')[0], 'lib'),
        to: path.resolve(__dirname, '.webpack/main/'),
      },
    ],
  }),
 {
    apply: (compiler) => {
      compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
        exec(`chmod -R 755 ${path.resolve(__dirname, '.webpack/main/chromium/')}`, (err, stdout, stderr) => {
          if (stdout) process.stdout.write(stdout);
          if (stderr) process.stderr.write(stderr);
        });
      });
    },
  },
  new DefinePlugin({
    CHROMIUM_BINARY: JSON.stringify( chromium.path.split('/lib/')[1]),
  }),
]
... 

Please note the different split_ patterns: /lib and /lib/. This plugin combination copies the downloaded chromium in the dist folder (.webpack/main in my case - the chromium will be accessed by the Electrons main process), changes permissions after the build and creates the global variable CHROMIUM_BINARY, which can be than accessed and used to define the path to the chromium executable. const chromiumPath = path.resolve(__dirname, CHROMIUM_BINARY)

The downside of this solution is, that platform specific builds probably needs to be done separately on respective envoronments.