0. 直接打包
npm run build
1. 按需加载第三方库
例如 ElementUI、lodash 等
npm install babel-plugin-component -D
babel.config.js
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
main.js
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
换成
import './plugins/element.js'
element.js
import Vue from 'vue'
import { Button } from 'element-ui'
Vue.use(Button)
2. 移除 console.log
npm i babel-plugin-transform-remove-console -D
babel.config.js
const prodPlugins = []
if (process.env.NODE_ENV === 'production') {
prodPlugins.push('transform-remove-console')
}
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
],
...prodPlugins
]
}
3. Close SourceMap
vue.config.js
module.exports = {
productionSourceMap: false
}
4. Externals && CDN
vue.config.js
module.exports = {
productionSourceMap: false,
chainWebpack: config => {
config.when(process.env.NODE_ENV === 'production', config => {
config.set('externals', {
vue: 'Vue',
'vue-router': 'VueRouter',
axios: 'axios',
lodash: '_',
echarts: 'echarts',
nprogress: 'NProgress',
'vue-quill-editor': 'VueQuillEditor'
})
config.plugin('html').tap(args => {
args[0].isProd = true
return args
})
})
}
}
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<% if(htmlWebpackPlugin.options.isProd){ %>
<script src="https://cdn.staticfile.org/vue/2.6.11/vue.min.js"></script>
<script src="https://cdn.staticfile.org/vue-router/3.1.3/vue-router.min.js"></script>
<script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.staticfile.org/lodash.js/4.17.11/lodash.min.js"></script>
<script src="https://cdn.staticfile.org/echarts/4.1.0/echarts.min.js"></script>
<script src="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.js"></script>
<!-- 富文本编辑器的 js 文件 -->
<script src="https://cdn.staticfile.org/quill/1.3.4/quill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.4/dist/vue-quill-editor.js"></script>
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
5. 排除 CSS 打包,用 CDN 替代
module.exports = {
chainWebpack: config => {
config.when(process.env.NODE_ENV === 'production', config => {
config.set('externals', {
'nprogress/nprogress.css': 'NProgress',
})
})
}
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<% if(htmlWebpackPlugin.options.isProd){ %>
<!-- nprogress 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/nprogress/0.2.0/nprogress.min.css" />
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
继续优化,vue.config.js
module.exports = {
chainWebpack: config => {
config.when(process.env.NODE_ENV === 'production', config => {
config.set('externals', {
'quill/dist/quill.core.css': 'VueQuillEditor',
'quill/dist/quill.snow.css': 'VueQuillEditor',
'quill/dist/quill.bubble.css': 'VueQuillEditor'
})
})
}
}
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<% if(htmlWebpackPlugin.options.isProd){ %>
<!-- 富文本编辑器 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.core.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.snow.min.css" />
<link rel="stylesheet" href="https://cdn.staticfile.org/quill/1.3.4/quill.bubble.min.css" />
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
6. 区分出开发环境和线上环境的标题
public/index.html
<title><%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统</title>
7. ElementUI 使用 CDN
注意:使用了完整的 CDN 文件,之前的按需加载在生产环境就失去意义了
vue.config.js
module.exports = {
chainWebpack: config => {
config.when(process.env.NODE_ENV === 'production', config => {
config.set('externals', {
'./plugins/element.js': 'ELEMENT'
})
config.plugin('html').tap(args => {
args[0].isProd = true
return args
})
})
}
}
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>
<%= htmlWebpackPlugin.options.isProd ? '' : 'dev - ' %>电商后台管理系统
</title>
<% if(htmlWebpackPlugin.options.isProd){ %>
<!-- element-ui 的样式表文件 -->
<link rel="stylesheet" href="https://cdn.staticfile.org/element-ui/2.13.0/theme-chalk/index.css" />
<!-- element-ui 的 js 文件 -->
<script src="https://cdn.staticfile.org/element-ui/2.13.0/index.js"></script>
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
8. 部署到 Nginx
下载 Nginx,双击运行 nginx.exe,浏览器输入 localhost 能看到界面表示服务启动成功!
前端 axios 中的 baseURL 指定为 /api,配置 vue.config.js 代理如下
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://127.0.0.1:8888',
changeOrigin: true
}
}
}
}
路由模式、基准地址、404 记得也配置一下
const router = new VueRouter({
mode: 'history',
base: '/shop/',
routes: [
// ...
{
path: '*',
component: NotFound
}
]
})
执行 npm run build 打包,把 dist 中的内容拷贝到 Nginx 的 html 文件夹中
修改 Nginx 配置
http {
server {
listen 80;
location / {
# proxy_pass https://www.baidu.com;
root html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
# 重写地址
# rewrite ^.+api/?(.*)$ /$1 break;
# 代理地址
proxy_pass http://127.0.0.1:8888;
# 不用管
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
重启服务
nginx -s reload
访问 localhost 查看下效果吧
9. 开启 Gzip 压缩
前端通过 vue.config.js 配置,打包成带有 gzip 的文件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config.plugins = [...config.plugins, new CompressionWebpackPlugin()]
}
}
}
Nginx 中开启 gzip 即可