## build
在vue项目build有两个需求:
- 动态指定环境变量配置(dev、test、production环境打包时对应特定的环境变量配置)
- 减少项目build后的体积和加快项目build速度
#### 动态指定环境变量配置
你可以通过在根目录下书写.env.[mode]文件来指定环境变量,示例如下:
```key
.env 在所有环境中被载入配置
.env.production build时默认载入配置
.env.local 等价于.env,但会被.git忽略
```
.env 文件的内容是“key=value”这种的一个个键值对,key必须已VUE_APP_开头才可以被webpack.DefinePlugin静态嵌入到客户端侧的包中。为一个特定模式准备的环境文件 (例如 .env.production) 将会比一般的环境文件 (例如 .env) 拥有更高的优先级。
vue-cli有三个默认模式,示例如下:
```key
development模式,用于vue-cli-service serve
test模式,用于vue-cli-service test:unit
production模式,用于vue-cli-service build or vue-cli-service test:e2e
```
你可以通过 --mode 选项来覆写默认的模式,vue-cli-service --mode test 将载入.env.test和.env.test.local配置文件。
在客户端侧代码中,你可以通过 process.env.VUE_APP_*来访问它们,示例如下:
```key
.env 文件配置
VUE_APP_NAME=你好呀
代码访问
console.log(process.env.VUE_APP_NAME)
```
#### 减少项目build后的体积和加快项目build速度
##### 减少项目build后的体积
1. 对于有些库,对于库中的功能用的非常少的,可以去掉(我去掉了jquery以及lodash),用到的地方,参考源码自己写
2. 非用不可的又比较大的库(我这里用了monaco-edit),使用cdn方式引入
##### 加快项目build速度(DLLPlugin 插件)
项目中都会依赖很多第三方包,但是除非版本升级,一般这些第三方包都不太会发生变更,那么在每次build时,这些文件如果能提前build好,项目build只是引入这些第三方包build后的文件,那么将可以提升项目的build速度,DLLPugin插件即是起到该作用的工具。
DLLPugin包含DLLPlugin、DLLReferencePlugin,DLLPlugin用于创建只有dll的bundle(dll-only-bundle)以及manifest.json 的文件,DLLReferencePlugin通过该文件映射到相应的依赖中(build好的依赖)。
```key
新建vue.config.js,配置如下:
module.exports = {
pluginOptions: {
dll: {
entry: ["core-js", 'vue', 'vue-router', "element-ui", "node-rsa"]
}
}
}
```
但上述配置依赖都打包在一个文件中,文件过大会导致请求阻塞,DLLPlugin提供配置可以将依赖分别build到不同的文件,示例如下:
```key
module.exports = {
pluginOptions: {
dll: {
entry: {
vue: ["core-js", 'vue', 'vue-router'], # vue.*.dll.js
other: [ "element-ui", "node-rsa"] # other.*.dll.js
}
}
}
}
```
### 部署
vue项目build后生成文件目录,如下:
```
├── css
│ └── app.08315448.css
├── favicon.ico
├── img
│ └── logo.82b9c7a5.png
├── index.html
├── js
│ ├── app.d8650714.js
│ ├── app.d8650714.js.map
│ └── dll.561e88a2.dll.js
```
本质即是部署静态文件,使之可以被访问。但这里有个特殊的点是vue-router的history模式,示例如 http://localhost:8080/path ,在npm run serve部署开发环境时,是由node运行了一个服务端环境来代理静态资源的访问,它对于所有页面的访问实际都以index.html来响应,http://localhost:8080/path 实际path部分是通过在浏览器端的js路由代码来控制响应,无实际跳转。所以部署history模式的vue项目时需要注意满足这一点。使用nginx代理时,可以通过配置try_files来满足这一特性。我们使用vue项目时,一般都会有配套的后端api服务项目,如果不希望部署那么复杂,完全可以把vue项目的build后文件放置到后端api服务项目中,在后端程序书写访问控制代码,从而达到前后端项目独立开发,但统一部署,减少运维复杂度。示例基于python flask的后端服务:
```key
# 设置静态文件、模版文件都指向dist目录
app = Flask(__name__, template_folder="../dist", static_folder="../dist")
# 将前端路由控制的url访问全部交由该控制器处理响应
@app.errorhandler(404)
def index():
return render_template("index.html")
```
静态css、js等文件有flask的static控制器控制访问,其它前端路由控制的访问交由errorhandler(404)来响应
### 其它
linux try_files 命令介绍
语法规则
1. try_files file ... uri;
2. try_files file ... =code;
可应用上下文 server, location,命令具体含义指按指定的file顺序查找存在的文件,并使用第一个找到的文件进行请求处理,查找路径是按照给定的root或alias为根路径来查找的,如果给出的file都没有匹配到,则重新请求最后一个参数给定的uri,就是新的location匹配,如果是格式2,最后一个参数是 = 404 ,若给出的file都没有匹配到,则最后返回404的响应码。示例如下:
```key
示例一
location /images/ {
try_files $uri /images/default.gif;
}
示例二
location / {
try_files $uri $uri/index.html $uri.html =404;
}
示例三
location / {
try_files /system/maintenance.html
$uri $uri/index.html $uri.html
@mongrel;
}
location @mongrel {
proxy_pass http://mongrel;
}
```
$uri 这个变量指当前的请求URI,不包括任何参数(见 𝑎𝑟𝑔𝑠)。
### 参考
https://cli.vuejs.org/zh/guide/mode-and-env.html
https://www.webpackjs.com/plugins/dll-plugin
https://juejin.im/post/6844903734007300109
https://cli.vuejs.org/guide/deployment.html
https://router.vuejs.org/zh/guide/essentials/history-mode.html#%E5%90%8E%E7%AB%AF%E9%85%8D%E7%BD%AE%E4%BE%8B%E5%AD%90
http://nginx.org/en/docs/http/ngx_http_core_module.html#try_files