精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Vite 插件開發實踐:微前端的資源處理

開發 前端
最近實現的簡單、透明、組件化微前端方案總體感覺不錯,也收到了很多人的反饋,很具有學習參考價值。

最近實現的簡單、透明、組件化微前端方案總體感覺不錯,也收到了很多人的反饋,很具有學習參考價值。

但有不少朋友使用該方案打包配置出現了一些問題,做事應有始有終,挖的坑總得完善一下。今天分享一下 Vite 針對微應用方案插件開發歷程。

通過文章你可以學到:

問題點

總結下來,在 Vite 中使用該微前端方案會遇到如下問題:

Vite 打包后的資源默認是以 HTML 為入口,我們的微前端方案需要以 JS 為入口

JS 為入口方案打包導出代碼被移除掉了

import.meta 語句打包被轉譯成 {} 空對象了

chunk 分離后的 CSS 文件,Vite 默認以document.head.appendChild 處理

打包后的 CSS 文件默認在 main.js 中沒有引用

資源路徑手動寫 new URL(image, import.meta.url) 太繁瑣

通過配置解決問題

首先前三個問題可以通過 Vite 解決。Vite 兼容了 rollup 的配置

問題一,修改 JS 入口則需要修改 Vite 配置,設置 build.rollupOptions.input 為 src/main.tsx,這樣 Vite 會默認以自定義配置的main.tsx 為入口文件做打包處理,不再生成 index.html。

問題二,rollup 的一個特性默認會清理掉入口文件的導出模塊,可以配置 preserveEntrySignatures: 'allow-extension' 來保證打包之后 export 的模塊不被移除掉。

問題三,看了 Vite 的 Issue,很多人遇到了這個問題,最初以為是 Vite 默認對它做了處理,后面看了 Vite 源碼也沒有發現處理的邏輯所在,應該是被 esbuild 做了轉譯。因此將 build.target 設置為 esnext 即可解決問題,即import.meta 屬于 es2020,設置為具體的 es2020 也行。

配置:

export default defineConfig({
build: {
// es2020 支持 import.meta 語法
target: 'es2020',
rollupOptions: {
// 用于控制 Rollup 嘗試確保入口塊與基礎入口模塊具有相同的導出
preserveEntrySignatures: 'allow-extension',
// 入口文件
input: 'src/main.tsx',
},
},
});


寫 Vite 插件

我們可以寫一個插件將上面的配置封裝。

一個普通的 Vite 插件很簡單

defineConfig({
plugins: [
{
// 可以使用 Vite 和 rollup 提供的鉤子
},
],
});


插件可以做很多事情,通過 Vite 和 rollup提供的鉤子對代碼解析、編譯、打包、輸出的整體流程進行自定義處理。

插件一般不直接寫在 vite.config.ts 中,可以定義一個方法導出這個插件,這里可以用config 這個鉤子來提供默認的 Vite 配置,將自定義的配置進行封裝:

export function microWebPlugin(): Plugin {
// 插件鉤子
return {
name: 'vite-plugin-micro-web',
config() {
return {
build: {
target: 'es2020',
rollupOptions: {
preserveEntrySignatures: 'allow-extension',
input: 'src/main.tsx',
},
},
};
},
};
}


這樣一個簡單的插件就完成了。

Vite 獨有鉤子

config - 在解析 Vite 配置前調用,它可以返回一個將被深度合并到現有配置中的部分配置對象,或者直接改變配置

configResolved - 在解析 Vite 配置后調用,使用這個鉤子讀取和存儲最終解析的配置

configureServer - 是用于配置開發服務器的鉤子

transformIndexHtml - 轉換 index.html 的專用鉤子。鉤子接收當前的 HTML 字符串和轉換上下文

handleHotUpdate - 執行自定義 HMR 更新處理。

rollup 鉤子

rollup 鉤子非常多,一共分兩個階段

編譯階段:

輸出階段:

這里我們會用到的鉤子有:

  • transform - 用于轉換已加載的模塊內容
  • generateBundle - 已經編譯過的代碼塊生成階段

樣式插入節點處理

問題四,document.head.appendChild 處理

使用 transform 鉤子,替換 Vite 默認的document.head.appendChild 為自定義節點

cssCodeSplit 打包為一個 CSS 文件

我們默認采用 cssCodeSplit 打包為一個 CSS 文件,免去了用插件 transform 修改 Vite 的邏輯。

問題五,即打包后的 CSS 沒有引用的問題,獲取這個帶 hash 的 CSS 我們可以有多種解決方案

使用 HTML 打包模式,抽取 index.html 中的 JS 、CSS 文件再單獨處理

不添加樣式文件名 hash ,通過約定固定該樣式名稱

通過鉤子提取文件名處理

權衡之下,最終采用 generateBundle 階段提取 Vite 編譯生成的 CSS 文件名,通過修改入口代碼將其插入。但 generateBundle 已經在輸出階段,不會再走 transform 鉤子。

發現一個兩全其美的辦法:創建極小的入口文件main.js,還可以配合 hash 和主應用時間戳緩存處理。

async generateBundle(options, bundle) {
// 主入口文件
let entry: string | undefined;
// 所有的 CSS 模塊
const cssChunks: string[] = [];
// 找出入口文件和 CSS 文件
for (const chunkName of Object.keys(bundle)) {
if (chunkName.includes('main') && chunkName.endsWith('.js')) {
entry = chunkName;
}
if (chunkName.endsWith('.css')) {
// 使用相對路徑,避免后續 ESM 無法解析模塊
cssChunks.push(`./${chunkName}`);
}
}
// 接下面代碼
},


生成新的入口文件

通過 bundle 提取可以獲取到帶 hash 的JS、CSS 入口文件了。現在需要寫入一個新的文件 main.js。rollup 中有個 API emitFile可以觸發創建一個資源文件。

接下來對它進行處理:

// 接上面代碼
if (entry) {
const cssChunksStr = JSON.stringify(cssChunks);

// 創建極小的入口文件,配合 hash 和主應用時間戳緩存處理
this.emitFile({
fileName: 'main.js',
type: 'asset',
source: `
// 帶上 microAppEnv 參數,使用相對路徑避免報錯
import defineApp from './${entry}?microAppEnv';

// 創建 link 標簽
function createLink(href) {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = href;
return link;
}

// 入口文件導出一個方法,將打包的 CSS 文件通過 link 的方式插入到對應的節點中
defineApp.styleInject = (parentNode) => {
${cssChunksStr}.forEach((css) => {
// import.meta.url 讓路徑保持正確,中括號取值避免被 rollup 轉換掉
const link = createLink(new URL(css, import.meta['url']));
parentNode.prepend(link);
});
};

export default defineApp;
`,
});
}


插件需要應用入口配合導出一個 styleInject方法提供樣式插入,我們通過封裝入口方法得以解決。

封裝一個方法給應用入口調用:

export function defineMicroApp(callback) {
const defineApp = (container) => {
const appConfig = callback(container);
// 處理樣式局部插入
const mountFn = appConfig.mount;
// 獲取到插件中的方法
const inject = defineApp.styleInject;
if (mountFn && inject) {
appConfig.mount = (props) => {
mountFn(props);
// 裝載完畢后,插入樣式
inject(container);
};
}
return appConfig;
};

return defineApp;
}


現在 build 之后會生成一個不帶 hash 的 main.js 文件,主應用可以正常加載打包后的資源了。

進一步優化,main.js 的壓縮混淆,可以用 Vite 導出 transformWithEsbuild 進行編譯:

const result = await transformWithEsbuild(customCode, 'main.js', {
minify: true,
});

this.emitFile({
fileName: 'main.js',
type: 'asset',
source: result.code,
});


子應用路徑問題

之前我們需要手動添加 new URL(image, import.meta.url) 來修復子應用路徑問題。通過 transform 鉤子自動處理該邏輯。

在這個插件之前,Vite 會將所有的資源文件轉換為路徑

import logo from './logo.svg';

// 轉換為:

export default '/src/logo.svg';


因此,我們只需要將 export default "資源路徑" 替換為 export default new URL("資源路徑", import.meta['url']).href 就可以了。

const imagesRE = new RegExp(`\\.(png|webp|jpg|gif|jpeg|tiff|svg|bmp)($|\\?)`);

transform(code, id) {
// 修正圖片資源使用絕對地址
if (imagesRE.test(id)) {
return {
code: code.replace(
/(export\s+default)\s+(".+")/,
`$1 new URL($2, import.meta['url']).href`
),
map: null,
};
}
return undefined;
},


完成,一個比較完善的 Vite 微應用方案由此而生。

看看效果:

更多

有了插件,可以發揮出意想不到的事情。本微前端方案沒有實現以下的隔離方式,不保證后續會實現,大家可以發揮更多的想象力。

CSS 樣式隔離

通過插件將主應用節點中的 id 添加并修改CSS

.name {
color: red;
}

/* 轉換為 */

#id .name {
color: red;
}


但前提是需要為每個 設置一個唯一的 id。并且樣式性能會受到影響,CSSModules 方案會更好。

JS 沙箱

雖然在 ESM 中做運行時沙箱目前沒有現成的方案,但運行時沙箱性能非常差。換個思路,可以從編譯時沙箱入手。用 transform 鉤子將應用所有的 window 轉譯為沙箱fakeWindow,從而達到隔離效果。

代碼示例

大家可以 clone 下來學習

插件倉庫:https://github.com/MinJieLiu/micro-app/tree/main/packages/micro-vite-plugin

微前端示例:https://github.com/MinJieLiu/micro-app-demo


責任編輯:武曉燕 來源: 前端星辰
相關推薦

2022-01-17 11:41:50

前端Vite組件

2022-05-09 09:28:04

Vite前端開發

2024-03-06 11:14:13

ViteReact微前端

2020-05-06 09:25:10

微前端qiankun架構

2024-09-23 00:00:10

2020-09-22 12:20:23

前端架構插件

2018-07-10 15:30:42

Go前端更新

2022-02-14 14:34:10

Next.js路由系統

2022-05-12 11:41:16

開發框架程序

2021-06-22 06:52:46

Vite 插件機制Rollup

2024-11-29 08:35:38

2022-07-13 09:01:17

前端開發文件處理庫

2022-08-10 10:32:47

編程實踐

2017-06-02 10:25:26

Java異常處理

2019-03-25 13:12:59

前端開發編程

2022-07-27 22:56:45

前端應用緩存qiankun

2017-09-12 10:50:55

前端SDK開發

2023-12-29 09:04:01

前端文件處理庫PDF.js

2022-10-17 15:21:18

2020-10-18 12:00:27

前端開發架構
點贊
收藏

51CTO技術棧公眾號

午夜激情综合网| 成人综合婷婷国产精品久久蜜臀 | 精品久久五月天| 欧美另类高清视频在线| 中文字幕无线码一区| 欧美在线资源| 亚洲精品中文字幕女同| www.偷拍.com| 日韩av大片站长工具| 亚洲欧美日韩中文播放| 欧美激情论坛| 亚洲免费国产视频| 日本成人超碰在线观看| 久久久久久久久久久人体| 谁有免费的黄色网址| 中文字幕一区二区三区四区久久| 欧洲生活片亚洲生活在线观看| 精品视频在线观看一区二区| 国产无套粉嫩白浆在线2022年 | 国产欧美日韩高清| 日韩高清精品免费观看| 91九色精品| 亚洲欧美日韩成人| 日本道中文字幕| 精品国产乱码一区二区三区 | 日韩理论片一区二区| 久久综合九色欧美狠狠| 亚洲免费一级片| 精品在线一区二区| 国产精品美女久久| 欧产日产国产69| 亚洲高清网站| 欧美精品成人在线| 俄罗斯毛片基地| 亚州av一区| 亚洲激情在线观看视频免费| 中文写幕一区二区三区免费观成熟| 日本肉肉一区| 91国在线观看| 青青在线免费观看视频| 午夜裸体女人视频网站在线观看| 亚洲一区二区三区四区不卡| 欧美中文字幕一区| 色综合影院在线观看| 色播色播色播色播色播在线| 成人av午夜电影| 成人片在线免费看| 亚洲精品一区二区口爆| 国产传媒久久文化传媒| 91美女高潮出水| 91在线公开视频| 麻豆精品一二三| 国产欧美一区二区| 国产又粗又猛又黄又爽无遮挡| 久久99久久精品| 91久久久久久久久| 国产视频一二三四区| 国产一区二区伦理片| 亚洲一区二区三区毛片| 精品国产九九九| 国产成人欧美日韩在线电影| 国产精品一级久久久| 色婷婷av一区二区三区之e本道| heyzo一本久久综合| 久久99精品国产99久久| 水莓100在线视频| 久久精品免视看| 亚洲一区尤物| 中文在线手机av| 午夜免费久久看| 精品99在线视频| 嫩草伊人久久精品少妇av杨幂| 欧美午夜片在线看| 日韩视频在线观看一区二区三区| 免费观看亚洲天堂| 亚洲精品一区二区三区影院| 右手影院亚洲欧美| 日韩av在线播放网址| 久久综合久久八八| xxxx 国产| 久久久久一区| 成人亚洲综合色就1024| 天天综合天天色| 欧美高清在线一区二区| 一级性生活视频| 欧美三级网址| 日韩一区二区在线播放| free性中国hd国语露脸| 国产免费无码一区二区视频 | 亚洲人成在线观看| 手机在线免费看片| 99热这里只有精品8| 国产精品日韩欧美大师| 精品国产无码一区二区| 久久久不卡网国产精品一区| 手机成人av在线| 天堂8中文在线最新版在线| 欧美视频完全免费看| 99热这里只有精品2| 国产91久久精品一区二区| 久久久999精品视频| 五月天婷婷激情| 国产一区二区三区免费播放| 欧美影视一区二区| 国产羞羞视频在线播放| 欧美三级乱人伦电影| av黄色一级片| 亚洲香蕉av| 国产91色在线|| 丰满人妻一区二区三区无码av| 欧美激情一区在线观看| 国产欧美日韩小视频| japansex久久高清精品| 国产亚洲xxx| 国产性xxxx高清| 国产老女人精品毛片久久| 欧美在线播放一区二区| 国产在线精彩视频| 欧美成人免费网站| 极品色av影院| 免费亚洲电影在线| 欧美日韩国产精品一卡| 日本蜜桃在线观看视频| 屁屁影院国产第一页| 日本一本在线免费福利| 欧美日韩三级视频| 中文幕无线码中文字蜜桃| 午夜精品偷拍| 国产欧美在线看| 国产精品视频一区二区久久| 精品久久久久久久中文字幕 | 日韩午夜电影免费看| 国产丝袜高跟一区| 国产无遮挡免费视频| 国产成人午夜电影网| japanese在线播放| 激情五月综合婷婷| 久久精品国产2020观看福利| 中文字幕永久免费视频| 国产偷v国产偷v亚洲高清| 91免费视频网站在线观看| 青青草原在线亚洲| 88xx成人精品| 午夜在线视频免费| 精品成人久久av| 欧洲一级黄色片| 亚洲午夜视频| 国产精品免费一区二区三区在线观看 | 国产69精品久久久久9999人| 中文字幕亚洲一区在线观看| 波多野结衣网站| 久久久久久久电影| 久久精品免费网站| 99tv成人| 亚洲一区二区三区四区视频| www.久久ai| 精品捆绑美女sm三区| 国产性70yerg老太| www.在线成人| www国产黄色| 欧美日韩有码| 成人av资源在线播放| 最好看的中文字幕| 日韩理论在线| 96精品久久久久中文字幕| 18+视频在线观看| 亚洲国产成人av在线| 日韩精品视频播放| 久久久久高清精品| 国产无遮挡猛进猛出免费软件 | 妺妺窝人体色www看人体| 91精品国产乱码久久久竹菊| 91av国产在线| 自拍视频在线网| 日韩一区二区在线看| 国产精品黄色大片| 国产精品无码永久免费888| 亚洲精品中文字幕乱码无线| 99热免费精品| 伊人色综合影院| a级日韩大片| 国产精品成人一区二区| 国产原厂视频在线观看| 亚洲国产精品福利| 在线免费av片| 亚洲电影一区二区三区| 法国空姐电影在线观看| 国产精品1区2区| 啊啊啊一区二区| 欧美独立站高清久久| 97在线中文字幕| 欧美××××黑人××性爽 | 国产成人免费视频| 黄色片视频在线播放| 88国产精品视频一区二区三区| 精品久久久久久一区二区里番| 成人涩涩视频| 久久久久久69| 日本视频在线播放| 日韩精品视频在线免费观看| 91麻豆一区二区| 五月天亚洲精品| 夫妻性生活毛片| 国产香蕉久久精品综合网| 亚洲精品久久久久久| 日韩av高清在线观看| 日韩精品在线中文字幕| 亚欧美无遮挡hd高清在线视频| 美乳视频一区二区| 澳门精品久久国产| 91九色国产视频| 国产成人精品一区二区三区免费| 26uuu国产精品视频| 亚洲第一图区| 久久亚洲一区二区三区四区五区高| 你懂得在线网址| 亚洲成色999久久网站| 99久久久国产精品无码网爆| 欧美在线观看你懂的| 久久国产精品系列| 亚洲一区二区三区四区在线免费观看| 国产探花视频在线| 久久毛片高清国产| 波多野结衣一二三区| 国产成人午夜精品5599| 99精品视频免费版的特色功能| 美女在线一区二区| 日本女优爱爱视频| 午夜在线播放视频欧美| 男人的天堂狠狠干| 国户精品久久久久久久久久久不卡| 伊人久久大香线蕉成人综合网| 日韩毛片视频| 一区二区三区久久网| 欧美日韩中字| 四虎永久在线精品免费一区二区| 视频一区中文| 日韩av大全| 日韩电影二区| 一区二区三区电影| 91精品国产成人观看| 大桥未久一区二区三区| 婷婷综合在线| 亚洲五码在线观看视频| 牛夜精品久久久久久久99黑人| 99热这里只有精品7| 2023国产精品久久久精品双| 2021狠狠干| 欧美日韩国产探花| 欧美又粗又长又爽做受| 最新日韩av| 91九色在线观看视频| 日韩亚洲国产欧美| 激情五月开心婷婷| 日韩经典一区二区| 日本肉体xxxx裸体xxx免费| 免费成人在线观看| 免费成年人高清视频| 国产激情91久久精品导航 | 性色av一区二区三区红粉影视| 波多野结衣中文字幕久久| 97碰碰碰免费色视频| 黄色亚洲网站| 国产在线精品播放| 最新国产精品精品视频| 精品久久久久久一区二区里番| 九九精品久久| 亚洲自拍偷拍二区| 中文字幕一区二区三三| 精品无码国模私拍视频| 国产农村妇女精品一二区| 成人黄色一区二区| 国产一区二区三区在线观看免费| 亚洲成人福利视频| 久久综合精品国产一区二区三区| 永久免费毛片在线观看| 亚洲免费资源在线播放| 国产无遮挡又黄又爽| 91成人看片片| www男人的天堂| 亚洲奶大毛多的老太婆| 免费a在线看| 8050国产精品久久久久久| 素人一区二区三区| 国产精品免费一区二区三区观看| 精品视频久久| 激情五月六月婷婷| 久久一区精品| 2025中文字幕| 国产欧美精品一区二区三区四区 | 激情亚洲成人| 蜜臀av免费观看| 99这里只有久久精品视频| 精品视频第一页| 婷婷综合久久一区二区三区| 91国内精品久久久| 国产视频一区在线| 亚洲91av| 国产欧美日韩中文字幕在线| 欧美一区 二区| 国产精品夜夜夜爽张柏芝| 亚洲永久在线| 色哟哟网站在线观看| 中文字幕欧美三区| 青青操免费在线视频| 日韩一区二区免费高清| 在线视频91p| 日本高清久久天堂| 成人av影音| 黄色一级视频播放| 日本在线不卡一区| 亚洲成人日韩在线| 亚洲大型综合色站| 国产普通话bbwbbwbbw| 中文字幕不卡av| 超碰超碰人人人人精品| 国产精品初高中精品久久| 91九色精品国产一区二区| 天天爱天天操天天干| 91免费视频网| 日韩精品一区二区三区国语自制| 日韩一区二区免费在线观看| 男人天堂手机在线| 国产精品色婷婷视频| 国产精品亚洲人成在99www| 久草视频国产在线| 18视频免费网址在线观看| 在线播放国产精品| 中国字幕a在线看韩国电影| 国产精品18毛片一区二区| 久久久久久久久丰满| 污网站在线免费| 日本一二三不卡| 国产成人av免费| 国产午夜精品一区理论片飘花 | 中文日本在线观看| 国产精品欧美一区二区三区奶水| 九九在线高清精品视频| 日本精品www| 久久人人97超碰com| 少妇高潮av久久久久久| 日韩精品中文字| 一二三四视频在线中文| 免费精品视频一区二区三区| 亚洲看片一区| 国产色视频一区二区三区qq号| 欧美三级免费观看| 毛片网站在线| 国产精品视频网站| 欧美高清视频在线观看mv| 日本免费色视频| 一区二区三区高清不卡| 亚洲狼人综合网| 18久久久久久| 国内精品伊人久久久| 国产又猛又黄的视频| 亚洲欧洲三级电影| 99国产精品欲| 久久久免费观看| 亚洲人成精品久久久| 少妇激情一区二区三区| 国产精品看片你懂得| 国产精品一区二区免费视频| 欧美日本中文字幕| 欧美黄色影院| 黄色免费网址大全| 亚洲美女在线国产| 十八禁一区二区三区| 国产精品91免费在线| 91亚洲国产成人久久精品| avtt中文字幕| 色狠狠av一区二区三区| 麻豆视频在线观看免费| 成人情视频高清免费观看电影| 亚洲欧美日韩精品一区二区| 一级黄色毛毛片| 日韩精品在线一区二区| 中文在线免费视频| 一级二级三级欧美| 成人av资源网站| 久草热在线观看| 欧美激情欧美激情在线五月| 婷婷综合电影| 波多野结衣免费观看| 黑人巨大精品欧美一区二区一视频| 91在线直播| 极品尤物一区二区三区| 麻豆精品一二三| 日本一级一片免费视频| 色老头一区二区三区| 精品精品国产三级a∨在线| 日本xxxx黄色| 午夜一区二区三区在线观看| 老司机精品影院| 久久精品国产一区二区三区日韩| 激情六月婷婷久久| 天码人妻一区二区三区在线看| 欧美精品在线观看| 精品国产一区二区三区四区 | 国模视频一区二区|