Javascript Webpack多阶段生产构建
我正在开发React/Redux SPA前端,我想用Webpack2构建和部署系统。它应该有什么: 1.JS代码拆分(供应商+我的自定义)、缩小、gzip、唯一散列、在index.html中链接、通过ssh部署到服务器。 2.CSS提取,合并成一个文件(供应商区块也有一些),缩小,压缩,散列,上传。非常直截了当 难点在于用html链接非标准gzip版本。 我在HTMLWebpack插件中设置了用于模板制作的pug,但它不接受除.js.css扩展之外的任何链接。这使我添加了addassethtmlwebpack插件,但这需要静态命名(因此我将哈希移到了这个阶段),并且在运行时要求该文件存在,即使它是插件数组中的最后一个文件(?)。这将导致一个单独的构建。问题是在第二阶段-如果我只是想用插件处理这些文件,而不是再次参与整个构建过程,该怎么办?它从入口点抓取我的index.js并再次开始咀嚼它,而我只想呈现一个模板和自定义链接。不管怎么说,我对这个疯狂和困惑的网页是陌生的。。。以下是我的设置:Javascript Webpack多阶段生产构建,javascript,reactjs,webpack,babeljs,Javascript,Reactjs,Webpack,Babeljs,我正在开发React/Redux SPA前端,我想用Webpack2构建和部署系统。它应该有什么: 1.JS代码拆分(供应商+我的自定义)、缩小、gzip、唯一散列、在index.html中链接、通过ssh部署到服务器。 2.CSS提取,合并成一个文件(供应商区块也有一些),缩小,压缩,散列,上传。非常直截了当 难点在于用html链接非标准gzip版本。 我在HTMLWebpack插件中设置了用于模板制作的pug,但它不接受除.js.css扩展之外的任何链接。这使我添加了addassethtml
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;
以及我随后援引的第1部分:
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'
}
};