webpack.config.production.js 10.2 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';

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 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
};
 
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: '/',
    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') : path.join(__dirname, '../temp_build/public'),
    publicPath: '/',
    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];