Skip to content

Commit 1e91bcf

Browse files
authored
Merge pull request #584 from simon04/production-build
production-build: enhance documentation
2 parents a856152 + c4eae2e commit 1e91bcf

File tree

2 files changed

+96
-38
lines changed

2 files changed

+96
-38
lines changed

content/guides/production-build.md

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,73 @@ sort: 13
44
contributors:
55
- henriquea
66
- rajagopal4890
7+
- markerikson
8+
- simon04
79
---
810

9-
Generating production builds with webpack is straight-forward. There are three things to keep in mind:
11+
This page explains how to generate production builds with webpack.
1012

11-
- Source Maps
12-
- Node environment
13-
- Minification
13+
## The automatic way
1414

15-
## Source Maps
15+
Running `webpack -p` (or equivalently `webpack --optimize-minimize --define process.env.NODE_ENV="production"`). This performs the following steps:
1616

17-
We encourage you to have Source Maps enabled in production. They are useful for debugging and to run benchmark tests. Webpack can generate inline Source Maps included in the bundles or separated files.
18-
19-
In your configuration, use the `devtools` object to set the Source Map type. We currently support seven types of Source Maps. You can find more information about them in our [configuration](/configuration/devtool) documentation page.
20-
21-
One of the good options to go is using `cheap-module-source-map` which simplifies the Source Maps to a single mapping per line.
22-
23-
## Node environment variable
24-
25-
The second step is to tell webpack to generate a production build by setting the Node.js environment variable to `production`. webpack will not include any extra useful code, warnings and checks used in development.
17+
- Minification using `UglifyJsPlugin`
18+
- Runs the `LoaderOptionsPlugin`, see its [documentation](/plugins/loader-options-plugin)
19+
- Sets the Node environment variable
2620

27-
The `DefinePlugin` creates **compile** time constants. Useful for injecting your Node.js environment as seen below.
21+
### Minification
2822

29-
?> TODO: Add a link to the `ProvidePlugin` documentation
23+
webpack comes with `UglifyJsPlugin`, which runs [UglifyJS](http://lisperator.net/uglifyjs/) in order to minimize the output. The plugin supports all of [UglifyJS options](https://github.com/mishoo/UglifyJS2#usage). Specifying `--optimize-minimize` on the command line, the following plugin configuration is added:
3024

3125
```js
3226
// webpack.config.js
33-
3427
const webpack = require('webpack');
3528

3629
module.exports = {
3730
/*...*/
38-
plugins: [
39-
new webpack.DefinePlugin({
40-
'process.env': {
41-
'NODE_ENV': JSON.stringify('production')
42-
}
31+
plugins:[
32+
new webpack.optimize.UglifyJsPlugin({
33+
sourceMap: options.devtool && (options.devtool.indexOf("sourcemap") >= 0 || options.devtool.indexOf("source-map") >= 0)
4334
})
4435
]
45-
/*...*/
4636
};
4737
```
4838

49-
T> Spoiler: Setting the env var only won't make your bundle smaller. This take us to the last step:
39+
Thus, depending on the [devtool options](/configuration/devtool), Source Maps are generated.
5040

51-
## Minification
41+
### Source Maps
5242

53-
webpack comes with UglifyJS plugin which minimize the output. You can pass an object containing [UglifyJS options](https://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin).
43+
We encourage you to have Source Maps enabled in production. They are useful for debugging and to run benchmark tests. Webpack can generate inline Source Maps included in the bundles or separated files.
44+
45+
In your configuration, use the `devtools` object to set the Source Map type. We currently support seven types of Source Maps. You can find more information about them in our [configuration](/configuration/devtool) documentation page.
46+
47+
One of the good options to go is using `cheap-module-source-map` which simplifies the Source Maps to a single mapping per line.
48+
49+
### Node environment variable
50+
51+
Running `webpack -p` (or `--define process.env.NODE_ENV="production"`) invokes the [`DefinePlugin`](/plugins/define-plugin) in the following way:
5452

5553
```js
5654
// webpack.config.js
57-
5855
const webpack = require('webpack');
5956

6057
module.exports = {
6158
/*...*/
6259
plugins:[
6360
new webpack.DefinePlugin({
64-
'process.env':{
65-
'NODE_ENV': JSON.stringify('production')
66-
}
67-
}),
68-
new webpack.optimize.UglifyJsPlugin({
69-
compress:{
70-
warnings: true
71-
}
61+
'process.env.NODE_ENV': JSON.stringify('production')
7262
})
7363
]
74-
/*...*/
7564
};
7665
```
77-
## Configuring webpack for multiple environments
7866

79-
When we do have multiple configurations in mind for different environments, the easiest way is to write seperate js files for
67+
The `DefinePlugin` performs search-and-replace operations on the original source code. Any occurrence of `process.env.NODE_ENV` in the imported code is replaced by by `"production"`. Thus, checks like `if (process.env.NODE_ENV !== 'production') console.log('...')` are evaluated to `if (false) console.log('...')` and finally minified away using `UglifyJS`.
68+
69+
T> Technically, `NODE_ENV` is a system environment variable that Node.js exposes into running scripts. It is used by convention to determine development-vs-production behavior, by both server tools, build scripts, and client-side libraries. Contrary to expectations, `process.env.NODE_ENV` is not set to `"production"` __within__ the build script `webpack.config.js`, see [#2537](https://github.com/webpack/webpack/issues/2537). Thus, conditionals like `process.env.NODE_ENV === 'production' ? '[name].[hash].bundle.js' : '[name].bundle.js'` do not work as expected.
70+
71+
## The manual way: Configuring webpack for multiple environments
72+
73+
When we do have multiple configurations in mind for different environments, the easiest way is to write seperate js files for
8074
each environment. For example:
8175

8276
** dev.js **

content/plugins/define-plugin.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: DefinePlugin
3+
---
4+
5+
``` javascript
6+
new webpack.DefinePlugin(definitions)
7+
```
8+
9+
The `DefinePlugin` allows you to create global constants which can be configured at **compile** time. This can be very useful for allowing different behaviour between development builds and release builds. For example, you might use a global constant to determine whether logging takes place; perhaps you perform logging in your development build but not in the release build. That's the sort of scenario the `DefinePlugin` facilitates.
10+
11+
**Example:**
12+
13+
``` javascript
14+
new webpack.DefinePlugin({
15+
PRODUCTION: JSON.stringify(true),
16+
VERSION: JSON.stringify("5fa3b9"),
17+
BROWSER_SUPPORTS_HTML5: true,
18+
TWO: "1+1",
19+
"typeof window": JSON.stringify("object")
20+
})
21+
```
22+
23+
``` javascript
24+
console.log("Running App version " + VERSION);
25+
if(!BROWSER_SUPPORTS_HTML5) require("html5shiv");
26+
```
27+
28+
T> Note that because the plugin does a direct text replacement, the value given to it must include actual quotes inside of the string itself. Typically, this is done either with alternate quotes, such as `'"production"'`, or by using `JSON.stringify('production')`.
29+
30+
Each key passed into `DefinePlugin` is an identifier or multiple identifiers joined with `.`.
31+
32+
* If the value is a string it will be used as a code fragment.
33+
* If the value isn't a string, it will be stringified (including functions).
34+
* If the value is an object all keys are defined the same way.
35+
* If you prefix `typeof` to the key, it's only defined for typeof calls.
36+
37+
The values will be inlined into the code which allows a minification pass to remove the redundant conditional.
38+
39+
**Example:**
40+
41+
``` javascript
42+
if (!PRODUCTION) {
43+
console.log('Debug info')
44+
}
45+
if (PRODUCTION) {
46+
console.log('Production log')
47+
}
48+
`````
49+
After passing through webpack with no minification results in:
50+
51+
``` javascript
52+
if (!true) {
53+
console.log('Debug info')
54+
}
55+
if (true) {
56+
console.log('Production log')
57+
}
58+
```
59+
60+
and then after a minification pass results in:
61+
62+
``` javascript
63+
console.log('Production log')
64+
```

0 commit comments

Comments
 (0)