前言
对于vue多页面配置,可以说cli2-cli3,是一个从0到1的过程,想起cli2的不堪回首,cli3是香的不是一丁半点;虽然cli3本身提供了pages多页面的入口配置,但是想要灵活的根据配置去适应结构,还是需要一些操作,避免后期不停的修改;本文就配合node做一个灵活配置以及设置一些刚需的配置加性能优化。
创建项目
-
操作方式
vue create xxx ... ... 选择配置(非路由模式) ... ... 创建完成
-
项目结构
分析vue.config.js
-
初始代码
module.exports = { lintOnSave: false }
-
官网多页面配置代码
module.exports = { pages: { index: { // page 的入口 entry: 'src/index/main.js', // 模板来源 template: 'public/index.html', // 在 dist/index.html 的输出 filename: 'index.html', // 当使用 title 选项时, // template 中的 title 标签需要是 <title><%= htmlWebpackPlugin.options.title %></title> title: 'Index Page', // 在这个页面中包含的块,默认情况下会包含 // 提取出来的通用 chunk 和 vendor chunk。 chunks: ['chunk-vendors', 'chunk-common', 'index'] }, // 当使用只有入口的字符串格式时, // 模板会被推导为 `public/subpage.html` // 并且如果找不到的话,就回退到 `public/index.html`。 // 输出文件名会被推导为 `subpage.html`。 subpage: 'src/subpage/main.js' } }
修改前分析
- 首先我们从官网提供的代码得出一个结论,那就是多页面其实就是一个统一入口的list,所以当有了新增页面的需求,为了不人工去修改添加list的数据信息,我们需要把这一块脚本化;
- 其次从第一条来看,多页面的结构和初始化的结构是不一致的,所以我们第一步先要修改整个模板的渲染结构,做增删处理,当然删不是刚需,但冗余的结构将毫无意义;
修改-调整结构
1.可清空public文件夹、删除main.js和app.vue等其他非核心冗余文件
2.src增加模板入口文件夹,名字随意,本来是用pages为入口文件夹,结构如下
修改-编写多页面配置逻辑
上面结构已经搭建好了,我们接下来调整逻辑,首先咱们先定好步骤;
第一步,怎么灵活?方案:将list用脚本读取配置;
第二部,怎么读取?方案:利用node的fs读取文件夹信息作为入口配置信息
方案有了,下面我们直接调整;
// -----------------------------pages config----------------------------------
const fs = require('fs')
let pages = {}
const _configPages = async function () {
await fs.readdirSync('./src/pages/').forEach((val) => {
pages[val] = {
// page entry
entry: `src/pages/${val}/index.js`,
// 模板来源
template: `src/pages/${val}/index.html`,
// 在 dist/index.html 的输出
filename: `${val}.html`
}
})
}
_configPages('./src/pages/') // readdirSync
module.exports = {
pages: pages // more pages config
}
注:打完收工,大家注意到唯一的key,就是每一个模板文件夹名称,里面的文件名称无需变更,所以每次添加一个页面,只需要重新run就可以了~
性能优化之gzip优化
首先说明一点的事,开启gzip,在最直观的感觉中,会占用服务端的带宽资源,但是相对于大文件的损耗,还是很值得的,而且目前主流的云cdn,默认开启gzip,所以提前gzip,往往是提高性能的最佳方式。
走一个configureWebpack,简单暴力
compression-webpack-plugin
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const gzipSourceList = ['css', 'js']
module.exports = {
configureWebpack: config => { // open gzip
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true
return {
plugins: [
new CompressionWebpackPlugin({
filename: '[path].gz[query]', // 目标资源文件名称
algorithm: 'gzip',
test: new RegExp(
'\\.(' + gzipSourceList.join('|') + ')$'
), // 匹配所有对应的文件
threshold: 10240, // 多少kb 配置10kb
minRatio: 0.8, // 压缩比例
deleteOriginalAssets: false // 是否删除原始资源
})
]
}
}
}
}
其余刚需配置
module.exports = {
publicPath: '/[name]/', // 根目录 | “/” 建议制定
outputDir: './dist/[name]/', // build path 打包输出路径
productionSourceMap: false, // don·t use map 不要把源暴露出去
devServer: {
port: 1314, // port
open: true, // default browser 主动打开默认浏览器
overlay: { // 报错展示
warnings: true, // eslint show warnings
errors: true // eslint show errors
}
}
}
结构拓展
为了使开发中高度灵活,所以一些fetch以及公共文件区域还是要预留出来的,结构如下~
-
fetch-index入口
import axios from 'axios' import qs from 'qs' function fetch (type, prefix, url, params, status) { return new Promise((resolve, reject) => { let postParams = {} const instance = axios.create({ timeout: 100000 }) postParams = params let fetchData = { method: type, url: `${prefix}${url}`, data: qs.stringify(postParams) } if (type === 'get' || type === 'GET') { } instance(fetchData).then(response => { const res = response.data if (res.code === status) { resolve(res) } else { resolve(res) } }).catch(error => { reject(error) }) }) } export { fetch }
-
fetch-api
import { fetch } from './index' import { API_ROOT_CODE } from '../config/config' // 域名配置区域 export default { getDemo (params) { // demo return fetch('get', API_ROOT_CODE, '/test/', params, 0) } }
... ... 等等等(此处省略,其他结构详情请参考源码)
调试工具
<script>
var _hmt = _hmt || [];
(function () {
// 这里使用的是 eruda, vconsole也不错,根据个人习惯(两种都是拦截了请求资源,所以遇到一些奇葩的请求问题,不妨注释一下)
const domains = [] // 正式服域名配置 根据域名自动判断是否开启
const hostname = window.location.hostname
if (domains.indexOf(hostname) === -1) {
var src = '//cdn.bootcss.com/eruda/1.2.4/eruda.min.js';
document.write('<scr' + 'ipt src="' + src + '"></scr' + 'ipt>');
document.write('<scr' + 'ipt>eruda.init();</scr' + 'ipt>');
}
})();
</script>
... ...
结语
本文基于cli拓展优化,基本适用于目前绝大多数项目级多页面开发,欢迎大家多提一些宝贵意见和见解,欢迎指正~
GIT源码,直通车