Webpack多阶段生产构建

时间:2017-05-30 22:22:46

标签: javascript reactjs webpack babeljs

我正在开发React / Redux SPA前端,我想用Webpack2制作构建和部署系统。应该有什么: 1. JS代码拆分(供应商+我的自定义),缩小,gzip,唯一散列,index.html链接,通过ssh部署到服务器。 2. CSS提取,合并为1个文件(供应商块也有一些),缩小,gzipping,散列,上传。很直接。

难点在于链接html中的非标准gzip压缩版本。 我在html-webpack-plugin中设置了用于模板化的pug,但除了.js .css扩展链接之外,它不接受任何其他内容。这让我添加了add-asset-html-webpack-plugin,但这需要静态命名(所以我将散列移到了这个阶段)并且在运行时它需要这个文件存在,即使它是插件数组中的最后一个(?)。这导致了单独的构建。问题出在第二阶段 - 如果我只是想用插件处理这些文件,而不是再次参与整个构建过程呢?它从入口点抓取我的index.js并再次开始咀嚼它,而我只是想渲染一个模板和海关链接。无论如何,我对这个Webpack的疯狂感到困惑并且感到困惑......这就是我的设置:

var path = require('path');
var webpack = require ('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var MergeFilesPlugin = require('merge-files-webpack-plugin');
var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
var cssProcessor = require('cssnano');
var CompressionPlugin = require('compression-webpack-plugin');

const VENDOR_LIBS = [ ... ];

const config = {
entry: {
app: [ 'babel-polyfill', './app/index.js' ],
vendor: VENDOR_LIBS
},

output: {
path: path.resolve(__dirname, 'build'),
publicPath: 'build/',
filename: '[name].js',
},

plugins: [

new webpack.DefinePlugin({
  'process.env': {
    'NODE_ENV': JSON.stringify('production')
  }
}),

new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: Infinity,
    filename: '[name].js',
  }),

  new ExtractTextPlugin('[name].css'),

  new MergeFilesPlugin({
         filename: 'style.css',
         test: /\.css$/,
         deleteSourceFiles: true
     }),

     new OptimizeCssAssetsPlugin({
       assetNameRegExp: /\.css$/g,
       cssProcessor: cssProcessor,
       cssProcessorOptions: { discardComments: {removeAll: true} },
       safe: true,
       canPrint: true
     }),

new webpack.optimize.UglifyJsPlugin({
  sourceMap: false,
  compressor: {
    warnings: false
  }
}),

new CompressionPlugin({
  asset: 'gzip/[path].gz[query]',
  algorithm: 'gzip',
  test: /\.js$|\.css$/,
  threshold: 0,
  minRatio: 0.8

 })

],
module: {
rules: [
  {
    use: [{
      loader: 'babel-loader',
      options: { presets: ['react', 'es2015', 'stage-1'] },
    }],
    test: /\.js$/,
    exclude: /node_modules/
  },
  {
    test: /\.json$/,
    use: 'json-loader'
  },
  {
    test: /\.(png|jpe?g|gif|svg)$/,
    use: [
      {
        loader: 'file-loader?name=[path][name].[ext]',
        options: { limit: 40000 /*, outputPath: 'images/'*/ }
      },
      'image-webpack-loader'
        ]
  },
  {
    test: /\.css$/,
     use: ExtractTextPlugin.extract({
       fallback: 'style-loader',
       use: [
        'css-loader?modules&localIdentName=[path][name]_[local]--[hash:base64:8]',
         {
           loader: 'postcss-loader',
           options: {
             importLoaders: 1
           }
         }

       ]
     })

  }
]
},
resolve: {
extensions: ['*', '.js', '.jsx', '.json']
},
devtool: false,
devServer: {

historyApiFallback: true,
contentBase: './app'
}
};

module.exports = config;

注射部分I之后调用:

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');

const config = {
entry: './app/index.js',
output: {
path: path.resolve(__dirname, 'build'),
publicPath: 'build/',
filename: 'index.js',
},

plugins: [
new HtmlWebpackPlugin({
  template: 'app/index.pug',
  inject: false
}),

new AddAssetHtmlPlugin({
filepath: 'build/gzip/vendor.js.gz',
includeSourcemap: false,
hash: true
})

],
module: {
 rules: [
  {
    use: [{
      loader: 'babel-loader',
      options: { presets: ['react', 'es2015', 'stage-1'] },
    }],
    test: /\.js$/,
    exclude: /node_modules/
  },
  {
    test: /\.pug$/,
    loader: 'pug-loader'
  },
  {
    test: /\.(png|jpe?g|gif|svg)$/,
    use: [
      {
        loader: 'file-loader?name=[path][name].[ext]',
        options: { limit: 40000 /*, outputPath: 'images/'*/ }
      },
      'image-webpack-loader'
        ]
   }
  ]
},
resolve: {
extensions: ['*', '.js', '.jsx', '.json']
},
devtool: false,
devServer: {

historyApiFallback: true,
contentBase: './app'
}
};

0 个答案:

没有答案