目前 vue-cli3 生成的配置是做单页面的,然而,我们有时也会有多页面的需求 。比如我们最常见的一个项目跑多个独立的小型的H5页面,这些页面不可能每一次都开一个新项目.但是在实际的项目中,我们需要这样的脚手架,参考了很多大牛的脚手架,这里提供了一种我的单页面脚手架转换为多页面脚手架的方案,供大家参考。
要求:
- 1.首页显示项目所有的H5链接列表;
- 2.支持小型本地收据mock,方便本地测试接口【我个人不推荐,建议mock和项目分离】
准备
使用vue-cli生成一个你需要的单页面项目脚手架,然后我们就可以为所欲为了,目录我就不说明了,默认大家都知道。
每一次新开的页面都在pages里面起一个文件夹,文件夹名字就是H5页面名字,入口文件是文件夹的index.html和index.js。
修改vue.config.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82let path = require('path')
let glob = require('glob')
let mock = require('./src/mock/index.json');
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
//配置pages多页面获取当前文件夹下的html和js
function getEntry(globPath) {
let entries = {};
glob.sync(globPath).forEach(function(entry) {
var tmp = entry.split('/').splice(-3);
entries[tmp[1]] = {
entry: 'src/' + tmp[0] + '/' + tmp[1] + '/' + 'index.js',
template: 'src/' + tmp[0] + '/' + tmp[1] + '/' + 'index.html',
filename: tmp[1]
};
});
return entries;
}
let pages = getEntry('./src/pages/**?/*.html');
module.exports = {
lintOnSave: false,
baseUrl: process.env.NODE_ENV === "production" ? 'https://www.baidu.com/' : '/',
productionSourceMap: false,
pages,
devServer: {
index: '/',
open: process.platform === 'darwin',
host: '',
port: 9527,
https: false,
hotOnly: false,
proxy: {
'/xrf/': {
target: 'http://reg.tool.hexun.com/',
changeOrigin: true,
pathRewrite: {
'^/xrf': ''
}
},
}, // 设置代理
before: app => {
app.get('/', (req, res, next) => {
for(let i in pages){
res.write(`<a target="_self" href="/${i}">/${i}</a></br>`);
}
res.end()
});
app.get('/goods/list', (req, res, next) => { //mock数据
res.status(299).json(mock)
})
}
},
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => {
// 修改它的选项...
options.limit = 100
return options
})
Object.keys(pages).forEach(entryName => {
config.plugins.delete(`prefetch-${entryName}`);
});
if(process.env.NODE_ENV === "production") {
config.plugin("extract-css").tap(() => [{
path: path.join(__dirname, "./dist"),
filename: "css/[name].[contenthash:8].css"
}]);
}
},
configureWebpack: config => {
// if(process.env.NODE_ENV === "production") {
// config.output = {
// path: path.join(__dirname, "./dist"),
// filename: "js/[name].[contenthash:8].js"
// };
// }
}
}
启动项目,显示项目所有H5连接
最主要的是修改:
before第一个参数express实例。
1 | before: app => { |
拦截器
【vue-cli3升级】老项目提速50%(二)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99import store from '@/store'
import axios from 'axios'
import { Toast } from 'vant'
import util from '@/libs/util'
// 创建一个错误
const errorCreate = msg => {
const err = new Error(msg)
errorLog(err)
throw err
}
// 记录和显示错误
const errorLog = err => {
// 添加到日志
store.dispatch('xxx/log/add', {
type: 'error',
err,
info: '数据请求异常'
})
// 打印到控制台
if (process.env.NODE_ENV === 'development') {
util.log.danger('>>>>>> Error >>>>>>')
console.log(err)
}
// 显示提示
Toast({
message: err.message,
type: 'error'
})
}
// 创建一个 axios 实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000 // 请求超时时间
})
// 请求拦截器
service.interceptors.request.use(
config => {
// 在请求发送之前做一些处理
const token = util.cookies.get('token')
config.headers['X-Token'] = token
// 处理mock
if (process.env.VUE_APP_MOCK && config.isMock) {
config.url = `${process.env.VUE_APP_MOCK_BASE_URL}/${config.url}`
}
return config
},
error => {
// 发送失败
console.log(error)
Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
const dataAxios = response.data
const { code } = dataAxios
if (!code) return dataAxios
switch (code) {
case 0:
case 10000:
// 成功
return dataAxios.data
case 'xxx':
errorCreate(`[ code: xxx ] ${dataAxios.msg}: ${response.config.url}`)
break
default:
// 不是正确的 code
errorCreate(`${dataAxios.msg}: ${response.config.url}`)
break
}
},
error => {
if (error && error.response) {
switch (error.response.status) {
case 400: error.message = '请求错误'; break
case 401: error.message = '未授权,请登录'; break
case 403: error.message = '拒绝访问'; break
case 404: error.message = `请求地址出错: ${error.response.config.url}`; break
case 408: error.message = '请求超时'; break
case 500: error.message = '服务器内部错误'; break
case 501: error.message = '服务未实现'; break
case 502: error.message = '网关错误'; break
case 503: error.message = '服务不可用'; break
case 504: error.message = '网关超时'; break
case 505: error.message = 'HTTP版本不受支持'; break
default: break
}
}
errorLog(error)
return Promise.reject(error)
}
)
export default service
vue-cli3 全面配置(持续更新)
目录
- √ 配置多环境变量
- √ 配置基础 vue.config.js
- √ 配置 proxy 跨域
- √ 修复 HMR(热更新)失效
- √ 修复 Lazy loading routes Error: Cyclic dependency
- √ 添加别名
- √ 去除多余无效的 css
- √ 添加打包分析
- √ 配置 externals
- √ 去掉 console.log
- √ 开启 gzip 压缩
- √ 为 sass 提供全局样式,以及全局变量
- √ 添加 IE 兼容
- √ 文件上传 ali oss
- √ 完整依赖
☞ 配置多环境变量
通过在 package.json 里的 scripts 配置项中添加–mode xxx 来选择不同环境
在项目根目录中新建.env, .env.production, .env.analyz 等文件
只有以 VUEAPP 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中,代码中可以通过 process.env.VUE_APP_BASE_API 访问
NODE_ENV 和 BASE_URL 是两个特殊变量,在代码中始终可用
.env serve 默认的环境变量
1 | NODE_ENV = 'development' |
.env.production build 默认的环境变量
如果开启 ali oss,VUE_APP_SRC 配置为 ali oss 资源 url 前缀,如:’https://staven.oss-cn-hangzhou.aliyuncs.com/demo'
1 | NODE_ENV = 'production' |
.env.analyz 用于 webpack-bundle-analyzer 打包分析
如果开启 ali oss,VUE_APP_SRC 配置为 ali oss 资源 url 前缀,如:’https://staven.oss-cn-hangzhou.aliyuncs.com/demo'
1 | NODE_ENV = 'production' |
修改 package.json
1 | "scripts": { |
☞ 配置基础 vue.config.js
1 | const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV); |
☞ 配置 proxy 跨域
1 | const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV); |
☞ 修复 HMR(热更新)失效
1 | module.exports = { |
☞ 修复 Lazy loading routes Error: Cyclic dependency https://github.com/vuejs/vue-cli/issues/1669
1 | module.exports = { |
☞ 添加别名
1 | const path = require('path'); |
☞ 去除多余无效的 css
1 | npm i --save-dev glob-all purgecss-webpack-plugin |
1 | const PurgecssPlugin = require('purgecss-webpack-plugin'); |
☞ 添加打包分析
1 | const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; |
☞ 配置 externals
防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖
1 |
|
☞ 去掉 console.log
方法一:
1 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); |
方法二:使用 babel-plugin-transform-remove-console 插件
1 | npm i --save-dev babel-plugin-transform-remove-console |
在 babel.config.js 中配置
1 | const plugins = []; |
☞ 开启 gzip 压缩
1 | npm i --save-dev compression-webpack-plugin |
1 | const CompressionWebpackPlugin = require('compression-webpack-plugin'); |
还可以开启比 gzip 体验更好的 Zopfli 压缩详见https://webpack.js.org/plugins/compression-webpack-plugin
1 | npm i --save-dev @gfx/zopfli brotli-webpack-plugin |
1 | const CompressionWebpackPlugin = require('compression-webpack-plugin'); |
☞ 为 sass 提供全局样式,以及全局变量
可以通过在 main.js 中 Vue.prototype.$src = process.env.VUE_APP_SRC;挂载环境变量中的配置信息,然后在js中使用$src 访问。
css 中可以使用注入 sass 变量访问环境变量中的配置信息
1 | module.exports = { |
在 scss 中引用
1 | .home { |
☞ 添加 IE 兼容
1 | npm i --save @babel/polyfill |
在 main.js 中添加
1 | import '@babel/polyfill'; |
配置 babel.config.js
1 | const plugins = []; |
☞ 文件上传 ali oss
开启文件上传 ali oss,需要将 baseUrl 改成 ali oss 资源 url 前缀,也就是修改 VUE_APP_SRC
1 | npm i --save-dev webpack-oss |
1 | const AliOssPlugin = require('webpack-oss'); |
☞ 完整配置
- 安装依赖
1 | npm i --save-dev compression-webpack-plugin babel-plugin-transform-remove-console glob-all purgecss-webpack-plugin |
其他依赖(@gfx/zopfli、brotli-webpack-plugin、webpack-oss)根据需求选择安装
- 环境配置
.env
1 | NODE_ENV = 'development' |
.env.production
如果开启 ali oss,VUE_APP_SRC 配置为 ali oss 资源 url 前缀,如:’https://staven.oss-cn-hangzhou.aliyuncs.com/demo'
1 | NODE_ENV = 'production' |
.env.analyz
如果开启 ali oss,VUE_APP_SRC 配置为 ali oss 资源 url 前缀,如:’https://staven.oss-cn-hangzhou.aliyuncs.com/demo'
1 | NODE_ENV = 'production' |
- package.json
1 | "scripts": { |
- babel.config.js
1 | const plugins = []; |
- vue.config.js
1 | const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") |