Advanced Webpack Configuration Techniques and Tips
The article presents advanced Webpack configuration strategies—including programmatic Node‑API builds, streamlined loader setups, global module injection and environment definitions, commons chunk extraction, DLL bundling, on‑demand code splitting, UglifyJS minification, and server‑side bundling—to help developers efficiently manage complex projects.
The article shares practical tips and key configurations accumulated from using Webpack in projects, aiming to help developers avoid dealing with module organization, loading, transformation, merging, minification, and compatibility issues.
1. Complex project configuration (Node API)
For complex projects (e.g., isomorphic apps) you can generate configurations programmatically using the Node API instead of static config files. A typical build script looks like this:
var webpack = require('webpack');
var configGen = require("./config.generator");
// Generate custom config from command‑line arguments
var config = configGen(options);
var compiler = webpack(config);
compiler.run(function(err, stats) {
if (err) {
console.err(err);
} else {
console.log(stats.toString({
colors: true
}));
}
});Then add a script entry in package.json:
{
"scripts": {
"build": "node ./build.js"
}
}Run it with npm run build. You can also use webpack-dev-server for a local development server.
2. Loader configuration
Place common loaders in the configuration to keep source code clean. Example for handling .jsx files with Babel:
module: {
loaders: [
{
test: /\.jsx$/,
include: path.resolve(__dirname, "lib"),
loader: "babel-loader",
query: {
presets: ["react", "es2015"],
plugins: ["syntax-object-rest-spread", "transform-object-rest-spread"],
cacheDirectory: true
}
}
]
}If a loader must run before others, use module.preLoaders. To alias custom loaders, configure resolveLoader.alias:
resolveLoader: {
alias: {
"seajs-loader": path.resolve(__dirname, "./web_modules/seajs-loader.js")
}
}When loaders are located outside the project root, set resolveLoader.root to the default location:
resolveLoader: {
// specify default loader path
root: path.resolve(__dirname, "./node_modules")
}3. Global modules and environment variables
Use ProvidePlugin to automatically inject modules like jQuery:
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery"
})
]Use DefinePlugin to embed static constants or environment‑specific values at compile time:
plugins: [
new webpack.DefinePlugin({
"process.env": {
NODE_ENV: JSON.stringify(options.dev ? 'development' : 'production')
},
"__SERVER__": isServer ? true : false
})
]4. Common chunk extraction
For multi‑entry projects, extract shared libraries with CommonsChunkPlugin:
entry: {
a: "./a.js",
b: "./b.js",
common1: [
"./lib/common.js",
"react",
"react-dom",
"redux",
"react-redux",
"redux-thunk",
"react-router",
"react-router-redux"
]
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['common1'],
minChunks: Infinity
})
]5. DllPlugin and DllReferencePlugin
Separate rarely‑changed third‑party libraries into a DLL bundle:
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: {
vendor: ["react", "react-dom", "redux", "react-redux", "redux-thunk", "react-router", "react-router-redux"]
},
output: {
filename: '[name].dll.js',
path: path.resolve(__dirname, './output/dll'),
library: "[name]"
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(__dirname, './output/dll/[name]-manifest.json'),
name: "[name]"
}),
new webpack.optimize.UglifyJsPlugin({ minimize: true, output: { comments: false } })
]
};Build it with webpack --config=config.dll.js. In the main project, reference the DLL via DllReferencePlugin:
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./output/dll/vendor-manifest.json')
})
]6. Code splitting / on‑demand loading
Use require.ensure to create split chunks that are loaded only when needed:
require.ensure(["./c"], function(require) {
var bbb = require("./b");
console.log(bbb.foo);
}, 'chunk-one');Only modules listed in the dependencies array are fetched; they are not executed until required. The complementary require.include can preload a module without executing it.
7. UglifyJS plugin
Configure minification and compression options:
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: { warnings: false },
except: [],
output: { comments: true }
})
]8. Server‑side bundling
When targeting Node, set target: "node", export with libraryTarget: "commonjs2", and exclude external modules via externals:
// Example snippet
target: "node",
externals: [/node_modules/],
output: {
libraryTarget: "commonjs2",
pathinfo: true
}These settings keep native Node modules as require calls and prevent them from being bundled.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Tencent Music Tech Team
Public account of Tencent Music's development team, focusing on technology sharing and communication.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
