调整 webpack 配置就是在 vue.config.js 中去设置,这个文件主要用于打包文件时候的一些配置。在根目录创建一个vue.config.js文件后就开启学习之旅
1. 查看默认的webpack配置
因为 @vue/cli-service 对 webpack 配置进行了抽象,所以理解配置中包含的东西会比较困难,vue-cli-service 暴露了 inspect 命令用于审查解析好的 webpack 配置.在控制台输入下面命令会得到相因的配置
vue inspect > output.js
//注意它输出的并不是一个有效的 webpack 配置文件,而是一个用于审查的被序列化的格式
//得到的是一个output.js文件
vue inspect module.rules.0
//只审查第一条规则
vue inspect --rule vue
vue inspect --plugin html
//指向一个规则或插件的名字:
vue inspect --rules
vue inspect --plugins
//列出所有规则和插件的名字:
2.基本的配置参数
module.exports ={
productionSourceMap: false,
publicPath: './',
outputDir: 'dist',
assetsDir: 'assets',
devServer: { port: 8090, host: '0.0.0.0', https: false, open: true },
// 其他配置 ...
-
productionSourceMap:生产环境是否要生成
sourceMap -
publicPath:部署应用包时的基本 URL,用法和
webpack本身的output.publicPath一致- 可以通过三元运算去配置
dev和prod环境,publicPath: process.env.NODE_ENV === 'production' ? '/prod/' : './'
- 可以通过三元运算去配置
-
outputDir:
build时输出的文件目录 -
assetsDir: 放置静态文件夹目录
-
devServer: dev环境下,
webpack-dev-server相关配置- port: 开发运行时的端口
- host: 开发运行时域名,设置成
'0.0.0.0',在同一个局域网下,如果你的项目在运行,同时可以通过你的http://ip:port/...访问你的项目 - https: 是否启用
https - open:
npm run serve时是否直接打开浏览器
3.配置方法一:简单的配置方式(configureWebpack)
在 vue.config.js 中的 configureWebpack 选项里写一个对象:该对象将会被 webpack-merge 合并入最终的 webpack 配置。
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
new MyAwesomeWebpackPlugin()
]
}
}
想要切换环境,或者想要直接修改配置,那就换成一个函数 (该函数会在环境变量被设置之后懒执行)。该方法的第一个参数会收到已经解析好的配置。在函数内,你可以直接修改配置,或者返回一个将会被合并的对象:
// vue.config.js
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...
} else {
// 为开发环境修改配置...
}
}
}
4. 配置方法二:链式操作 (高级)
Vue CLI 内部的 webpack 配置是通过 webpack-chain 维护的。这个库提供了一个 webpack 原始配置的上层抽象,使其可以定义具名的 loader 规则和具名插件,并有机会在后期进入这些规则并对它们的选项进行修改。它允许我们更细粒度的控制其内部配置。
-
loader
(1)基本使用方法:
config.module
.rule(name)
.use(name)
.loader(loader)
.options(options)
(2)修改 Loader 选项(直接修改options)
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
// 修改它的选项...
return options
})
}
}
(4)替换一个规则里的 Loader
如果你想要替换一个已有的基础 loader,例如为内联的 SVG 文件使用 vue-svg-loader 而不是加
// vue.config.js
module.exports = {
chainWebpack: config => {
const svgRule = config.module.rule('svg')
// 清除已有的所有 loader。
// 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。
svgRule.uses.clear()
// 添加要替换的 loader
svgRule
.use('vue-svg-loader')
.loader('vue-svg-loader')
}
}
(5)添加一个新的 Loader
// vue.config.js
module.exports = {
chainWebpack: config => {
// GraphQL Loader
config.module
.rule('graphql')
.test(/.graphql$/)
.use('graphql-tag/loader')
.loader('graphql-tag/loader')
.end()
// 你还可以再添加一个 loader
.use('other-loader')
.loader('other-loader')
.end()
}
}
-
plugin
(1)基本使用情况
config
.plugin(name)
.use(WebpackPlugin, args)
(2)新增hot-hash-webpack-plugin
const HotHashWebpackPlugin = require('hot-hash-webpack-plugin');
module.exports = {
chainWebpack: (config) => {
// 新增一个`hot-hash-webpack-plugin`
// 注意:这里use的时候不需要使用`new HotHashWebpackPlugin()`
config.plugin('hotHash')
.use(HotHashWebpackPlugin, [{ version: '1.0.0' }]);
}
}
(3)删除console和debugger
const HotHashWebpackPlugin = require('hot-hash-webpack-plugin');
module.exports = {
chainWebpack: (config) => {
// 修改打包时css抽离后的filename及抽离所属目录
config.plugin('extract-css')
.tap(args => [{
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].css'
}]);
// 正式环境下,删除console和debugger
config.optimization
.minimize(true)
.minimizer('terser')
.tap(args => {
let { terserOptions } = args[0];
terserOptions.compress.drop_console = true;
terserOptions.compress.drop_debugger = true;
return args
});
}
}
config.plugins.delete(name)//对于一些`webpack`默认的 `plugin` ,如果不需要可以进行删除
(4)用tap修改插件选项
config
.plugin(name)
.tap(args => newArgs)
5.一些常见的配置
- 定义全局全局变量,
DefinePlugin是webpack已经默认配置的,我们可以对参数进行修改
config.plugin('define').tap(args => [{
...args,
"window.isDefine": JSON.stringify(true),
}]);
- 自定义filename
config.output.filename('./js/[name].[chunkhash:8].js');//自定义打包后js文件的路径及文件名字
- 设置别名alias
config.resolve.alias
.set('@', resolve('src'))
.set('api', resolve('src/apis'))
.set('common', resolve('src/common'))
//一份大佬的vue.config.js的配置
const path = require('path');
const HotHashWebpackPlugin = require('hot-hash-webpack-plugin');
const WebpackBar = require('webpackbar');
const resolve = (dir) => path.join(__dirname, '.', dir);
module.exports = {
productionSourceMap: false,
publicPath: './',
outputDir: 'dist',
assetsDir: 'assets',
devServer: {
port: 9999,
host: '0.0.0.0',
https: false,
open: true
},
chainWebpack: (config) => {
const types = ['vue-modules', 'vue', 'normal-modules', 'normal'];
types.forEach(type => {
let rule = config.module.rule('less').oneOf(type)
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [path.resolve(__dirname, './lessVariates.less')]
});
});
config.resolve.alias
.set('@', resolve('src'))
.set('api', resolve('src/apis'))
.set('common', resolve('src/common'))
config.module.rule('images').use('url-loader')
.tap(options => ({
name: './assets/images/[name].[ext]',
quality: 85,
limit: 0,
esModule: false,
}));
config.module.rule('svg')
.test(/\.svg$/)
.include.add(resolve('src/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader');
config.plugin('define').tap(args => [{
...args,
"window.isDefine": JSON.stringify(true)
}]);
// 生产环境配置
if (process.env.NODE_ENV === 'production') {
config.output.filename('./js/[name].[chunkhash:8].js');
config.output.chunkFilename('./js/[name].[chunkhash:8].js');
config.plugin('extract-css').tap(args => [{
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].css'
}]);
config.plugin('hotHash').use(HotHashWebpackPlugin, [{ version : '1.0.0'}]);
config.plugin('webpackBar').use(WebpackBar);
config.optimization.minimize(true)
.minimizer('terser')
.tap(args => {
let { terserOptions } = args[0];
terserOptions.compress.drop_console = true;
terserOptions.compress.drop_debugger = true;
return args
});
config.optimization.splitChunks({
cacheGroups: {
common: {
name: 'common',
chunks: 'all',
minSize: 1,
minChunks: 2,
priority: 1
},
vendor: {
name: 'chunk-libs',
chunks: 'all',
test: /[\\/]node_modules[\\/]/,
priority: 10
}
}
});
}
}
};