Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack - build bundle without dependencies

I;m wondering if it's possible to build a bundle with some javascript files but without dependencies?

I want to have small bundles with React components (each react component in my case is builded from few react components, for example Comment component incldues comment box, list, and form), I can split React components to a separate files by specifying few entry points in webpack, but if I have: 1. Component comment 2. Component newsletter and both of them require ReactDOM, files which will be generated will have like 600kb, where my react components contain only ~100 lines of js code.

I would like to have one more file which will contain all the code which would come from "require('react-dom'), and those two files which will only have the React component code. is that possible?

My current setup:

'use strict';
import path from 'path';
import CommonsChunkPlugin from "webpack/lib/optimize/CommonsChunkPlugin";
module.exports = {
    entry: {
        app: "./app.js",
        newsletter: "./components/renderers/newsletter.renderer.js",
        comment: "./components/renderers/comment.renderer.js"
    },
    output: {
        path: path.join(__dirname),
        filename: "built/[name].entry.js"
    },
    devtool: 'sourcemaps',
    cache: true,
    debug: true,
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: [/(node_modules)/],
                loader: 'babel'
            }
        ],
        resolve: {
            extensions: ['', '.js', '.jsx']
        }
    },
    plugins: [
        new CommonsChunkPlugin({
            name: "comment.js",
            chunks: ["comment", "app"],
            minChunks: 2
        }),
        new CommonsChunkPlugin({
            name: "newsletter.js",
            chunks: ["newsletter", "app"],
            minChunks: 2
        })
    ]
};

Comment.renderer.js:

import CommentBox from './../comment/commentBox';
ReactDOM.render(
    <CommentBox/>,
    document.getElementById("comment")
);

Newsletter.renderer.js:

import Newsletter from './../newsletter/newsletter';
ReactDOM.render(
    <Newsletter/>,
    document.getElementById("newsletter")
);

app.js:

'use strict';
import React from 'react';
import ReactDOM from 'react-dom';
import client from './lib/client';
like image 885
Ma Kro Avatar asked Mar 14 '23 17:03

Ma Kro


2 Answers

Ok I've managed how to do that:

import path from 'path';
import CommonsChunkPlugin from "webpack/lib/optimize/CommonsChunkPlugin";
module.exports = {
    entry: {
        vendor: ["react","react-dom", "underscore"],
        comment: "./components/renderers/comment.renderer.js",
        newsletter: "./components/renderers/newsletter.renderer.js"
    },
    output: {
        path: path.join(__dirname),
        filename: "built/[name].bundle.js"
    },
    devtool: 'sourcemaps',
    cache: true,
    debug: true,
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: [/(node_modules)/],
                loader: 'babel'
            }
        ],
        resolve: {
            extensions: ['', '.js', '.jsx']
        }
    },
    plugins: [
        new CommonsChunkPlugin({
            name: "vendor",
            minChunks: Infinity
        })
    ]
};

this part:

minChunks: Infinity

will ensure that code included in bundle "vendor" is not included in any other bundle. Thanks to this approach, comment and newsletter will contain only my React components.

like image 72
Ma Kro Avatar answered Mar 23 '23 15:03

Ma Kro


I use following code in webpack.config.js to exclude the external dependencies from bundle.

module.exports = {
     ...
     ...
    externals:{
       "react": "React",
       "react-dom": "ReactDOM"
     },
     ...
     ...
}

I found this answer from this link

like image 21
AnandShanbhag Avatar answered Mar 23 '23 13:03

AnandShanbhag