webpack.config.production.js 10.3 KB
/**
 * React Starter Kit (http://www.reactstarterkit.com/)
 *
 * Copyright © 2014-2015 Kriasoft, LLC. All rights reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE.txt file in the root directory of this source tree.
 */

import path from 'path';
import webpack from 'webpack';
import AssetsPlugin from 'assets-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import HappyPack from 'happypack';

import os from 'os';
import UglifyJsPlugin from 'uglifyjs-webpack-plugin';


import ParallelUglifyPlugin from 'webpack-parallel-uglify-plugin';
import UglifyJsParallelPlugin from 'webpack-uglify-parallel';
import getSettings from '../server/boot/config';

var happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
var extractLESS = new ExtractTextPlugin('css/[name].css?[contenthash]');
var extractLES = new ExtractTextPlugin('css/less[name].css?[contenthash]');


// process.traceDeprecation = true ;
const framePath = path.resolve(__dirname, '..');
const DEBUG = !process.argv.includes('--release');
const VERBOSE = process.argv.includes('--verbose');
const prefix = getSettings().defaults.prefix || '/';
const minimizeCssOptions = {
  discardComments: { removeAll: true },
};
const AUTOPREFIXER_BROWSERS = [
  'Android 2.3',
  'Android >= 4',
  'Chrome >= 35',
  'Firefox >= 31',
  'Explorer >= 9',
  'iOS >= 7',
  'Opera >= 12',
  'Safari >= 7.1',
];

const GLOBALS = {
  'process.env.NODE_ENV': DEBUG ? '"development"' : '"production"',
  __DEV__: DEBUG,
  '__DEBUG__': DEBUG,
  '__DEBUG_NW__': false,
  '__PREFIX__': `'${prefix}'`
};

var lessLoader = extractLESS.extract('style-loader', [`css-loader?${JSON.stringify({
  sourceMap: DEBUG,
  minimize: !DEBUG
})}`, 'less-loader' + (DEBUG ? '?sourceMap' : '?minimize')]);
var lesLoader = extractLES.extract('style-loader', [`css-loader?${JSON.stringify({
  sourceMap: DEBUG,
  modules: true,
  localIdentName: DEBUG ? '[name]_[local]_[hash:base64:3]' : '[hash:base64:4]',
  minimize: !DEBUG
})}`, 'postcss-loader', 'less-loader' + (DEBUG ? '?sourceMap' : '?minimize')]);
//
// Common configuration chunk to be used for both
// client-side (app.js) and server-side (server.js) bundles
// -----------------------------------------------------------------------------

const config = {
  context: path.resolve(__dirname, '../src'),
  output: {
    path: DEBUG ? path.resolve(__dirname, '../build') : path.resolve(__dirname, '../temp_build'),
    publicPath: prefix,
    sourcePrefix: '  ',
  },
  module: {
    strictExportPresence: true,
    rules: [
      ...(DEBUG ?
        [{
          test: /\.(js|jsx?)$/,
          loader: 'babel-loader',
          include: [
            path.resolve(__dirname, '../node_modules/react-routing/src'),
            path.resolve(__dirname, '../node_modules/antd/lib'),
            path.resolve(__dirname, '../node_modules/pinyin'),
            path.resolve(__dirname, '../src'),
            path.resolve(__dirname, '../tests')
          ],
          exclude: /node_modules/,
          options: {
            cacheDirectory: DEBUG,
            babelrc: false,
            presets: [
              'react',
              'es2015',
              'stage-0',
            ],
            env: {
              development: {
                plugins: [
                  ['react-transform', {
                    transforms: [{
                      transform: 'react-transform-hmr',
                      imports: ['react'],
                      locals: ['module']
                    }, {
                      transform: 'react-transform-catch-errors',
                      imports: ['react', 'redbox-react']
                    }]
                  }]
                ]
              }
            },
            plugins: [
              'transform-runtime',
              'add-module-exports',
              ["import", [{ "style": "css", "libraryName": "antd" }]]
            ]
          }
        }]
        :
        [{
          test: /\.(js|jsx?)$/,
          loader: 'happypack/loader?id=babelJs',
          include: [
            path.resolve(__dirname, '../node_modules/react-routing/src'),
            path.resolve(__dirname, '../node_modules/antd/lib'),
            path.resolve(__dirname, '../node_modules/pinyin'),
            path.resolve(__dirname, '../src'),
            path.resolve(__dirname, '../tests')
          ],
          exclude: /node_modules/
        }]
      ), {
        test: /\.les$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              // CSS Loader https://github.com/webpack/css-loader
              url: false,
              importLoaders: 1,
              sourceMap: DEBUG,
              // CSS Modules https://github.com/css-modules/css-modules
              modules: true,
              localIdentName: DEBUG
                ? '[name]_[local]_[hash:base64:3]'
                : '[hash:base64:4]',
              // CSS Nano http://cssnano.co/
              minimize: DEBUG ? false : minimizeCssOptions,
            }
          },
          {
            loader: 'less-loader'
          }
        ]
      }, {
        test: /\.less$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
              sourceMap: DEBUG,
              minimize: DEBUG ? false : minimizeCssOptions,
            }
          },
          {
            loader: 'less-loader'
          }
        ]
      }, {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: DEBUG,
              minimize: DEBUG ? false : minimizeCssOptions,
            }
          },
          {
            loader: 'postcss-loader',
            options: {
              config: { path: path.resolve(__dirname, '../tools/postcss.config.js') }
            }
          }
        ]
      }, {
        test: /\.json$/,
        loader: 'json-loader',
      }, {
        test: /\.txt$/,
        loader: 'raw-loader',
      }, {
        test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
        loader: 'url-loader',
        options: {
          name: DEBUG ? '[path][name].[ext]?[hash]' : '[hash].[ext]',
          limit: 10000,
        }
      }, {
        test: /\.(eot|ttf|wav|mp3)$/,
        loader: 'file-loader',
        options: {
          name: DEBUG ? '[path][name].[ext]?[hash]' : '[hash].[ext]',
        }
      },
    ],
  },
  resolve: {
    modules: ['node_modules'],
    extensions: ['.les', '.webpack.js', '.web.js', '.js', '.jsx', '.json', '.less']
  },
  cache: DEBUG,
  stats: {
    colors: true,
    reasons: false,
    hash: VERBOSE,
    version: VERBOSE,
    timings: true,
    chunks: VERBOSE,
    cached: VERBOSE,
    cachedAssets: VERBOSE,
    assets: true,
    modules: false
  }
};

//
// Configuration for the client-side bundle (app.js)
// -----------------------------------------------------------------------------

const appConfig = Object.assign({}, config, {
  entry: {
    app: [
      ...(DEBUG ? ['webpack-hot-middleware/client'] : []),
      './app.js'
    ]
  },
  output: {
    path: DEBUG ? path.resolve(__dirname, '../build' + prefix.substring(0, prefix.length - 1)) : path.join(__dirname, '../temp_build/public' + prefix.substring(0, prefix.length - 1)),
    publicPath: prefix,
    filename: DEBUG ? '[name].js?[hash]' : '[name].[hash].js',
  },
  devtool: DEBUG ? '#cheap-module-eval-source-map' : false,
  plugins: [
    new webpack.DefinePlugin(GLOBALS),
    ...(!DEBUG ? [
      new HappyPack({
        id: 'babelJs',
        threadPool: happyThreadPool,
        loaders: [{
          loader: 'babel-loader',
          options: {
            cacheDirectory: DEBUG,
            babelrc: false,
            presets: [
              'react',
              'es2015',
              'stage-0',
            ],
            plugins: [
              'transform-runtime',
              'add-module-exports',
              ["import", [{ "style": "css", "libraryName": "antd" }]]
            ]
          }
        }]
      })
    ] : []),
    new AssetsPlugin({
      path: DEBUG ? path.join(__dirname, '../build') : path.join(__dirname, '../temp_build'),
      filename: 'assets.json',
    }),
    // new webpack.optimize.OccurrenceOrderPlugin(true),
    ...(!DEBUG ? [
      // new UglifyJsParallelPlugin({
      //     workers: os.cpus().length, // usually having as many workers as cpu cores gives good results
      //     output: {
      //       comments: false,  // remove all comments
      //     },
      //     mangle:{
      //       except:['$','exports','require']
      //     },
      //     compress: {
      //       warnings: VERBOSE,
      //     }
      // }),
      // new UglifyJsPlugin({
      //   cache: false,
      //   parallel:false,
      //   uglifyOptions: { 
      //     mangle:{
      //       reserved:['$','exports','require']
      //     },
      //     compress: {
      //       warnings: VERBOSE,
      //     }
      //   }
      // }),
      new webpack.optimize.UglifyJsPlugin({
        mangle: {
          except: ['$', 'exports', 'require']
        },
        compress: {
          warnings: VERBOSE,
          drop_debugger: !DEBUG,
          drop_console: !DEBUG
        }
      }),
      // new ParallelUglifyPlugin({
      //   cacheDir: '.cache/',
      //   workerCount:os.cpus().length,
      //   uglifyJS:{
      //     output: {
      //       comments: false
      //     },
      //     compress: {
      //       warnings: VERBOSE
      //     }
      //   }
      // }),
      // new webpack.optimize.AggressiveMergingPlugin(),
    ] : []),
    ...(DEBUG ? [
      new webpack.HotModuleReplacementPlugin(),
      new webpack.NoEmitOnErrorsPlugin(),
    ] : []),
    ...(!DEBUG ? [
      new HtmlWebpackPlugin({
        "title": 'Custom template',
        "csrfToken": '<%=csrfToken%>',
        "filename": path.resolve(framePath, 'temp_build', 'index.ejs'),
        "inject": 'body',
        "template": path.resolve(framePath, 'temp_build', 'index-production.ejs')
      })
    ] : []),
    ...(!DEBUG ? [new webpack.DllReferencePlugin({
      context: '.',
      manifest: require('../temp_build/manifest.json')
    })] : [])
  ],
});

export default [appConfig];