const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);
// js丑化
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const webpack = require("webpack");
// gzip压缩
const CompressionWebpackPlugin = require('compression-webpack-plugin');
// css添加版本号
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const productionGzipExtensions = ['js', 'css']
// glob检测所有的css
const glob = require('glob');
// 去除冗余的css
const PurifyCssWebpack = require('purifycss-webpack');
// 打包时把一些静态文件一起打包
const CopyWebpackPlugin = require('copy-webpack-plugin');
function resolve(dir) {
return path.join(__dirname, dir)
}
// 以时间戳作为版本号
function timestampToTime() {
var date = new Date();//时间戳为10位需*1000,时间戳为13位的话不需乘1000
var Y = date.getFullYear();
var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours());
var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes());
var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
strDate = Y + '' + M + '' + D + '' + h + '' + m + '' + s;
return strDate;
}
const cdn = {
css: [],
js: [
'https://cdn.staticfile.org/vue/2.6.10/vue.min.js',
'https://cdn.staticfile.org/vue-router/3.1.3/vue-router.min.js',
'https://cdn.staticfile.org/vuex/3.1.2/vuex.min.js',
'https://cdn.staticfile.org/axios/0.19.0/axios.min.js',
'https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js',
'https://cdn.staticfile.org/qs/6.9.1/qs.min.js',
]
}
module.exports = {
publicPath: '/',
// 设置代理
devServer: {
open: true,
port: '9000'
},
pwa: {
iconPaths: {
favicon32: 'favicon1.ico',
favicon16: 'favicon1.ico',
appleTouchIcon: 'favicon1.ico',
maskIcon: 'favicon1.ico',
msTileImage: 'favicon1.ico'
}
},
//生产环境构建文件的目录
outputDir: "dist",
// 静态文件构建的目录
assetsDir: 'assets',
//生产环境是否生成SourceMap
productionSourceMap: true,
// 是否使用包含运行时编译器的 Vue 构建版本
runtimeCompiler: true,
// 默认值为require('os').cpus().length > 1 在系统的 CPU 有多于一个内核时自动启用
parallel: require('os').cpus().length > 1,
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: IS_PROD ? true : false,
// 开启 CSS source maps?
sourceMap: IS_PROD ? false : true,
loaderOptions: {
postcss: {
plugins: [
require('postcss-pxtorem')({ // 把px单位换算成rem单位
rootValue: 37.5, // 换算的基数(设计图750的为75)
selectorBlackList: [], // 忽略转换正则匹配项
propList: ['*']
})
]
}
}
},
transpileDependencies: [
'async', 'qs', 'vue-lazyload', 'vue-3d-picker', 'mint-ui'
],
configureWebpack: config => {
//生产环境去掉console 和 debugger
//压缩代码减少文件体积
if (IS_PROD) {
// 配置不打包的插件 key是require的名字 value是库暴露出来的方法
config.externals = {
"vue": "Vue",
"vue-router": "VueRouter",
"vuex": "Vuex",
"axios": "axios",
"qs": "Qs",
"jquery": "jQuery",
}
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console: true,
drop_debugger: true,//移除debugger
pure_funcs: ['console.log', 'console.table']//移除console
}
},
sourceMap: false,
})
);
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' + productionGzipExtensions.join('|') + ')$'
),
threshold: 10240,
minRatio: 0.8
})
);
config.plugins.push(
new MiniCssExtractPlugin({
// 修改打包后css文件名
filename: `assets/css/[name].${timestampToTime()}.css`,
chunkFilename: `assets/css/[name].${timestampToTime()}.css`
})
);
// 公共代码抽离
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'common',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 60
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
// 将部分静态文件一起打包
config.plugins.push(
new CopyWebpackPlugin([
{
from: path.join(__dirname, "./static/MP_verify_0ZWw0QASKR3fdW8L.txt"),
to: path.join(__dirname, "./dist/MP_verify_0ZWw0QASKR3fdW8L.txt")
},
{
from: path.join(__dirname, "./static/apple-app-site-association"),
to: path.join(__dirname, "./dist")
},
])
)
}
config.plugins.push(
new webpack.ProvidePlugin({
jQuery: "jquery",
$: "jquery"
})
)
},
chainWebpack: config => {
// 修复HMR
config.resolve.symlinks(true)
//配置别名
config.resolve.alias
.set("@", resolve('src')) // key,value自行定义,比如.set('@@', resolve('src/components'))
if (IS_PROD) {
// 生产环境配置
// 图片增加版本号
config.module
.rule("images")
.use("url-loader")
.tap(options => {
options.name = `img/[name].${timestampToTime()}.[ext]`;
options.fallback = {
loader: "file-loader",
options: {
name: `img/[name].${timestampToTime()}.[ext]`
}
};
return options;
});
// js增加版本号
config.output.filename('assets/js/[name]' + timestampToTime() + '.js').end();
config.output.chunkFilename('assets/js/[name]' + timestampToTime() + '.js').end();
// 不打包的插件,需要把值传到htmlWebpackPlugin
config.plugin("html").tap(options => {
options[0].cdn = cdn;
return options;
})
} else {
//开发环境配置
}
}
}
网友评论