(点击上方公众号,可快速关注)
文/劳卜
阅读本文需要 3.1 分钟
这是劳卜的第 32 篇 原创文章
前言
当我们的前端项目完成了技术选型阶段后,接下来所要做的便是项目的构建和配置。
虽然说用脚手架能够帮助我们完成基本的目录构建和一些基础配置,但是其他很多实用的功能及特殊配置都需要自己动手实践,根据实际场景进行针对性的设置。
本文主要介绍下项目使用 Vue CLI 3.x 构建后,如何正确的配置 webpack。
webpack 配置
首先你需要知道的是,Vue CLI 3 的 vue-cli-service 集成了一份 webpack 的主流配置,可以满足基础场景的开发任务。
这一份配置你可以通过在项目根目录运行以下命令查看:
vue inspect
# 或者
vue ui # 进入对应项目后点击任务中的 inspect 任务查看
1. 基本配置
如果你不想使用 vue-cli-service 集成的 webpack 默认配置,你可以在根目录的 vue.config.js(没有需自己新建)中修改它。
比如说修改一些基础的配置项:
/* vue.config.js */
// 配置化文件
const configs = require('./config')
// 根据环境判断使用哪份配置
const isPro = process.env.NODE_ENV === 'production'
const cfg = isPro ? configs.build : configs.dev
module.exports = {
...
publicPath: cfg.BASE_URI, // 部署应用包时的基本 URL
outputDir: configs.build.outputDir, // 输出目录
assetsDir: configs.build.assetsDir, // 放置生成的静态资源目录
lintOnSave: cfg.lintOnSave, // 是否启用 eslint
productionSourceMap: configs.build.productionSourceMap, // 生产环境是否启用 sourceMap
...
}
一般情况下我们建议将配置化的东西单独存放到配置文件中进行管理,比如上述的 config 目录,然后根据不同环境引入不同配置,便于修改和查看。
2. 额外配置
除此之外,针对项目的需要,你可能还需要注入一些额外的环境变量,抑或限制下 url-loader 的大小,或者移除 prefetch 插件,设置下 alias,你可以这样配置:
module.exports = {
...
chainWebpack: config => {
// 移除 prefetch 插件
config.plugins.delete('prefetch')
// 限制 url-loader 大小
config.module
.rule('images')
.use('url-loader')
.tap(options => merge(options, {
limit: 5120,
}))
// 注入环境变量
config.plugin('define')
.tap(args => {
let name = 'process.env'
// 使用 merge 保证原始值不变
args[0][name] = merge(args[0][name], {
...cfg.env
})
return args
})
// alias 设置
config.resolve.alias
.set('_img', resolve('src/assets/images'))
// 关闭包大小告警提示
config.performance.set('hints', false)
},
...
}
除了我们可以用 chainWebpack 这一函数来对内部的 webpack 配置进行更细粒度的修改外,我们还可以使用 configureWebpack 来合并相应配置,具体可以查看官方文档 《简单的配置方式》。
3. 本地配置
另外,针对一个中后台项目,本地开发时需要用到的一些配置也是必不可少的,比如代理设置(解决本地开发跨域问题),我们可以使用 devServer 来解决:
const proxyTarget = 'http://x.xxx.xxx.com' // 本地 proxy
module.exports = {
...
devServer: {
open: true, // 是否自动打开浏览器页面
host: configs.dev.host, // 指定使用一个 host。默认是 localhost
port: configs.dev.port, // 端口地址
https: false, // 使用https提供服务
progress: true,
// string | Object 代理设置
proxy: {
'/LOCAL_URL': {
target: proxyTarget,
changeOrigin: true,
pathRewrite: {
'^/LOCAL_URL': ''
}
}
},
}
...
}
上方我们除了配置了本地启动的 host 和 端口外,还进行了 proxy 的配置。
当我们的接口匹配到 /LOCAL_URL(在接口封装篇会讲解) 字段时,就会将请求服务转发到其 target 配置下,同时重写路由地址,将假地址前缀删除,实现接口的转发。
4. 特殊配置
最后,在实现了基本配置、额外配置、本地配置后,我们再来看下特殊配置。
特殊配置也就是在特殊场景下进行特殊处理的配置,比如我在架构这一中后台项目时,一套代码会运行在不同站点上(也就是发布到不同服务器上),不同站点有些配置也是不一样的,比如权限、页面展示、接口调用地址等都可能不尽相同。
那么如何在发布前不手动去修改对应站点的配置,而是以一种自动化的方式来解决呢?我们可以跑不同的 npm 命令来实现:
/* package.json */
{
"scripts": {
"local": "vue-cli-service serve",
"a_dev_build": "vue-cli-service build --site a --env development",
"b_dev_build": "vue-cli-service build --site b --env development",
"a_build": "vue-cli-service build --site a --env production",
"b_build": "vue-cli-service build --site b --env production",
}
}
比如说,当我们要发布 a 站点到预发环境时,我们只需要在发布前(可以交给发布系统运行)运行 npm run a_dev_build 命令,然后 vue.config.js 中去读取相应配置,注入全局环境变量即可:
const site = process.argv.slice(4, 5)[0] || 'a' // 当前运行站点
const env = process.argv.slice(6, 7)[0] || 'development' // 当前运行前端环境
const local = process.env.npm_lifecycle_event === 'local' ? 'on' : 'off' // 是否调用本地接口
module.exports = {
...
chainWebpack: config => {
// 注入环境变量
config.plugin('define')
.tap(args => {
let name = 'process.env'
// 使用 merge 保证原始值不变
args[0][name] = merge(args[0][name], {
SITE: JSON.stringify(site),
LOCAL: JSON.stringify(local),
CLIENT_ENV: JSON.stringify(env)
})
return args
})
}
...
}
然后在前端环境中再去根据不同的站点、不同的环境运行不同的代码(包括接口、界面显示等)即可。
当然你也可以换其他方式实现相同的功能,比如使用 cross-env 或者 mode 这样的工具或参数。
结语
本文结合实际情况针对 webpack 进行了不同程度的配置展示,当然除此之外还有很多配置项和配置方法没有一一展示,比如开启 Gzip 压缩、使用包分析工具等。
大家需要在此基础上学会举一反三,才能灵活的架构一个中后台项目的 webpack 配置。
那么下篇文章我会给大家带来《如何架构一个中后台项目的前端部分(接口配置篇)》
热门阅读: