Search code examples
webpacksource-maps

Webpack slow on vendors compilation


I'm using webpack to generate my bundle and vendors.

My problem is that, since I've added the vendors to my compilation, my compilation time has go from 2s to 20s (on a slow machine, you can wait like 40s).

I've notice that sourceMap is generated all the time, but when I'm compiling for production, it's not optimized to generate sourceMap then remove them with the Uglify plugin. I guess I missed the point somewhere!

I've tried the #eval but the weight is like 4x time bigger and also isn't compiling faster (even slower).

So i'm looking for the Holy Graal: * a way to disable sourceMap for all the compilation * a way to disable sourceMap for only vendor (for development) * a caching system to recompile only changed file (like when using the --watch)

My workflow is to use a dev env (so I use the --watch) on my local machine, then pushing it to my dev server with Jenkins that compile everything. Using watch on the server is not an option (I keep webpack up to date, and if I change the vendor list, I have to restart the --watch))

An option could be to remove vendors from my webpack config, but that would be my last try.

my webpack.config.js:

var path = require('path');
var webpack = require('webpack');

var jsPath = path.join(__dirname, './src/js/src/');
var vendorPath = path.join(__dirname, './src/js/src/vendors/');

// Detect environnement from package.json or command line
var prod = process.argv.indexOf("--prod") > -1;
var dev = process.argv.indexOf("--dev") > -1;

module.exports = {
    entry: {
        app: jsPath + 'init.js',
        vendor: [
            vendorPath + 'jquery.js',
            vendorPath + 'bootstrap.js',
            vendorPath + 'nunjucks.js',
            vendorPath + 'jquery.pickmeup.js',
            vendorPath + 'select2.js',
            vendorPath + 'select2_ext.js'
        ]
    },
    // Key for ProvidePlugin
    resolve: {
        alias: {
            jquery: vendorPath + 'jquery.js'
        }
    },
    output: {
        path: path.join(__dirname, './src/js/build/'),
        filename: 'bundle.js',
        publicPath: ''
    },
    devtool: prod ? "" : "#inline-source-map",
    module: {
        loaders: [
            {test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", query: {compact: false}}
        ]
    },
    plugins: [
        // Expose $ as global variable
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery"
        }),
        // Concat vendors files
        new webpack.optimize.CommonsChunkPlugin({
            name: "vendor",
            filename: "vendor.js",
            minChunks: Infinity
        }),
        // Set __DEBUG__ global variable
        new webpack.DefinePlugin({
            __DEBUG__: dev
        })
    ]
    // In 'production', Uglify all JS chunked files
        .concat(prod ?
            [
                new webpack.optimize.UglifyJsPlugin({
                    compress: {
                        warnings: false
                    },
                    sourceMap: false,
                    mangle: {
                        except: ['$', 'exports', 'require']
                    }
                })
            ]
            : []
        )
};

Solution

  • You can use the SourceMapDevToolPlugin directly instead of devtool in order to exclude certain chunks from having source maps generated. For example, if you want to exclude your vendor and polyfills bundles:

    config.plugins.push(new webpack.SourceMapDevToolPlugin({
      filename: '[name].js.map',
      exclude: ['vendor.js', 'polyfills.js']
    }));