vue.config.js 基础概述
vue.config.js 是 Vue CLI 项目中的可选配置文件,用于自定义项目的构建配置。该文件位于项目根目录,采用 CommonJS 模块语法导出一个配置对象。当该文件存在时,Vue CLI 会自动加载并应用其中的配置。
常用配置项详解
publicPath
定义应用部署的基础路径。默认值为 '/',即假设应用部署在域名的根路径下。如果应用部署在子路径(如 /my-app/),需设置为 '/my-app/'。
示例:
javascript
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/production-sub-path/' : '/'
}
outputDir
指定构建输出目录(默认 dist)。构建时目录会被清除(除非配置了 noClean 为 true)。
示例:
javascript
module.exports = {
outputDir: 'dist',
assetsDir: 'static',
filenameHashing: true
}
assetsDir
指定放置生成的静态资源的目录(相对于 outputDir)。默认 ''。
indexPath
指定生成的 index.html 的输出路径(相对于 outputDir)。默认 'index.html'。
filenameHashing
是否使用包含 hash 的文件名(用于缓存控制)。默认 true。
pages
配置多页面应用。默认 undefined。
示例:
javascript
module.exports = {
pages: {
index: {
entry: 'src/index/main.js',
template: 'public/index.html',
filename: 'index.html',
chunks: ['chunk-vendors', 'chunk-common', 'index']
},
admin: {
entry: 'src/admin/main.js',
template: 'public/admin.html',
filename: 'admin.html',
chunks: ['chunk-vendors', 'chunk-common', 'admin']
}
}
}
lintOnSave
是否在开发环境下通过 eslint-loader 在每次保存时 lint 代码。默认 true。
runtimeCompiler
是否使用包含运行时编译器的 Vue 构建版本。默认 false。
transpileDependencies
默认情况下 babel-loader 会忽略 node_modules 中的文件。如需显式转译依赖,可在此列出。
示例:
javascript
module.exports = {
transpileDependencies: ['vuex-persist']
}
productionSourceMap
是否生成生产环境的 source map。默认 true。
crossorigin
配置生成的 HTML 中 <link rel="stylesheet"> 和 <script> 的 crossorigin 属性。默认 undefined。
integrity
在生成的 HTML 中启用 Subresource Integrity (SRI)。默认 false。
链式配置 (chainWebpack)
提供更细粒度的 webpack 配置修改能力,使用 webpack-chain 语法。
示例:
javascript
module.exports = {
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.tap(options => {
options.compilerOptions = {
isCustomElement: tag => tag.startsWith('my-')
}
return options
})
}
}
配置 webpack (configureWebpack)
简单合并到最终 webpack 配置的对象或函数。
对象形式示例:
javascript
module.exports = {
configureWebpack: {
plugins: [
new MyAwesomeWebpackPlugin()
]
}
}
函数形式示例:
javascript
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 生产环境配置
} else {
// 开发环境配置
}
}
}
CSS 相关配置
css.requireModuleExtension
默认情况下,只有 *.module.[ext] 文件会被视为 CSS Modules 模块。设置为 false 后可以去掉文件名中的 .module 并将所有 *.(css|scss|sass|less|styl(us)?) 文件视为 CSS Modules 模块。默认 true。
css.extract
是否将组件中的 CSS 提取至一个独立的 CSS 文件中(而不是动态注入到 JavaScript 中的 inline 代码)。生产环境下默认 true,开发环境下默认 false。
css.sourceMap
是否为 CSS 开启 source map。默认 false。
css.loaderOptions
向 CSS 相关的 loader 传递选项。
示例:
javascript
module.exports = {
css: {
loaderOptions: {
css: {
modules: {
localIdentName: '[name]_[local]_[hash:base64:5]'
}
},
sass: {
prependData: `@import "@/styles/variables.scss";`
}
}
}
}
devServer 开发服务器配置
devServer.port
指定开发服务器端口。默认 8080。
devServer.proxy
配置代理规则,解决跨域问题。
示例:
javascript
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
}
devServer.hot
启用 webpack 的模块热替换特性。默认 true。
devServer.open
服务器启动后自动打开浏览器。默认 false。
devServer.overlay
当出现编译错误或警告时,在浏览器全屏显示。默认 false。
其他高级配置
parallel
是否为 Babel 或 TypeScript 使用 thread-loader。默认 require('os').cpus().length > 1。
pwa
PWA 插件配置。
示例:
javascript
module.exports = {
pwa: {
name: 'My App',
themeColor: '#4DBA87',
msTileColor: '#000000',
appleMobileWebAppCapable: 'yes',
appleMobileWebAppStatusBarStyle: 'black',
workboxPluginMode: 'GenerateSW'
}
}
pluginOptions
传递参数给插件。
示例:
javascript
module.exports = {
pluginOptions: {
electronBuilder: {
nodeIntegration: true,
builderOptions: {
win: {
icon: 'build/icons/icon.ico'
}
}
}
}
}
配置合并策略
当需要扩展或修改内部 webpack 配置时,可通过 chainWebpack 或 configureWebpack 实现。chainWebpack 提供更细粒度的控制,而 configureWebpack 更简单直观。
性能优化配置
configureWebpack 优化示例
javascript
module.exports = {
configureWebpack: {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]
return `npm.${packageName.replace('@', '')}`
}
}
}
}
}
}
}
使用 DllPlugin 提升构建速度
虽然 Vue CLI 3+ 不再内置 DllPlugin,但可通过配置实现:
- 创建 webpack.dll.config.js
- 在 vue.config.js 中引用生成的 manifest 文件
多环境配置
可通过环境变量实现多环境配置:
javascript
module.exports = {
publicPath: process.env.VUE_APP_BASE_URL,
devServer: {
proxy: process.env.VUE_APP_API_PROXY
}
}
然后在项目根目录创建:
- .env.development
- .env.production
- .env.staging
自定义 loader 和 plugin
通过 chainWebpack 添加自定义 loader:
javascript
module.exports = {
chainWebpack: config => {
config.module
.rule('yaml')
.test(/\.ya?ml$/)
.use('yaml-loader')
.loader('yaml-loader')
.end()
}
}
添加自定义 plugin:
javascript
const MyPlugin = require('./my-plugin')
module.exports = {
configureWebpack: {
plugins: [
new MyPlugin()
]
}
}
完整配置示例
javascript
const path = require('path')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/production-path/' : '/',
outputDir: 'dist',
assetsDir: 'static',
indexPath: 'index.html',
filenameHashing: true,
lintOnSave: process.env.NODE_ENV !== 'production',
runtimeCompiler: false,
transpileDependencies: [],
productionSourceMap: false,
crossorigin: undefined,
integrity: false,
css: {
extract: true,
sourceMap: false,
loaderOptions: {
sass: {
prependData: `@import "@/styles/variables.scss";`
}
}
},
devServer: {
port: 8080,
open: true,
overlay: {
warnings: true,
errors: true
},
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true
}
}
},
chainWebpack: config => {
config.module
.rule('svg')
.exclude.add(path.resolve(__dirname, 'src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(path.resolve(__dirname, 'src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
},
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: 'bundle-report.html',
openAnalyzer: false
})
)
}
},
pluginOptions: {
i18n: {
locale: 'en',
fallbackLocale: 'en',
localeDir: 'locales',
enableInSFC: true
}
},
pwa: {
name: 'My App',
themeColor: '#4DBA87',
workboxPluginMode: 'GenerateSW',
workboxOptions: {
skipWaiting: true
}
}
}
注意事项
- 修改 vue.config.js 后需要重启开发服务器
- 某些配置可能在特定环境下不生效
- 优先使用 Vue CLI 提供的配置项,必要时再使用底层 webpack 配置
- 生产环境和开发环境配置可能有不同行为
- 可通过 vue inspect 命令查看最终 webpack 配置
调试配置
使用 Vue CLI 提供的 inspect 命令可以检查最终生成的 webpack 配置:
bash
vue inspect > output.js
或者查看特定规则:
bash
vue inspect module.rules
常见问题解决方案
解决跨域问题
通过 devServer.proxy 配置代理:
javascript
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://backend-server:3000',
changeOrigin: true,
secure: false
}
}
}
}
配置路径别名
javascript
const path = require('path')
module.exports = {
configureWebpack: {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
'components': path.resolve(__dirname, 'src/components')
}
}
}
}
打包优化
- 使用 CDN 加载外部资源
- 配置 SplitChunks 分割代码
- 启用 gzip 压缩
- 使用 DllPlugin 预编译依赖
支持旧版浏览器
通过 browserslist 配置和 transpileDependencies 选项:
javascript
module.exports = {
transpileDependencies: [
'vuex-persist',
'element-ui'
]
}
并在 package.json 中配置:
json
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}