我正在开发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'
}
};