来看看官网提供的多页面配置:pages需要在vue.config.js中进行配置,如下:pages:{index:{//页面的Entryentry:'src/index/main.js',//templatesourcetemplate:'public/index.html',//dist/index.html中的输出文件名:'index.html',//当使用title选项时,//模板中的title标签需要是
<%=htmlWebpackPlugin.options.title%>title:'IndexPage',//这个包含的块页面,默认情况下它将包含//提取的通用块和供应商块。chunks:['chunk-vendors','chunk-common','index']},//当使用仅限条目的字符串格式时,//模板将被推断为`public/subpage.html`//并且如果找不到,回退到`public/index.html`。//输出文件名将被推断为`subpage.html`。subpage:'src/subpage/main.js'}每个页面都是一个对象,其中包含如下配置:entry入口文件路径template模板文件路径filenamecompiledhtmlfilenametitlechunksinhtmlpackagedchunks文件,数组格式,包含entryfiles首先我们要设计src目录下的多页文件:看了很多多页工程,有两种方案:一种叫pages文件夹,另一种叫views或者其他名字可以选择或者自己定义文件夹。这里我们选择页面,看看里面的文件:入口文件:文件名可以叫main.js或者index.js模板文件:可以使用统一的'public/index.html',也可以自己写在目录中,命名为index.htmltitle:你可以从一个文件中获取srcpagespage1index.htmlmain.jsApp.vuepage2index.htmlmain.jsApp.vue下面是通过函数Pages配置生成的:第一步:找到入口文件。可以使用globconstglob=require('glob')页面目录的位置,可以使用相对路径或绝对路径:constpath=require('path')constPAGES_PATH=path.resolve(__dirname,'./src/pages')定义一个pages对象:constpages={}glob.sync(PAGES_PATH+'/*/main.js').forEach(filepath=>{//...})这里是要设置相应的键。很多项目基本上都是用/分隔符把字符串排列起来,然后简单的获取。但是,如果你熟悉node.js的路径模块,你会这样处理:constpageName=path.basename(path.dirname(filepath))在pages中循环设置:pages[pageName]={entry:filepath,filename:`${pageName}.html`,chunks:['chunk-vendors','chunk-common',pageName]}模板有点复杂,我们需要判断一下,如果存在则使用自定义的,如果不存在则使用通用的consttemplatePath=path.dirname(filepath)+'/index.html'然后使用fs.existsSync判断是否是自定义文件exists:if(!fs.existsSync(templatePath)){//如果入口没有配置,直接使用templatePath='public/index.html'}当然,后面我们分享源码后,你会发现你做了无用的工作。我们来看一下源码实现部分:每个版本的cli-service都有很多小改动。cli-service/lib/config/app.js文件定义了一个变量multiPageConfig,用来获取vue.config.js取出来的页面:constmultiPageConfig=options.pagesclearonceentrywebpackConfig.entryPoints.clear()通过Object获取key。keys,然后forEach循环constpages=Object.keys(multiPageConfig)pages.forEach(name=>{})循环内部:首先定义要使用的变量,从multiPageConfig[name]的每个对象中取:const{title,entry,template=`public/${name}.html`,filename=`${name}.html`,chunks}=normalizePageConfig(multiPageConfig[name])normalizePageConfig函数如下:processsubpage:'src/subpage/main.js'caseconstnormalizePageConfig=c=>typeofc==='string'?{entry:c}:csetentrywebpackConfig.entry(name).add(api.resolve(entry))hasDedicatedTemplate是判断用户传入的多页配置自定义模板路径是否存在:constfs=require('fs')consthasDedicatedTemplate=fs.existsSync(api.resolve(template))templatePath处理细节:htmlPath路径为:/Users/*/public/index.htmlconsthtmlPath=api.resolve('public/index.html')defaultHtmlPath路径是:/Users/*/node_modules/@vue/cli-service/lib/config/index-default。htmlconstdefaultHtmlPath=path.resolve(__dirname,'index-default.html')如果:1.如果有自定义模板,直接给templatePath2。如果不存在就先取public/index.html,如果不存在就取node_modules中的consttemplatePath=hasDedicatedTemplate?模板:fs.existsSync(htmlPath)?htmlPath:defaultHtmlPath最后使用html-webpack-plugin插件生成指定名称的html文件到指定目录:1.指定目录:由vue.config.js中的outputDir来决定constoutputDir=api。resolve(options.outputDir)2.生成关于html-webp的webpack配置ack-plugin部分:constHTMLPlugin=require('html-webpack-plugin')webpackConfig.plugin(`html-${name}`).use(HTMLPlugin,[pageHtmlOptions])pageHtmlOptions处理细节:传给html-的webpack-plugin插件的参数,这里默认设置了chunks,所以上面的配置没有用',名称],模板:templatePath,文件名:ensureRelative(outputDir,文件名),标题})