Exclude module from webpack minification

Bronumski picture Bronumski · Nov 25, 2015 · Viewed 22.9k times · Source

We are using WebPack in a single page application. The application is deployed to many environments. We have a requirement where the application needs to call a specific endpoint in a given environment.

In order to provide the endpoint address for the given environment is to have an environments module. This is the current solution (there are many and this is not the point of the question). However we need to exclude the config.js from minification so that it can be overwritten as part of the deployment process.

The config.js looks like the following:

module.exports = {
    env: {
        endpointUrl: 'http://1.2.3.4',
        authUrl: 'http://5.6.7.8'
    }
};

And is referenced using the following:

const endpointUrl = config.env.endpointUrl;
const authUrl = config.env.authUrl;

The WebPack config looks like the following:

var webpack = require('webpack');
​
module.exports = {
    entry: {
        main: './src/js/main.jsx',
        login: './src/js/login-main.jsx'
    },
    output: {
        path: __dirname + '/dist',
        filename: '[name].bundle.js'
    },
    devtool: 'source-map',
    module: {
        loaders: [{
            test: /.jsx?$/,
            exclude: /node_modules/,
            loader: 'babel-loader',
            plugins: ['transform-react-jsx'],
            query: {stage: 0}
        }, {
            test: /\.jsx?$/,
            exclude: /node_modules/,
            loader: 'eslint-loader'
        }]
    },
    plugins: [
        new webpack.ProvidePlugin({
            fetch: 'imports?this=>global!exports?global.fetch!whatwg-fetch'
        }),
        new webpack.DefinePlugin({
            __DEV__: JSON.stringify(JSON.parse(process.env.DEV || false))
        })
    ]
};

So far we have looked at externals and module loaders but have not found anything that works. The exclude in the module loader still causes the module to be minified.

Some SO questions that we have looked at:

Answer

dreyescat picture dreyescat · Nov 29, 2015

Webpack externals are a good option to avoid bundle certain dependencies.

However we need to exclude the config.js from minification so that it can be overwritten as part of the deployment process.

Adding a dependency as external not only excludes it from minification but it is not even resolved by webpack.

webpack.config.js

var webpack = require('webpack');

module.exports = {
  entry: {
    index: './src/index.js'
  },
  output: {
    path: './dist',
    filename: 'bundle.js'
  },
  externals: {
    './config': 'config'
  }
};

Add as external the path used to require your config.js. In my simple example the path corresponds to ./config. Associate it to the global variable that will contain your configuration object. In my case I just used config as the variable name (see below config.js).

index.js

const config = require('./config');

const endpointUrl = config.env.endpointUrl;
const authUrl = config.env.authUrl;

console.log(endpointUrl);
console.log(authUrl);

As you are preventing webpack to resolve the config.js module then it has to be available in the environment during runtime. One way could be to expose it as a config variable in the global context.

config.js

window.config = {
  env: {
    endpointUrl: 'http://1.2.3.4',
    authUrl: 'http://5.6.7.8'
  }
};

Then you can load a specific config.js file for any given environment.

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Webpack</title>
</head>
<body>
  <script type="text/javascript" src="config.js"></script>
  <script type="text/javascript" src="dist/bundle.js"></script>
</body>
</html>