webpack By Example: Part 1
webpack (apparently always written in lowercase) is a module bundler. Rather than trying to explain what this means, we will explore the purpose and functionality of webpack through a series of increasingly complex examples. The examples’ configuration files and source code is available as a GitHub repository.
To follow along on your own, you will need to have the following installed:
- Node.js : Node.js is a JavaScript runtime built on Chrome’s V8 JavaScript engine.
- webpack-cli : Among other things, webpack-cli, is a scaffolding tool to create webpack configuration files.
For each of the examples, the first step is to create a new folder (one per example) and from the command line in it, run npm init
to initialize a project (creating a package.json file).
For each of the examples the entry point to the application will be the file ./src/index.js (used for both npm and webpack commands).
hello-world
The entry point for this example is a very simple ES5 implementation with no CSS files.
src/index.js
window.console.log('hello world');
By choosing No
on all the questions during the execution of webpack-cli init
(from the command line in the project folder) the we end up with an (almost) minimal webpack configuration. The configuration does includes UglifyJS Webpack Plugin that minifies the output.
webpack.config.js
const webpack = require('webpack');
const path = require('path');/*
* We've enabled UglifyJSPlugin for you! This minifies your app
* in order to load faster and run less javascript.
*
* https://github.com/webpack-contrib/uglifyjs-webpack-plugin
*
*/const UglifyJSPlugin = require('uglifyjs-webpack-plugin');module.exports = {
entry: './src/index.js',
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: []
},
plugins: [new UglifyJSPlugin()]
};
note: As of version 1.3.1, webpack-cli incorrectly specifies the output path in the configuration (I manually corrected). By the time you read this, however, the fix is likely to have been incorporated into the next release.
Executing the command ./node_modules/.bin/webpack
from the command line in the project folder will create a main.bundle.js file in the dist folder. This file is simply a minified version of the original source code.
To use the bundled file, create the index.html file into the dist folder and open it a browser; the developer console will display hello world.
dist/index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>webpack Patterns</title>
</head>
<body>
<script src="main.bundle.js"></script>
</body>
</html>
production
As with the previous example, the entry point for this example is a very simple ES5 implementation with no CSS file.
src/index.js
window.console.log('hello world');
if (process.env.NODE_ENV !== 'production') {
window.console.log('not in production');
}
As with the previous example, we chose No
on all the questions during the execution of webpack-cli init
(from the command line in the project folder); thus we get the same webpack.config.js file as before.
Executing the command ./node_modules/.bin/webpack
from the command line in the project folder will create a main.bundle.js file in the dist folder. As before, this file is simply a minified version of the original source code.
To use the bundled file, create the index.html file (above) into the dist folder and open it a browser; the developer console will display hello world followed by not in production.
Executing the command ./node_modules/.bin/webpack -p
will create an updated main.bundle.js. Reloading the index.html file will now only display hello world in the developer console; the unreachable code was minified away by the UglifyJS Webpack Plugin.
source-map
In the previous examples, the JavaScript was minified and no source maps were generated; thus using debugging tools (e.g., Chrome Developer Tools) do not have access to the original source code (making debugging virtually impossible).
In this example, everything is identical to the production example, except we update the UglifyJS Webpack Plugin’s options in webpack.config.js to support source maps.
webpack.config.js
...
plugins: [new UglifyJSPlugin({sourceMap: true})]
...
To generate the source map simply add the command line option --devtool source-map
at the end of the webpack command, e.g., ./node_modules/.bin/webpack -p --devtool source-map
note: Remember, source maps are not downloaded (do not impact performance) unless a developer tool that uses source maps is being used, e.g., Chrome Developer Tools is open.
The Next Part
In the next part, webpack By Example: Part 2, we will explore including CSS files in our project.