Pierre Capo
Pierre Capo

Reputation: 1053

Webpack 4 : generating a shared dependency

I have 2 applications and they both use a common dependency (the d3 library) :

App1:

// app1.js
import * as d3 from "d3";

App2:

//app2.js
import * as d3 from "d3";

I don't want to duplicate this dependency and have it in each file, instead I would like that Webpack generates my 2 app files with an additional file for the dependency usable by the 2 apps :

This is what I have done so far :

const path = require('path');

module.exports = {
  entry: {
      app1:'./app1/main.js',
      app2: './app2/main.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  optimization: {
     splitChunks: {
       chunks: 'all'
     }
   }
}

But what I get is a vendor for each app :

Upvotes: 0

Views: 1278

Answers (3)

Pierre Capo
Pierre Capo

Reputation: 1053

Alright, so thanks to @MatheusSilva answer and Jamie answer, I have been able to understand the issue :

  • First, I've used MatheusSilva's code to generate only one file.

  • Second, I had node_modules folder inside each folder of both apps, and although they used the exactly same version of d3 (same package.json), webpack was duplicating the dependency still. I've had to remove d3 from each node_modules folder, and define and install d3 in the root folder, from where I'm building all my bundles. And thanks to this, webpack didn't duplicate d3.

Upvotes: 0

Jamie
Jamie

Reputation: 6114

I tested with [email protected], entering everything just as you specified. It seemed to work for me.

app1/main.js

import * as d3 from "d3";

app2/main.js

import * as d3 from "d3";

package.json

{
  "name": "webpacktest",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "d3": "^5.5.0",
    "webpack": "^4.16.2",
    "webpack-cli": "^3.1.0"
  }
}

webpack.config.js

const path = require('path');

module.exports = {
  entry: {
      app1:'./app1/main.js',
      app2: './app2/main.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  optimization: {
     splitChunks: {
       chunks: 'all'
     }
   }
}

Running

yarn webpack

I get

yarn run v1.7.0
$ /mydir/webpacktest/node_modules/.bin/webpack
Hash: 7011417172396d73dd17
Version: webpack 4.16.2
Time: 1807ms
Built at: 2018-07-23 09:58:23
               Asset      Size  Chunks                    Chunk Names
vendors~app1~app2.js   244 KiB       0  [emitted]  [big]  vendors~app1~app2
             app1.js  1.49 KiB       1  [emitted]         app1
             app2.js  1.49 KiB       2  [emitted]         app2
Entrypoint app1 [big] = vendors~app1~app2.js app1.js
Entrypoint app2 [big] = vendors~app1~app2.js app2.js
[0] ./node_modules/d3/index.js + 505 modules 520 KiB {0} [built]
    |    506 modules
[1] ./app1/main.js 46 bytes {1} [built]
[2] ./app2/main.js 46 bytes {2} [built]

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
  vendors~app1~app2.js (244 KiB)

WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
  app1 (246 KiB)
      vendors~app1~app2.js
      app1.js
  app2 (246 KiB)
      vendors~app1~app2.js
      app2.js


WARNING in webpack performance recommendations: 
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/
Done in 2.60s.

With ./dist contents:

  • app1.js
  • app2.js
  • vendors~app1~app2.js

Upvotes: 1

PlayMa256
PlayMa256

Reputation: 6831

I'm just not really good with regex, but i tried.

module.exports = {
  entry: {
      app1:'./app1/main.js',
      app2: './app2/main.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist')
  },
  optimization: {
     splitChunks: {
        cacheGroups: {
            vendor: {
                test: /node_modules/,
                name: 'vendor',
                chunks: "all",
                priority: -10
            }
        }
     }
   }
}

Upvotes: 1

Related Questions