vue 打包多頁(yè)面應(yīng)用解決方案

傳統(tǒng)的vue都是spa應(yīng)用,也就是俗稱的單頁(yè)面應(yīng)用。但是有些情況下我們可能需要將多個(gè)單頁(yè)面應(yīng)用整合在一個(gè)項(xiàng)目里,這個(gè)時(shí)候就需要將項(xiàng)目打包成多頁(yè)面應(yīng)用了。
具體操作往下看

首先創(chuàng)建一個(gè)符合需求的項(xiàng)目,文件目錄結(jié)構(gòu)如下


image.png

可以看到,他和傳統(tǒng)的項(xiàng)目不同的是,根目錄下不再有public文件夾,自然也就沒有了index.html。并且src目錄下的main.js入口文件也沒有了。

取而代之的是pages目錄下,多了幾個(gè)子項(xiàng)目,每個(gè)子項(xiàng)目的目錄結(jié)構(gòu)都是一個(gè)完整的單頁(yè)面應(yīng)用的結(jié)構(gòu),他們有自己的index.html 并且也有自己的入口文件。

接下來需要在vue.config.js里做一些調(diào)整

正常情況下,通過webpack配置多頁(yè)面應(yīng)用的話我們需要指定多個(gè)entry 并且指定多個(gè)output。但是 vue.config.js提供了一個(gè)叫做pages的配置項(xiàng)給我們,可以做到很便捷的配置這些東西。

要弄明白為什么要配置多入口就得先知道webpack的工作原理,他到底幫我們做了什么。其實(shí)webpack簡(jiǎn)單點(diǎn)理解就是指定入口js,也就是告訴webpack從哪個(gè)js開始起手打包,然后指定出口js,也就是最終輸出什么js。然后我們還需要借助HtmlWebpackPlugin這個(gè)插件幫我們生成模板html文件并且引入我們打包出來的js文件以及css文件。這樣一個(gè)單頁(yè)面應(yīng)用就打包完成了。
而vue.config.js提供的pages配置項(xiàng)應(yīng)該就是已經(jīng)整合了entry output以及HtmlWebpackPlugin了。

首先我們一個(gè)傳統(tǒng)的單頁(yè)面應(yīng)用,其實(shí)就是一個(gè)html文件,然后引入各種js。vue通過自己的路由來替換index.html文件里的模板。這就是一個(gè)單頁(yè)面應(yīng)用。理解了這個(gè),就不難理解配置多頁(yè)面應(yīng)用的過程了。既然一個(gè)html文件就是一個(gè)單頁(yè)面應(yīng)用,那多頁(yè)面應(yīng)用無(wú)非就是多個(gè)html文件嘛。
每個(gè)html文件負(fù)責(zé)自己項(xiàng)目里的東西。我們要做的就是將入口和出口都指定多個(gè)就行了。這樣打包出來的就是多個(gè)html文件,那我們?cè)谠L問的時(shí)候就和在訪問真實(shí)的服務(wù)器上的資源一樣,根據(jù)具體的文件名訪問到對(duì)應(yīng)的項(xiàng)目了。

下面先來看看pages的具體配置都有哪些


image.png
image.png

再來看看我們的配置

  pages:{
    index:{
      entry:'src/pages/pages1/main.ts',
      template:'src/pages/pages1/public/pages1.html',
      title:'pages1'
    },
    pages2:{
      entry:'src/pages/pages2/main.ts',
      template:'src/pages/pages2/public/pages2.html',
      title:'pages1'
    },
    pages3:{
      entry:'src/pages/pages3/main.ts',
      template:'src/pages/pages3/public/pages3.html',
      title:'pages1'
    },
  },

這樣配好之后我們運(yùn)行項(xiàng)目就能根據(jù)pages對(duì)象里的key值訪問到對(duì)應(yīng)的子項(xiàng)目了
比如http://localhost:8080/pages1/ 訪問到的就是pages1項(xiàng)目。

上圖中配置了一個(gè)index,目的是為了訪問http://localhost:8080的時(shí)候不會(huì)空白頁(yè),會(huì)默認(rèn)就指向index的模板。當(dāng)然也可以在devserve的before屬性里配置生成一個(gè)導(dǎo)航頁(yè)來跳轉(zhuǎn)目標(biāo)子項(xiàng)目,這些都是非常自由的。

下面來講一下在配置的過程中遇到的問題。
問題一:
剛開始配置的時(shí)候沒有刪除掉根目錄下public文件夾,然后運(yùn)行項(xiàng)目一直報(bào)錯(cuò)
Multiple chunks emit assets to the same filename。后面搜了很久都找不到合適的答案,這個(gè)報(bào)錯(cuò)的大概意思就是多個(gè)塊將資源發(fā)射到同一文件名。這里多個(gè)塊肯定說的就是我們?cè)趐ages里配置的這幾個(gè)子項(xiàng)目了。


image.png

估計(jì)就是因?yàn)閛utput的輸出filename沒有使用占位符,導(dǎo)致每個(gè)都輸出成index.html了,但是讓我不明白的是為什么在pages里配置的這些子項(xiàng)目明明都指定了自己的模板,還會(huì)和public里的index.html扯上關(guān)系。

最后解決方案就是要么刪除public文件夾,要么在pages里給每個(gè)對(duì)象指定filename。
但是為什么會(huì)出現(xiàn)這個(gè)問題,我猜測(cè)是構(gòu)建過程中默認(rèn)會(huì)去找public文件夾下的index.html,即使你配置了一個(gè)名為index的入口也無(wú)濟(jì)于事。

或許使用configureWebpack去更改webpack 的配置應(yīng)該就不會(huì)出現(xiàn)這個(gè)問題了把,但是那會(huì)需要多寫很多步驟。

如果想要了解webpack打包多頁(yè)面的可以看看這篇文章,寫的很詳細(xì)
https://juejin.cn/post/6844903545922158599

下面再調(diào)整一下pages,如果有很多個(gè)子項(xiàng)目的時(shí)候每個(gè)都需要這么去寫會(huì)很麻煩,這里可以通過glob這個(gè)庫(kù)來讀取src目錄下的文件,然后動(dòng)態(tài)的生成pages的配置項(xiàng)

const { defineConfig } = require('@vue/cli-service')
const glob = require('glob')
function getEntry(){
  let files = glob.sync('src/pages/**/public/*.html')
  const map = {}
  files.forEach(file=>{
    const key = file.split('public/')[1].split('.')[0]
    map[key] = {
      entry:`src/pages/${key}/main.ts`,
      template:file,
      title:key,
      filename:`${key}.html`
    }
  })
  console.log(map)

  return map
}
const pages = getEntry()

module.exports = defineConfig({
  transpileDependencies: true,
  pages
})

正則不太好,只能用點(diǎn)撈的方法去匹配內(nèi)容了,但是大概步驟就是這樣。
glob 是 webpack 安裝時(shí)依賴的一個(gè)第三方模塊,該模塊允許你使用 * 等符號(hào),
例如 lib/*.js 就是獲取 lib 文件夾下的所有 js 后綴名的文件

*代表所有目錄,代表所有名稱

src/pages/*/public/.html的意思就是src下的pages下的所有目錄下的public下的所有html文件的意思。

lQLPJxbRvpm7PvnNAeLNA-OwCE6VJlfUj-sDWLY07sD0AA_995_482.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容