Appearance
vue.config.js 是vue-cli的配置文件
工具插件
- copy-webpack-plugin:复制文件 地址
- eslint-webpack-plugin:eslint检查 地址
- webpack-bundle-analyzer:打包分析工具 地址
- stylelint-webpack-plugin:stylelint检查 地址
- webpackbar:打包进度条 地址
- webpack-theme-color-replacer:主题色替换 地址
- clean-webpack-plugin:清除打包的输出文件夹 地址
压缩插件
- compression-webpack-plugin:压缩文件生成gzip 地址
- css-minimizer-webpack-plugin:css压缩 地址
- optimize-css-assets-webpack-plugin':压缩css,会去除重复的类名样式 地址
- html-minimizer-webpack-plugin:html压缩 地址
- image-minimizer-webpack-plugin:图片压缩 地址
- json-minimizer-webpack-plugin:json压缩 地址
- terser-webpack-plugin:js压缩 地址
- mini-css-extract-plugin:CSS 提取到单独的文件中,为每个包含 CSS 的 JS 文件创建一个 CSS 文件,并且支持 CSS 和 SourceMaps 的按需加载。地址
基本配置
js
module.exports={
productionSourceMap: false, //关闭生产环境的sourceMap
publicPath: './', //设置项目的根路径
outputDir: 'dist', //设置打包后的文件夹名称
assetsDir: 'assets', //设置静态资源文件夹名称
devServer:{ //开发服务器配置
open: true, //自动打开浏览器
port: 8080, //设置端口号
https: false, //设置是否使用https协议
host: 'localhost', //设置主机名
disableHostCheck: true, //关闭主机检查
publicPath: '/', //设置服务器的根路径
proxy: { //设置代理
'/api': {
target: 'http://localhost:3000', //设置代理目标
changeOrigin: true, //开启跨域
pathRewrite: { //路径重写
'^/api': '' //将/api重写为空
}
}
}
},
css: { //css配置
requireModuleExtension: true, //启用css modules
extract: true, //是否提取CSS到单独的文件中
sourceMap: false, //是否生成sourceMap
loaderOptions: { //css预处理器配置
// 设置 scss 公用变量文件
sass: {
prependData: '@import \'~@/assets/style/public.scss\';',
},
},
},
}webpack配置
- configureWebpack 配置
- 可以为
对象或者函数
js
module.exports={
//对象配置
configureWebpack : {
externals:{}, //配置外部扩展
rules:[], //配置规则
plugins:[], //配置插件
resolve: {
alias: {
'@': path.resolve(__dirname, 'src') //配置别名
}
}, //配置解析器
},
//链式操作 (高级)
chainWebpack: config => {
//rules的新增
config.module.rule(name).use(name).loader(loader).options(options)
//rules的修改 tap 传入一个函数
config.module.rule(name).use(name).tap(options => newOptions)
//plugins的新增 不需要new plugin
config.plugin(name).use(plugin, args)
//plugin 的修改
config.plugin(name).tap(args => newArgs)
//plugin 删除
config.plugins.delete(name)
//删除插件 prefetch 和 preload 降低带宽压力
config.plugins.delete('prefetch').delete('preload')
//配置别名
config.resolve.alias.set('@', path.resolve(__dirname, 'src'))
//修改入口
config.entryPoints.clear(); // 清空默认入口
config.entry('test').add(getPath('./test/main.ts')); // 重新设置
//定义全局全局变量
config.plugin('define').tap(args => {
return [...args,{
"window.isDefine": JSON.stringify(true),
}]
})
//修改html插件
config.plugin('html').tap(args => {
return [...args,{
title: 'new title'
}]
})
config.optimization.runtimeChunk('single')
//script脚本切分
config.optimization.splitChunks({
chunks: 'all', //async异步代码分割 initial同步代码分割 all同步异步分割都开启
minSize: 30000, //字节 引入的文件大于30kb才进行分割
minChunks: 1, //模块至少使用次数
maxAsyncRequests: 5, //同时加载的模块数量最多是5个
maxInitialRequests: 3, //入口文件做代码分割最多能分成3个js文件
automaticNameDelimiter: '~', //文件生成时连接符
name: true, //打包后的名称,默认是chunk的名字通过分隔符(默认是~)分隔
cacheGroups: { //缓存组,将所有加载模块放在缓存里面一起分割
libs: { //自定义打包的chunk名
name: 'chunk-libs', //自定义打包后的文件名
test: /[\\/]node_modules[\\/]/, //正则规则验证,如果符合就提取 chunk
priority: 10, //优先级
chunks: 'initial' //initial表示提取入口文件的公共css及js部分
},
commons: {
name: 'chunk-commons',
test: path.join(__dirname, 'src/components'),
minChunks: 3, // 最小公用次数
priority: 5, // 优先级
reuseExistingChunk: true, // 公共模块必开启
},
}
})
}
}参考配置
js
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const webpackBar = require('webpackbar');
const ThemeColorReplacer = require('webpack-theme-color-replacer')
const forElementUI = require('webpack-theme-color-replacer/forElementUI')
const optimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
const resolve = (dir) => require('path').join(__dirname, dir)
module.exports={
publicPath:'./',
outputDir:'dist',
assetsDir:'static',
lintOnSave: false,
productionSourceMap: false,
devServer:{
open:true,
disableHostCheck: true,
publicPath: '/',
},
css: {
loaderOptions: {
sass: {
prependData: '@import \'~@/assets/style/public.scss\';',
},
},
},
configureWebpack:{
plugins:[
new webpackBar(),
new CleanWebpackPlugin(),
new optimizeCssAssetsWebpackPlugin(),
],
},
chainWebpack: (config) => {
config.module.rule('md').test(/\.md$/).use('text-loader').loader('text-loader').end()
config.module.rule('images').test(/\.(png|jpe?g|gif|webp|svg)(\?.*)?$/).exclude.add(resolve('src/assets/')).end()
config.plugins.delete('prefetch').delete('preload')
config.resolve.symlinks(true)
config.resolve.alias.set('@api', resolve('src/api'))
config.resolve.alias.set('@', resolve('src'))
config.resolve.alias.set('@assets', resolve('src/assets'))
config.optimization.minimize(true)
config.plugin('theme-color-replacer').use(ThemeColorReplacer, [
{
fileName: 'css/theme-colors.[contenthash:8].css',
matchColors: [
...forElementUI.getElementUISeries('#409EFF'),
],
externalCssFiles: ['./node_modules/element-ui/lib/theme-chalk/index.css'],
changeSelector: forElementUI.changeSelector,
},
])
config.optimization.splitChunks({
chunks: 'all',
cacheGroups:{
vue: {
name: 'chunk-vue',
test: /[\\/]node_modules[\\/](vue|vuex|vue-router|vue-i18n|vue-class-component|vue-property-decorator|vue-meta)(.*)/,
priority: 99, // 优先级
reuseExistingChunk: true,
},
lodash: {
name: 'chunk-lodash',
test: /[\\/]node_modules[\\/](lodash)(.*)/,
priority: 98,
reuseExistingChunk: true,
},
elementUI: {
name: 'chunk-elementUI',
priority: 97,
test: /[\\/]node_modules[\\/]_?element-ui(.*)/,
},
components: {
name: 'chunk-components',
test: resolve('src/components'),
priority: 96,
reuseExistingChunk: true,
enforce: true,
},
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 1,
chunks: 'initial',
},
},
}).runtimeChunk('single')
}
}