<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在微前端qiankun中使用Vite你踩坑了嗎?

          共 4280字,需瀏覽 9分鐘

           ·

          2022-01-22 01:31

          哈嘍,我是樹(shù)醬。之前搭建的微前端體系已經(jīng)穩(wěn)步運(yùn)行將近兩年了,最近遇到一些童鞋反饋。之前據(jù)說(shuō)qiankun并不支持Vite打包的應(yīng)用,那是不是我就無(wú)法使用了?

          是的,官方暫未有文檔表明已經(jīng)支持Vite。接下來(lái)我會(huì)從Vite聊起,然后一步步解析如何去解決在qiankun微前端體系中集成基于Vite構(gòu)建的子應(yīng)用.

          1 為什么要用Vite?

          在Vite沒(méi)有誕生之前,我們前端大多都是基于 webpack 構(gòu)建的,主要離不開(kāi)以下兩點(diǎn):

          • 本地開(kāi)發(fā)(熱更新HMR)
          • 打包上線

          webpack的核心簡(jiǎn)單概括就是將各類資源打包整合在一起,形成bundle的能力。但是隨著項(xiàng)目的不斷迭代,慢慢演變成一個(gè)中大型項(xiàng)目,這時(shí)候你會(huì)發(fā)現(xiàn)打包時(shí)間太久了,換句話說(shuō)構(gòu)建效率變低了。

          bundle工具的演變

          而在Bundle工具的演變過(guò)程中,我們見(jiàn)證了?webpack[1]Rollup[2]?和?Parcel[3]?等工具,同時(shí)構(gòu)建效率也在逐步提升,如下圖所示??

          webpack vs rollup vs parcel vs esbuild

          而伴隨著瀏覽器對(duì)ES模塊(ESM)逐步支持兼容,是不是有更快的方式可以解決構(gòu)建問(wèn)題?

          那就是基于瀏覽器支持的?ESM import特性實(shí)現(xiàn)的 bundless, 通過(guò)利用瀏覽器進(jìn)行模塊間依賴加載,而不需要在編譯時(shí)進(jìn)行。

          換句話說(shuō)我們不再需要構(gòu)建一個(gè)完整的 Bundle(下文我們稱為:Bundless)。當(dāng)我們修改文件時(shí),瀏覽器只需要重新加載單個(gè)文件即可。

          image.png

          啊樂(lè)同學(xué):那有哪些 Bundless 解決方案 ?

          (見(jiàn)下文)Vite就是其一,回顧下Vite的優(yōu)勢(shì):??

          • 在開(kāi)發(fā)模式下:基于esbuild 預(yù)構(gòu)建依賴(減少HTTP請(qǐng)求) + 瀏覽器自主加載對(duì)應(yīng)的模塊,熱更新頁(yè)面!

          • 在生產(chǎn)模式下:基于Rollup的打包,速度也有一定提升

          你一旦體驗(yàn)到Vite的神速!你真的會(huì)停不下來(lái) ??

          ?? 飯后思考:

          • esbuild不是比Rollup更快嗎?生產(chǎn)模式下,為何不用esbuild構(gòu)建??? 參考答案[4]

          • 如果是對(duì)于原生ESM不支持的瀏覽器,開(kāi)發(fā)模式咋處理??? 參考答案[5]

          • 不是說(shuō)好bundless?為何還要用esbuild 預(yù)構(gòu)建依賴呢??? 參考答案[6]

          • Bundless方案除了Vite之外,還有哪些??? 參考答案[7]

          • Vite 的目標(biāo)是要干掉 Webpack??? 參考答案[8]

          2. 微前端框架qiankun與Vite

          通過(guò)上文,我們了解到使用Vite的優(yōu)勢(shì)。那是否qiankun支持基于vite構(gòu)建的子應(yīng)用集成呢?這里我們以vue3+vite的demo為例

          會(huì)遇到以下兩個(gè)需要解決的問(wèn)題:

          • 開(kāi)發(fā)模式:在開(kāi)發(fā)環(huán)境下,如果我們使用 vite 來(lái)構(gòu)建 vue3 子應(yīng)用,基于vite的構(gòu)建機(jī)制,會(huì)在子應(yīng)的 html 的入口文件的 script 標(biāo)簽上攜帶 type=module。而我們知道qiankun父應(yīng)用引入子應(yīng)用,本質(zhì)上是將html做為入口文件,并通過(guò)import-html-entry這個(gè)庫(kù)去加載子應(yīng)用所需要的資源列表Js、css,然后通過(guò)eval直接執(zhí)行,而基于vite構(gòu)建的js中import、export并沒(méi)有被轉(zhuǎn)碼,會(huì)導(dǎo)致直接報(bào)錯(cuò)(不允許在非 type=module 的 script 里面使用 import)

          • 生產(chǎn)模式:生產(chǎn)模式下,因?yàn)闆](méi)有諸如webpack中支持運(yùn)行時(shí)publicPath,也就是__webpack_public_path__,換句話說(shuō)就是vite不支持運(yùn)行時(shí)publicPath,其主要作用是用來(lái)解決微應(yīng)用動(dòng)態(tài)載入的腳本、樣式、圖片等地址不正確的問(wèn)題。

          ?? 拓展閱讀:

          一開(kāi)始import-html-entry會(huì)過(guò)濾掉type=module的文件,導(dǎo)致缺失js卻直接eval最終執(zhí)行出錯(cuò),后期這個(gè)問(wèn)題官方已經(jīng)支持??

          • Support of?type=module?and?nomodule?attribute in?import-html-entry[9]

          目前qiankun官網(wǎng)文檔并沒(méi)有基于Vue3+Vite構(gòu)建的子應(yīng)用打包的文檔指引,但是我們可以在Github的Issue中找到一些解決方案,主要通過(guò)以下這兩種方式解決

          2.1 只解決生產(chǎn)模式的集成

          我們可以通過(guò)對(duì)子應(yīng)用vite配置的構(gòu)建配置改造來(lái)實(shí)現(xiàn)

          首先修改Vite.config.js·中的build配置, 默認(rèn)Vite的輸出目標(biāo)targetmodule,需改為esnext

          然后在配置文件中引入 @rollup/plugin-html[10]

          上圖省略部分方法,詳情請(qǐng)看本節(jié)末尾的Demo實(shí)例[11],代碼實(shí)現(xiàn)的目的是為了構(gòu)建html文件作為子應(yīng)用的入口,構(gòu)建結(jié)果如下所示??

          其他環(huán)節(jié)跟基于Webpack的配置大致相同,這里不一一贅述

          雖然這種方式針對(duì)生產(chǎn)模式可以實(shí)現(xiàn)集成,但是存在幾個(gè)局限性:

          • 我們知道為了讓qiankun?拿到子應(yīng)用export的生命周期函數(shù),所以需要將子應(yīng)用打包成?umd?格式,而vite的code-splitting(代碼分割)功能并不支持iifeumd兩種格式,這會(huì)導(dǎo)致路由無(wú)法實(shí)現(xiàn)懶加載。
          • 因?yàn)関ite不支持運(yùn)行時(shí)publicPath,只能在打包時(shí)寫死Base配置

          • 圖片最終會(huì)被打包成 base64

          更詳細(xì)的Demo集成例子:?? ?app-vue-vite[12]

          2.2 解決開(kāi)發(fā)模式 + 生產(chǎn)模式的集成

          單獨(dú)解決生產(chǎn)模式的集成也不方便,畢竟很多時(shí)候需要我們?cè)诒镜丨h(huán)節(jié)進(jìn)行調(diào)試,那有什么方式可以同時(shí)讓Vite支持這兩種模式的集成呢?

          Github上有一名開(kāi)源作者開(kāi)發(fā)了一款Vite插件叫vite-plugin-qiankun,通過(guò)這個(gè)插件可以在qiankun下走通這兩種模式。甚至保留了vite構(gòu)建模塊的優(yōu)勢(shì)

          1. 修改Vite.config.js
          1. 修改子應(yīng)用的main.ts,將生命周期mountbootstrapunmount 等通過(guò)插件函數(shù)renderWithQiankun在其中暴露完成。其他配置與基于webpack構(gòu)建的子應(yīng)用相同
          =

          ? 注意事項(xiàng):

          • qiankun官方是以window.__POWERED_BY_QIANKUN__來(lái)判斷當(dāng)前是否為qiankun環(huán)境下,而該插件引用之后是通過(guò)qiankunWindow.__POWERED_BY_QIANKUN__來(lái)判斷

          ?? 局限性:

          • 生產(chǎn)模式下依舊不支持publicPath, 需要將vite.config.jsbase配置寫死。導(dǎo)致多環(huán)境部署不便捷。無(wú)法像在webpack結(jié)合window.INJECTED_PUBLIC_PATH_BY_QIANKUN + publicpath來(lái)解決

          更詳細(xì)的Demo集成例子:?? viteapp[13]

          2.3 ?Vite對(duì)runtime publicpath的支持

          目前在Vite官方文檔沒(méi)查閱到相關(guān)的配置,但在Github中找到一個(gè)插件vite-plugin-dynamic-publicpath[14]。如果你有更好的解決方案,也歡迎評(píng)論區(qū)留言

          2.4 關(guān)于Vite的Dotenv配置

          如果你從 vue-cli 切換到Vite 需要注意 Dotenv 命名的變化

          • vite前綴是?VITE_?,vue-cli?是?VUE_APP_
          • 獲取方式也不一樣,在vite是通過(guò) import.meta.env,而在?vue-cli則是通過(guò)?process.env

          3.最后

          如果你有其他解決方式,歡迎在評(píng)論區(qū)留言,也可以加我微信,我們一起喝茶?? 討論

          你好,我是?? 樹(shù)醬,請(qǐng)你喝杯?? 記得三連哦~

          1.閱讀完記得點(diǎn)個(gè)贊哦,有?? 有動(dòng)力

          2.關(guān)注公眾號(hào)前端那些趣事,陪你聊聊前端的趣事

          3.文章收錄在Github frontendThings 感謝Star?

          參考資料

          [1]

          webpack: https://webpack.js.org/

          [2]

          Rollup: https://rollupjs.org/

          [3]

          Parcel: https://parceljs.org/

          [4]

          ?? 參考答案: https://cn.vitejs.dev/guide/why.html#why-not-bundle-with-esbuild

          [5]

          ?? 參考答案: https://cn.vitejs.dev/guide/#browser-support

          [6]

          ?? 參考答案: https://cn.vitejs.dev/guide/dep-pre-bundling.html

          [7]

          ?? 參考答案: https://cn.vitejs.dev/guide/comparisons.html

          [8]

          ?? 參考答案: https://www.zhihu.com/question/477139054/answer/2156019180

          [9]

          Support of?type=module?and?nomodule?attribute in?import-html-entry: https://github.com/umijs/qiankun/issues/507

          [10]

          @rollup/plugin-html: https://github.com/rollup/plugins/tree/master/packages/html

          [11]

          Demo實(shí)例: https://github.com/gongshun/qiankun-vue-demo/blob/feature/vite-child/app-vue-vite/vite.config.ts

          [12]

          ?? ?app-vue-vite: https://github.com/gongshun/qiankun-vue-demo/tree/feature/vite-child/app-vue-vite

          [13]

          ?? viteapp: https://github.com/tengmaoqing/vite-plugin-qiankun/tree/master/example/viteapp

          [14]

          vite-plugin-dynamic-publicpath: https://github.com/jy0529/vite-plugin-dynamic-publicpath


          瀏覽 131
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲AV无码久久精品蜜桃小说 | 91干在线观看 | 天天视频黄 | 狂野欧美性交 | 日韩第1页|