二、多入口
在單頁(yè)應(yīng)用中,我們的入口文件只有一個(gè), CLI 默認(rèn)配置的是 main.js ,但是到了多頁(yè)應(yīng)用,我們的入口文件便包含了 page1.js 、 page2.js 、 index.js 等,數(shù)量取決于 pages 文件夾下目錄的個(gè)數(shù),這時(shí)候?yàn)榱隧?xiàng)目的可拓展性,我們需要自動(dòng)計(jì)算入口文件的數(shù)量并解析路徑配置到 webpack 中的 entry 屬性上,如:
module.exports = { ... entry: { page1: '/xxx/pages/page1/page1.js', page2: '/xxx/pages/page2/page2.js', index: '/xxx/pages/index/index.js', }, ... }
那么我們?nèi)绾巫x取并解析這樣的路徑呢,這里就需要使用工具和函數(shù)來(lái)解決了。我們可以在根目錄新建 build 文件夾存放 utils.js 這樣共用的 webpack 功能性文件,并加入多入口讀取解析方法
/* utils.js */ const path = require('path'); // glob 是 webpack 安裝時(shí)依賴的一個(gè)第三方模塊,該模塊允許你使用 * 等符號(hào), // 例如 lib/*.js 就是獲取 lib 文件夾下的所有 js 后綴名的文件 const glob = require('glob'); // 取得相應(yīng)的頁(yè)面路徑,因?yàn)橹暗呐渲?,所以?src 文件夾下的 pages 文件夾 const PAGE_PATH = path.resolve(__dirname, '../src/pages'); /* * 多入口配置 * 通過(guò) glob 模塊讀取 pages 文件夾下的所有對(duì)應(yīng)文件夾下的 js * 后綴文件,如果該文件存在 * 那么就作為入口處理 */ exports.getEntries = () => { let entryFiles = glob.sync(PAGE_PATH + '/*/*.js') // 同步讀取所有入口文件 let map = {} // 遍歷所有入口文件 entryFiles.forEach(filePath => { // 獲取文件名 let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')) // 以鍵值對(duì)的形式存儲(chǔ) map[filename] = filePath }) return map }
讀取并存儲(chǔ)完畢后,我們得到了一個(gè)入口文件的對(duì)象集合,這個(gè)對(duì)象我們便可以將其設(shè)置到 webpack 的 entry 屬性上,這里我們需要修改 vue.config.js 的配置來(lái)間接修改 webpack 的值
/* vue.config.js */ const utils = require('./build/utils') module.exports = { ... configureWebpack: config => { config.entry = utils.getEntries() }, ... }
這樣我們多入口的設(shè)置便完成了,當(dāng)然這并不是 CLI 所希望的操作,后面我們會(huì)進(jìn)行改進(jìn)。
三、多模板
相對(duì)于多入口來(lái)說(shuō),多模板的配置也是大同小異,這里所說(shuō)的模板便是每個(gè) page 下的 html 模板文件,而模板文件的作用主要用于 webpack 中 html-webpack-plugin 插件的配置,其會(huì)根據(jù)模板文件生產(chǎn)一個(gè)編譯后的 html 文件并自動(dòng)加入攜帶 hash 的腳本和樣式,基本配置如下
/* webpack 配置文件 */ const HtmlWebpackPlugin = require('html-webpack-plugin') // 安裝并引用插件 module.exports = { ... plugins: [ new HtmlWebpackPlugin({ title: 'My Page', // 生成 html 中的 title filename: 'demo.html', // 生成 html 的文件名 template: 'xxx/xxx/demo.html', // 模板路徑 chunks: ['manifest', 'vendor', 'demo'], // 所要包含的模塊 inject: true, // 是否注入資源 }) ] ... }
以上是單模板的配置,那么如果是多模板只要繼續(xù)往 plugins 數(shù)組中添加 HtmlWebpackPlugin 即可,但是為了和多入口一樣能夠靈活的獲取 pages 目錄下所有模板文件并進(jìn)行配置,我們可以在 utils.js 中添加多模板的讀取解析方法
/* utils.js */ // 多頁(yè)面
/* vue.config.js */ const utils = require('./build/utils') module.exports = { ... configureWebpack: config => { config.entry = utils.getEntries() // 直接覆蓋 entry 配置 // 使用 return 一個(gè)對(duì)象會(huì)通過(guò) webpack-merge 進(jìn)行合并,plugins 不會(huì)置空 return { plugins: [...utils.htmlPlugin()] } }, ... }
如此我們多頁(yè)應(yīng)用的多入口和多模板的配置就完成了,這時(shí)候我們運(yùn)行命令 yarn build 后你會(huì)發(fā)現(xiàn) dist 目錄下生成了 3 個(gè) html 文件,分別是 index.html 、 page1.html 和 page2.html
四、使用 pages 配置
其實(shí),在 vue.config.js 中,我們還有一個(gè)配置沒(méi)有使用,便是 pages 。 pages 對(duì)象允許我們?yōu)閼?yīng)用配置多個(gè)入口及模板,這就為我們的多頁(yè)應(yīng)用提供了開(kāi)放的配置入口。官方示例代碼如下
/* vue.config.js */ module.exports = { pages: { index: { // page 的入口 entry: 'src/index/main.js', // 模板來(lái)源 template: 'public/index.html', // 在 dist/index.html 的
我們不難發(fā)現(xiàn), pages 對(duì)象中的 key 就是入口的別名,而其 value 對(duì)象其實(shí)是入口 entry 和模板屬性的合并,這樣我們上述介紹的獲取多入口和多模板的方法就可以合并成一個(gè)函數(shù)來(lái)進(jìn)行多頁(yè)的處理,合并后的 setPages 方法如下
// pages 多入口配置 exports.setPages = configs => { let entryFiles = glob.sync(PAGE_PATH + '/*/*.js') let map = {} entryFiles.forEach(filePath => { let filename = filePath.substring(filePath.lastIndexOf('\/') + 1, filePath.lastIndexOf('.')) let tmp = filePath.substring(0, filePath.lastIndexOf('\/')) let conf = { // page 的入口 entry: filePath, // 模板來(lái)源 template: tmp + '.html', // 在 dist/index.html 的
上述代碼我們 return 出的 map 對(duì)象就是 pages 所需要的配置項(xiàng)結(jié)構(gòu),我們只需在 vue.config.js 中引用即可
/* vue.config.js */ const utils = require('./build/utils') module.exports = { ... pages: utils.setPages(), ... }
這樣我們多頁(yè)應(yīng)用基于 pages 配置的改進(jìn)就大功告成了,當(dāng)你運(yùn)行打包命令來(lái)查看輸出結(jié)果的時(shí)候,你會(huì)發(fā)現(xiàn)和之前的方式相比并沒(méi)有什么變化,這就說(shuō)明這兩種方式都適用于多頁(yè)的構(gòu)建,但是這里還是推薦大家使用更便捷的 pages 配置
總結(jié)
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com