ttmarek
ttmarek

Reputation: 3260

Is there a way to completely ignore dynamic requires in webpack?

I'm working on an electron app that uses dynamic requires to load in extensions (node modules) during run-time. The app currently gets an array of installed extensions loops through them, require's them and save's references to them:

getInstalledExtensions()
  .then(extensions => {
    extensions.map(extension => require(extension.path))
  })
  .then(saveExtensions)

I'm having trouble getting webpack to completely ignore the require statement on the third line: require(extension.path).

The list of installed extensions is not known at build time. When a user first installs the app the array is empty, it grows/shrinks as the user installs/uninstalls extensions.

I've tried:

module: {
    exprContextRegExp: /$^/,
    exprContextCritical: false,
}

but it just replaces require(extension.path) with

!(function webpackMissingModule() { var e = new Error("Cannot find module \".\""); e.code = 'MODULE_NOT_FOUND'; throw e; }())

Why do I want to use webpack in an electron app?

require is expensive and it affects my app's startup time considerably. As an example, require('request') takes about 800ms which is ridiculous. I'd like to bundle as many modules as I can to reduce my app's startup time.

I'd also like to have the possibility of using CSS loaders. I'm currently using a mix of global classes and inline styles, which isn't ideal.

Upvotes: 0

Views: 2739

Answers (3)

ravi
ravi

Reputation: 133

Webpack does not support fully dynamic expressions in import and require. There is hacky solution provided by the webpack in such situation which I think is very ugly. You can use the magic comment provided by webpack. For this, you include a comment webpackIgnore: true inside your import/require method.

require(/* webpackIgnore: true */ 'ignored-module')

getInstalledExtensions()
  .then(extensions => {
    extensions.map(extension => require(/* webpackIgnore:true */ extension.path))
  })
  .then(saveExtensions)


There is another option you can try. Check the webpack plugin webpack-ignore-dynamic-require.The plugin simply ignores require() if it has non string expression which in your case is require(extension.path).

Upvotes: 0

Monkey Juice
Monkey Juice

Reputation: 11

You can use window.require() instead of require() in electron.

Upvotes: 1

Anton Semenov
Anton Semenov

Reputation: 31

I had the same problem with making an yeoman package for atom. My solution is folowing:

  1. Create in output folder "originalRequire.js" file with only one line: module.exports = require.
  2. In webpack config mention "./originalRequire" in externals section (so it will not process and include originalRequire into build).
  3. Use string-replace-loader for replace require with require("./originalRequire"). In your example it will be require("./originalRequire")(extension.path).

Upvotes: 1

Related Questions