Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供:
main.js :是我们的入口文件,主要作用是初始化vue实例并使用需要的插件。
单页应用(SPA)往往只含有包含一个主入口文件与index.html,页面间切换通过局部刷新资源来完成。而在多页应用中,我们会为每个HTML文档文件都指定好一个JS入口,这样一来当页面跳转时用户会获得一个新的HTML文档,整个页面会重新加载。
单页应用、多页应用的优劣势在此就不进行分析了,总而言之,多页架构模式暂时是无法取代的。
1、vue-cli 2.0版本官方不支持多页,且2.0使用的webpack构建任务不支持多线程以及DLL,全靠自己扩展,不便于维护和升级
2、vue-cli 2.0在多页数量较多的情况下,且一个单页比较大的时候,不管本地热更新还是构建打包,都是非常慢的。之前的项目在不开启webpack多线程时,整个项目热更新需要20秒左右!这意味着你修改保存文档,需要更待20秒页面才刷新…,所以,大型项目支持启动单页调试功能非常非常重要!
3、现在的工程大多存在多个子应用,且多个子通常使用一套组件,但是子应用采用单独发包迭代。通常是建立多个工程,然后前端公共库和组件套等都上传NPM,其实这样挺费劲的。所以支持多应用也是有必要。
vue-cli 3.0官方支持多页,重点在于vue.config.js文件的配置。
官方多页面配置API地址:https://cli.vuejs.org/zh/config/#pages
1、v-cli3.0在vue.config.js中暴漏出一个pages字段进行多入口配置,默认则是单入口模式;
2、修改项目目录:
a) 在src文件夹下新建pages文件夹
b) 在pages文件夹下新建page1、page2模块
修改结构如下图所示:
至此多页面的模块目录结构已经准备完毕,接下来就是如何配置webpack:
4、 初步多入口写法
手动增加入口格式确定后即考虑如何从pages文件夹自动获取入口对象来传给pages。
5、 自动生成入口对象
// 多页配置
let path = require('path')
let glob = require('glob')
//配置pages多页面获取当前文件夹下的html和js
function getEntry(globPath) {
let entries = {}, basename, tmp, pathname, appname;
glob.sync(globPath).forEach(function(entry) {
basename = path.basename(entry, path.extname(entry));
// console.log(entry)
tmp = entry.split('/').splice(-3);
console.log(tmp)
pathname = basename; // 正确输出js和html的路径
// console.log(pathname)
entries[pathname] = {
entry: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[1] + '.js',
template: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[2],
title: tmp[2],
filename: tmp[2]
};
});
return entries;
}
let pages = getEntry('./src/pages/**?/*.html');
console.log(pages)
const DIST_PATH = path.resolve(__dirname, 'dist');
// 多页配置 End
核心思想:
(1) 利用node.js中path模块的path.basename方法获取文件路径
(2) 利用node.js中glob模块的glob.sync方法来获取匹配对应规则的文件.
最终通过getEntry(’./src/pages/**?/*.html’)方法自动从pages文件夹里将多个入口模块拼接出pages参数需要的多入口格式。
6、查看当前项目中webpack中的配置
核心一点就是: cmd 中敲 vue inspect > output.js , 这样我们会得到一份最终生效的 webpack 配置信息,省去了你自己去看 cli-service 源码。
最后完整的vue.config.js代码奉上:
// 多页配置
let path = require('path')
let glob = require('glob')
//配置pages多页面获取当前文件夹下的html和js
function getEntry(globPath) {
let entries = {}, basename, tmp, pathname, appname;
glob.sync(globPath).forEach(function(entry) {
basename = path.basename(entry, path.extname(entry));
// console.log(entry)
tmp = entry.split('/').splice(-3);
console.log(tmp)
pathname = basename; // 正确输出js和html的路径
// console.log(pathname)
entries[pathname] = {
entry: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[1] + '.js',
template: 'src/' + tmp[0] + '/' + tmp[1] + '/' + tmp[2],
title: tmp[2],
filename: tmp[2]
};
});
return entries;
}
let pages = getEntry('./src/pages/**?/*.html');
console.log(pages)
const DIST_PATH = path.resolve(__dirname, 'dist');
// 多页配置 End
// vue.config.js 配置说明
// 这里只列一部分,具体配置惨考文档啊
module.exports = {
// baseUrl type:{string} default:'/'
// 将部署应用程序的基本URL
// 将部署应用程序的基本URL。
// 默认情况下,Vue CLI假设您的应用程序将部署在域的根目录下。
// https://www.my-app.com/。如果应用程序部署在子路径上,则需要使用此选项指定子路径。例如,如果您的应用程序部署在https://www.foobar.com/my-app/,集baseUrl到'/my-app/'.
publicPath: process.env.NODE_ENV === 'production' ? '/online/' : '/',
// outputDir: 在npm run build时 生成文件的目录 type:string, default:'dist'
outputDir: DIST_PATH,
assetsDir:'static',
pages,
// pages:{ type:Object,Default:undfind }
/*
构建多页面模式的应用程序.每个“页面”都应该有一个相应的JavaScript条目文件。该值应该是一
个对象,其中键是条目的名称,而该值要么是指定其条目、模板和文件名的对象,要么是指定其条目
的字符串,
注意:请保证pages里配置的路径和文件名 在你的文档目录都存在 否则启动服务会报错的
*/
// lintOnSave:{ type:Boolean default:true } 问你是否使用eslint
lintOnSave: true,
// productionSourceMap:{ type:Bollean,default:true } 生产源映射
// 如果您不需要生产时的源映射,那么将此设置为false可以加速生产构建
productionSourceMap: false,
// devServer:{type:Object} 3个属性host,port,https
// 它支持webPack-dev-server的所有选项
devServer: {
contentBase: DIST_PATH,
port: 8080, // 端口号
host: 'localhost',
https: false, // https:{type:Boolean}
open: true, //配置自动启动浏览器
// proxy: 'http://localhost:4000' // 配置跨域处理,只有一个代理
proxy: {
'/api': {
target: '',
ws: true,
changeOrigin: true
}
}, // 配置多个代理
before: app => {}
}
}