一. 目标
- /src/view内,一个文件夹输出一个页面
- 自动配置vue.config.js内的pages字段
- 不使用vue的router
二. 实现
1.vue-cli3基本配置
- 文件结构如下 去掉了src文件夹下的主入口文件,views文件夹下的文件夹内,一个文件夹生成一个页面
- vue.config.js配置 主要是vue.config.js下的pages字段, 指定多页面的入口,模板,输出文件等等, 配置路径
const path = require('path');
console.log('当前环境变量NODE_ENV:', process.env.NODE_ENV);
module.exports = {
// 配置多页应用
pages: {
index: {
// page 的入口
entry: 'src/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']
},
introduce: {
entry: 'src/introduce.js',
template: 'public/introduce.html',
filename: 'introduce.html'
}
},
...
}
...
2. 自动配置pages字段
common.config.js文件
const fs = require('fs');
const join = require('path').join;
const fileList = [];
const VIEW_PATH = 'src/views';
// 读取文件夹
function readDirs(path) {
let dirList = fs.readdirSync(path);
dirList.forEach((item, index) => {
readFilesOfDir(path, item);
});
}
// 读取文件
function readFilesOfDir(path, dirName) {
const dirPath = join(path, dirName);
const stat = fs.statSync(dirPath);
// 读取文件夹下的所有文件, 检查是否存在和文件夹名称相同的三个文件(dirName.html, dirName.vue, dirName.js)
if (stat.isDirectory()) {
const files = fs.readdirSync(dirPath);
const filesObj = array2obeject(files, dirName);
fileList.push(filesObj);
}
}
// 验证文件夹文件正确性
function vertify(list) {
let flag = true;
for (let i = 0, iLen = list.length; i < iLen; i++) {
const item = list[i];
const necessaryFiles = [`${item.dirName}.html`, `${item.dirName}.js`, `${item.dirName}.vue`];
for (let j = 0, jLen = necessaryFiles.length; j < jLen; j++) {
const subItem = necessaryFiles[j];
if (!item.hasOwnProperty(subItem)) {
console.error(`-------------------${item.dirName}缺少文件${subItem}, 请修改!-------------------`);
flag = false;
break;
}
}
if (flag) {
console.log(`${item.dirName}文件夹文件结构验证通过!`);
}
if (!flag) {
break;
}
}
return flag;
}
// 数组转为对象
function array2obeject(list, dirName) {
const obj = {};
for (const key in list) {
obj[list[key]] = list[key];
}
obj.dirName = dirName;
return obj;
}
// 生成pages
function createPageParams() {
readDirs(VIEW_PATH);
const flag = vertify(fileList);
let pages = {};
if (flag) {
fileList.forEach(ele => {
const dirName = ele.dirName;
pages[dirName] = {
// page 的入口
entry: `${VIEW_PATH}/${dirName}/${dirName}.js`,
// 模板来源
template: `${VIEW_PATH}/${dirName}/${dirName}.html`,
// 在 dist/home.html 的输出
filename: `${dirName}.html`
}
});
}
return pages;
}
// 生成pages变量
module.exports = {
createPageParams: createPageParams
}
vue.config.js调用示例
const path = require('path');
const common = require('./common.config');
const pages = common.createPageParams();
console.log('当前环境变量NODE_ENV:', process.env.NODE_ENV);
module.exports = {
pages: pages,
chainWebpack: config => {
const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
types.forEach(type => addStyleResource(config.module.rule('scss').oneOf(type)))
if (process.env.NODE_ENV === 'production') {
config.set('externals', {
vue: 'Vue',
'vue-router': 'VueRouter',
'lodash': '_'
});
}
},
}
function addStyleResource (rule) {
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [
path.resolve(__dirname, './src/styles/common.scss'),
],
})
}