目前 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")  |