webpack: Building React For Production on Windows

I ran into some unexpected errors while trying to build React for production using a Windows machine (which was undocumented in the React docs. No love for Windows machines? =p).

The below is just some documentation of my research for personal reference.

Mac OS: Package.json webpack Build Script

The React docs provide the following script:

package.json
  "scripts": {
    "build": "NODE_ENV='production' webpack -p"
  }

Windows: Package.json webpack Build Script

However, trying to run the above script on a Windows machine (even using cygwin) will give you the error:

'NODE_ENV' is not recognized as an internal or external command, operable program or batch file.

The script needs to be run slightly differently on Windows machines:

package.json
  "scripts": {
    "build": "set NODE_ENV=production && webpack -p"
  }

Understanding The Scripts

1. package.json: Optimizing webpack for Production

The webpack production flag webpack -p is shorthand for --optimize-minimize --optimize-occurrence-order.

--optimize-minimize: Minimize scripts and CSS (if using css-loader).

--optimize-occurrence-order: webpack assigns IDs to modules and chunks (I believe for caching validation purposes). --optimize-occurrence-order makes sure that commonly used ids will have a smaller id length.

package.json
// Set NODE_ENV for webpack to 'production'
// Use the webpack 'production' shortcut, -p
  "scripts": {
    "build": "set NODE_ENV=production && webpack -p"
  }

2. webpack.config.js: Build React for Production and Minify JS

In webpack, DefinePlugin,allows creating global constants that can be configured at compile time. This provides flexibility for different behaviors between development builds and release builds.

Tell React to use the production version of React

This instance of DefinePlugin performs a search-and-replace on the original source code, and instances of process.env.NODE_ENV in the imported code is replaced by "production".

React's internals has references to process.env.NODE_ENV. When set to, "production", React removes warning messages to reduce file-size and increase performance.

webpack.config.js
new webpack.DefinePlugin({
  "process.env.NODE_ENV": JSON.stringify("production")
});

Make webpack Minify Javascript code

webpack comes with UglifyJsPlugin, and uses UglifyJS to minimize the output.

webpack.config.js
new webpack.optimize.UglifyJsPlugin();

Complete webpack.config.js

webpack.config.js
let path = require("path");
let HtmlWebpackPlugin = require("html-webpack-plugin");
let webpack = require("webpack");

let config = {
  entry: "./app/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "index.bundle.js",
    publicPath: "/"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader"
      },
      {
        exclude: /(node_modules)/,
        test: /\.css$/,
        use: ["style-loader", "css-loader"]
      }
    ]
  },
  devServer: {
    historyApiFallback: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "app/index.html"
    })
  ]
};

if (process.env.NODE_ENV === "production") {
  config.plugins.push(
    new webpack.DefinePlugin({
      "process.env.NODE_ENV": JSON.stringify("production")
    }),
    new webpack.optimize.UglifyJsPlugin()
  );
}

module.exports = config;