'use strict';
const isProduction = process.env.NODE_ENV === 'production';
const webpack = require('webpack');
const merge = require('webpack-merge'); // webpack merge 工具包
const baseWebpackConfig = require('./webpack.base.conf'); // 基础配置引入
const TerserWebpackPlugin = require('terser-webpack-plugin'); // js压缩优先配置
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 提取单独打包css文件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CssCustomSourcemapUrlPlugin = require('css-custom-sourcemap-url-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const WebpackObfuscator = require('webpack-obfuscator');
const config = require('../config');
function resolve(dir) {
return path.join(__dirname, '..', dir);
}
const prodWebpackConfig = merge(baseWebpackConfig, {
mode: 'production', // 设定环境
optimization: {
// webpack4.0 新加优化策略
minimizer: [
new TerserWebpackPlugin({
parallel: true, // 开启并行压缩,充分利用cpu
extractComments: false, // 移除注释
sourceMap: !isProduction,
cache: true,
terserOptions: {
compress: {
warnings: false,
drop_debugger: true,
drop_console: isProduction,
},
output: {
comments: false, // 移除所有注释
beautify: false, // 不美化,压缩成一行
ascii_only: true, // 只输出 ASCII 字符
},
},
}),
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
map: {
inline: false,
},
autoprefixer: false,
},
}),
new CssCustomSourcemapUrlPlugin({
append: config.build.sourcePath,
}),
],
splitChunks: {
chunks: 'all',
name: 'vendors',
},
runtimeChunk: {
name: 'manifest',
},
},
plugins: [
new HtmlWebpackPlugin({
pageAnalyticScript: isProduction
? config.build.pageAnalyticScript
: config.dev.pageAnalyticScript,
pageProbeScript: isProduction
? config.build.pageProbeScript
: config.dev.pageProbeScript,
escapeScript: isProduction
? config.build.escapeScript
: config.dev.escapeScript,
inject: true,
template: 'index.html',
}),
// css 提取
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:7].css',
chunkFilename: 'css/[id].[contenthash:7].css',
sourceMap: true,
ignoreOrder: true,
}),
new webpack.SourceMapDevToolPlugin(
isProduction
? {
filename: '[file].map',
append: `\n//# sourceMappingURL=${config.build.sourcePath}[url]`,
}
: {
filename: '[file].map',
},
),
// 代码混淆插件,排除 vendor 和 manifest,仅生产环境启用
...(isProduction ? [new WebpackObfuscator(
{
rotateStringArray: true,
stringArray: true,
stringArrayEncoding: ['rc4'],
stringArrayThreshold: 1,
compact: true,
disableConsoleOutput: true,
},
['**/vendor*.js', '**/vendors~*.js', '**/manifest.*.js']
)] : []),
// new BundleAnalyzerPlugin(), // 可视化打包
],
});
module.exports = prodWebpackConfig;
这串打包逻辑中
runtimeChunk: {
name: 'manifest',
},
的作用是什么,manifest又是什么
最新发布