T.Todua
T.Todua

Reputation: 56487

How to force WebPack to use one version of module (instead of 6 different versions?)

In our project Webpack-bundle-analyzer plugin says that the bundle uses specific module (js file) 6 times.

enter image description here

What is the best way to make project as it used only one ( instead of multiple)? I know they might be from dependencies' depencendies, but how such problem should be solved?


I am OK with checking my APP manually for possible code-breaks, but the goal is surely to use one bn.js. Our package.json doesnt contain it in any dependencies directly.

Upvotes: 4

Views: 4198

Answers (2)

PMCS
PMCS

Reputation: 21

I agree with the accepted answer that doing this for transitive dependencies is very risky, however, if you know what you are doing:

Another approach would be to write a custom Plugin based on the NormalModuleReplacementPlugin which will always resolve to an aliased version.

Let's say you always want to use [email protected] when Webpack encounters require('lodash') / import lodash from 'lodash'.

This is very useful if your non-webpack code (for example custom Node scripts) depend on a different version, but you'd like to use another version for runtime code.

// package.json
{
  "dependencies": {
    "lodash-for-webpack": "https://registry.npmjs.org/lodash/-/lodash-4.17.2.tgz",
    "lodash": "^3.0.0"
  }
}
const webpack = require('webpack');

// Match 'lodash', 'lodash/foo/bar', but not 'lodash-es' or 'webpack-lodash-plugin'
const lodashRegex = /lodash(?!-)(\/[a-zA-Z0-9\-_]*)*/;

function FixLodashVersionPlugin () {
  return new webpack.NormalModuleReplacementPlugin(
    lodashRegex,
    function (resource) {
      const segments = resource.request.split('/');

      if (segments[0] === 'lodash') {
        segments[0] = 'lodash-for-webpack';
        resource.request = segments.join('/');
      }
    }
  );
}

module.exports = {
  FixLodashVersionPlugin
};

Note that in this example I directly link to a gzipped tarball, as documented in the npm install docs under b) and c). But you could also use the npm: prefix.

Upvotes: 0

felixmosh
felixmosh

Reputation: 35553

This situation happens probably because your app (or it's dependencies) are requiring a different version of the same lib.

It is not recommended to "force" the same version by hacking some Webpack's config (it is possible). There is a meaning to semantic versioning, if the lib bumped a major version, this means that it contains breaking changes.

A better approach will be to manually align the version of the lib (or its consumer).

You can run yarn why lib-name or npm ls lib-name which will print you a list of dependencies which are consuming the lib and at which version, this will help you to upgrade the dependencies in order to align the versions.

If you still want to force, you can check these solutions https://github.com/webpack/webpack/issues/6505

  1. Using yarn resolutions to install only one version.
  2. Using webpack alias, to alias the lib-name to a specific path (each different version is installed in the consumer node_modules folder)
  3. Force webpack to resolve only from the app node_modules by
// webpack.config.js
module.exports = {
  ...
  modules: [
    path.join(__dirname, '../node_modules')
  ]
  ...
}

Upvotes: 2

Related Questions