0

We have 4 React components bundled with Webpack (version 1): A, B, C and D. The dependency tree looks like this:

  • A
    • B
      • D
    • C
      • D

We want each component to be reusable, so we use webpack to generate a UMD module. The generated bundle for each component is located in ./dist/index.js, and the package.json of each component sets this script as the entry point for the library:

"main": "./dist/index.js"

This is the webpack config file for component A:

const webpack = require('webpack');
const UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;

var reactExternal = {
    root: 'React',
    commonjs2: 'react',
    commonjs: 'react',
    amd: 'react'
};
var reactDOMExternal = {
    root: 'ReactDOM',
    commonjs2: 'react-dom',
    commonjs: 'react-dom',
    amd: 'react-dom'
};

module.exports = {
    entry: {
        index: ['./src/index.js'],
        'index.min': ['./src/index.js']
    },

    output: {
        path: './dist/',
        filename: '[name].js',
        library: 'ComponentA',
        libraryTarget: 'umd'
    },

    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel'
            },
        ]
    },

    plugins: [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
        }),
        new UglifyJsPlugin({
            include: /\.min\.js$/,
            minimize: true,
            compress: {
                warnings: false
            }
        })
    ],

    externals: {
        react: reactExternal,
        'react-dom': reactDOMExternal
    },

    devtool: 'source-map'
};

The rest of webpack config files for B, C and D components are the same but changing the name of the library to export in output.library, so for component B

outpub.library: 'ComponentB',

for component C

output.library: 'ComponentC',

and for component D

output.library: 'ComponentD',

Everything works fine except for A's bundle size. The bundle is too heavy because D is duplicated inside of A's ./dist/index.js.

We have tried using Dedupe plugin to no avail. It seems webpack is not able to 'see' inside the already bundled dist B and C files to extract the common code from D. Isn't webpack able to detect duplicates between two of their own generated bundles?

We also tried to change package.json files so that the main entry is the non-transpiled version "main": "./src/index.js". This allows webpack to detect D duplication but this solution is not suitable as leaves us with non-transpiled ES6 entrypoints to our components.

Any ideas?

jaime
  • 520
  • 5
  • 15
  • I don't know why you would want to pack everything separately anyway. Just let Webpack handle everything into a single file and that's it. If that leaves you with something non-transpiled then you have something wrong in the configuration. Webpack can take everything and transpile it into a single blob you can then use. – Sami Kuhmonen Feb 15 '17 at 12:26
  • We need to bundle components separately as they are individually used in other projects / use cases. – jaime Feb 15 '17 at 12:47
  • 1
    Does that mean A is requiring the bundled versions of B and C? If yes, it's no surprise that D is duplicated (since you are including two separate bundles). A should include the non-bundled versions. – Felix Kling Feb 15 '17 at 14:06
  • Yes, A requires B and C bundles. This is because B and C are also available as independent modules. How can we instruct webpack to use the non-bundled version of the import while keeping the main entrypoint of the component as a bundle? – jaime Feb 15 '17 at 14:37

0 Answers0