日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

淺析Vite插件機制,你學會了嗎?

來源: 責編: 時間:2024-07-19 08:03:22 665觀看
導讀前言對于Vite來說,它是基于esbuild與rollup雙引擎設計的,在開發階段使用esbuild進行依賴預構建,然后基于瀏覽器原生支持的ESM完成開發預覽,而在生產環境打包時,直接使用的rollup構建。那么在這種背景下,Vite的插件機制應該

前言

對于Vite來說,它是基于esbuild與rollup雙引擎設計的,在開發階段使用esbuild進行依賴預構建,然后基于瀏覽器原生支持的ESM完成開發預覽,而在生產環境打包時,直接使用的rollup構建。那么在這種背景下,Vite的插件機制應該如何設計?QFf28資訊網——每日最新資訊28at.com

在源碼中,我們能夠經常看到PluginContainer的身影,Vite正是通過它來模擬rollup的行為QFf28資訊網——每日最新資訊28at.com

圖片QFf28資訊網——每日最新資訊28at.com

pluginContainer

PluginContainer 的 實現 基于借鑒于 WMR 中的 rollup-plugin-container.js ,主要功能有兩個:QFf28資訊網——每日最新資訊28at.com

  • 管理插件的生命周期
  • 實現插件鉤子內部的 Context 上下文對象

插件生命周期

在開發階段,vite會模擬rollup的行為,所以插件的執行機制也與rollup相同QFf28資訊網——每日最新資訊28at.com

圖片圖片QFf28資訊網——每日最新資訊28at.com

  1. 調用 options 鉤子進行配置的轉換,得到處理后的配置對象。
  2. 調用buildStart鉤子,正式開始構建流程。
  3. 調用 resolveId 鉤子中解析文件路徑。(從 input 配置指定的入口文件開始)。
  4. 調用load鉤子加載模塊內容。
  5. 緊接著 Rollup 執行所有的 transform 鉤子來對模塊內容進行進行自定義的轉換(比如 babel 轉譯)
  6. Rollup 拿到最后的模塊內容,進行 AST 分析,得到所有的 import 內容,調用 moduleParsed 鉤子
  7. 直到所有的 import 都解析完畢,Rollup 執行buildEnd鉤子,Build 階段結束。

?QFf28資訊網——每日最新資訊28at.com

這里需要注意的是:在 vite 中由于 AST 分析是通過 esbuild 進行的,所有沒有模擬 moduleParsed 鉤子QFf28資訊網——每日最新資訊28at.com

傳遞上下文對象

上下文對象通過 Context 實現 PluginContext 接口定義,PluginContext 實際上是 Rollup 內部定義的類型,可以在源碼中看到 vite 實現了 Rollup 上下文對象QFf28資訊網——每日最新資訊28at.com

class Context implements PluginContext {  //... 具體實現}type PluginContext = Omit<  RollupPluginContext, // Rollup 定義插件上下文接口  // not documented  | 'cache'  // deprecated  | 'moduleIds'>

Context 上下文對象一共有 14 個核心方法,其中有 3 個方法是比較核心的方法QFf28資訊網——每日最新資訊28at.com

  • parse:使用 Rollup 的內部基于 SWC 的解析器將代碼解析為 AST
  • resolve:將相對路徑解析為絕對路徑,從而正確地處理模塊之間的引用
  • load:加載并解析與給定 ID 對應的模塊,并在提供的情況下附加附加的元信息到模塊

更多內容可以查看rollup文檔QFf28資訊網——每日最新資訊28at.com

rollup插件

rollup構建流程主要分為兩大類:build和output,build 階段主要負責創建模塊依賴圖,初始化各個模塊的 AST 以及模塊之間的依賴關系。output階段才是真正的打包構建過程QFf28資訊網——每日最新資訊28at.com

插件hook類型(構建階段)

通過構建流程rollup的hook類型可以分為:build hook和output hook兩大類QFf28資訊網——每日最新資訊28at.com

  • Build Hook即在Build階段執行的鉤子函數,在這個階段主要進行模塊代碼的轉換、AST 解析以及模塊依賴的解析,那么這個階段的 Hook 對于代碼的操作粒度一般為模塊級別,也就是單文件級別。
  • Ouput Hook(官方稱為Output Generation Hook),則主要進行代碼的打包,對于代碼而言,操作粒度一般為 chunk級別(一個 chunk 通常指很多文件打包到一起的產物)。

插件hook類型(執行方式)

除了上面這種分類,rollup插件還可以根據各自的執行方式來進行分類:QFf28資訊網——每日最新資訊28at.com

  • Build Hook即在Build階段執行的鉤子函數,在這個階段主要進行模塊代碼的轉換、AST 解析以及模塊依賴的解析,那么這個階段的 Hook 對于代碼的操作粒度一般為模塊級別,也就是單文件級別。
  • Ouput Hook(官方稱為Output Generation Hook),則主要進行代碼的打包,對于代碼而言,操作粒度一般為 chunk級別(一個 chunk 通常指很多文件打包到一起的產物)。

除了根據構建階段可以將 Rollup 插件進行分類,根據不同的 Hook 執行方式也會有不同的分類,主要包括Async、Sync、Parallel、Squential、First這五種。在后文中我們將接觸各種各樣的插件 Hook,但無論哪個 Hook 都離不開這五種執行方式。QFf28資訊網——每日最新資訊28at.com

1. Async & Sync

首先是Async和Sync鉤子函數,兩者其實是相對的,分別代表異步和同步的鉤子函數,這個很好理解。QFf28資訊網——每日最新資訊28at.com

2. Parallel

這里指并行的鉤子函數。如果有多個插件實現了這個鉤子的邏輯,一旦有鉤子函數是異步邏輯,則并發執行鉤子函數,不會等待當前鉤子完成(底層使用 Promise.all)。QFf28資訊網——每日最新資訊28at.com

比如對于Build階段的buildStart鉤子,它的執行時機其實是在構建剛開始的時候,各個插件可以在這個鉤子當中做一些狀態的初始化操作,但其實插件之間的操作并不是相互依賴的,也就是可以并發執行,從而提升構建性能。反之,對于需要依賴其他插件處理結果的情況就不適合用 Parallel 鉤子了,比如 transform。QFf28資訊網——每日最新資訊28at.com

3. Sequential

Sequential 指串行的鉤子函數。這種 Hook 往往適用于插件間處理結果相互依賴的情況,前一個插件 Hook 的返回值作為后續插件的入參,這種情況就需要等待前一個插件執行完 Hook,獲得其執行結果,然后才能進行下一個插件相應 Hook 的調用,如transform。QFf28資訊網——每日最新資訊28at.com

4. First

如果有多個插件實現了這個 Hook,那么 Hook 將依次運行,直到返回一個非 null 或非 undefined 的值為止。比較典型的 Hook 是 resolveId,一旦有插件的 resolveId 返回了一個路徑,將停止執行后續插件的 resolveId 邏輯。QFf28資訊網——每日最新資訊28at.com

通用hook

以下鉤子在服務器啟動時被調用:QFf28資訊網——每日最新資訊28at.com

  • options
  • buildStart

以下鉤子會在每個傳入模塊請求時被調用:QFf28資訊網——每日最新資訊28at.com

  • resolveId
  • load
  • transform

它們還有一個擴展的 options 參數,包含其他特定于 Vite 的屬性。QFf28資訊網——每日最新資訊28at.com

以下鉤子在服務器關閉時被調用:QFf28資訊網——每日最新資訊28at.com

  • buildEnd
  • closeBundle

請注意 moduleParsed 鉤子在開發中是 不會 被調用的,因為 Vite 為了性能會避免完整的 AST 解析。QFf28資訊網——每日最新資訊28at.com

output階段的hook(除了 closeBundle) 在開發中是 不會 被調用的。你可以認為 Vite 的開發服務器只調用了 rollup.rollup() 而沒有調用 bundle.generate()。QFf28資訊網——每日最新資訊28at.com

Vite 獨有hook

Vite 插件也可以提供鉤子來服務于特定的 Vite 目標。當然這些鉤子會被 Rollup 忽略。QFf28資訊網——每日最新資訊28at.com

config

在解析 Vite 配置前調用。鉤子接收原始用戶配置(命令行選項指定的會與配置文件合并)和一個描述配置環境的變量,包含正在使用的 mode 和 command。它可以返回一個將被深度合并到現有配置中的部分配置對象,或者直接改變配置(如果默認的合并不能達到預期的結果)。QFf28資訊網——每日最新資訊28at.com

// 返回部分配置(推薦)const partialConfigPlugin = () => ({  name: 'nanjiu-plugin',  config(config, { command }) {    console.log('config', config, command)  }})

圖片圖片QFf28資訊網——每日最新資訊28at.com

需要注意的是:用戶插件在運行這個鉤子之前會被解析,因此在 config 鉤子中注入其他插件不會有任何效果。QFf28資訊網——每日最新資訊28at.com

configResolved

在解析 Vite 配置后調用。使用這個鉤子讀取和存儲最終解析的配置。QFf28資訊網——每日最新資訊28at.com

const examplePlugin = () => {  let config  return {    name: 'read-config',    configResolved(resolvedConfig) {      // 存儲最終解析的配置      config = resolvedConfig    },    // 在其他鉤子中使用存儲的配置    transform(code, id) {      if (config.command === 'serve') {        // dev: 由開發服務器調用的插件      } else {        // build: 由 Rollup 調用的插件      }    },  }}

configureServer

是用于配置開發服務器的鉤子。最常見的用例是在內部 connect 應用程序中添加自定義中間件QFf28資訊網——每日最新資訊28at.com

const myPlugin = () => ({  name: 'configure-server',  configureServer(server) {    server.middlewares.use((req, res, next) => {      // 自定義請求處理...    })  },})

configurePreviewServer

與 configureServer 相同,但用于預覽服務器。configurePreviewServer 這個鉤子與 configureServer 類似,也是在其他中間件安裝前被調用。如果你想要在其他中間件 之后 安裝一個插件,你可以從 configurePreviewServer 返回一個函數,它將會在內部中間件被安裝之后再調用QFf28資訊網——每日最新資訊28at.com

const myPlugin = () => ({  name: 'configure-preview-server',  configurePreviewServer(server) {    // 返回一個鉤子,會在其他中間件安裝完成后調用    return () => {      server.middlewares.use((req, res, next) => {        // 自定義處理請求 ...      })    }  },})

transformIndexHtml

轉換 index.html 的專用鉤子。鉤子接收當前的 HTML 字符串和轉換上下文。上下文在開發期間暴露ViteDevServer實例,在構建期間暴露 Rollup 輸出的包。QFf28資訊網——每日最新資訊28at.com

這個鉤子可以是異步的,并且可以返回以下其中之一:QFf28資訊網——每日最新資訊28at.com

  • 經過轉換的 HTML 字符串
  • 注入到現有 HTML 中的標簽描述符對象數組({ tag, attrs, children })。每個標簽也可以指定它應該被注入到哪里(默認是在 <head> 之前)
  • 一個包含 { html, tags } 的對象

默認情況下 order 是 undefined,這個鉤子會在 HTML 被轉換后應用。為了注入一個應該通過 Vite 插件管道的腳本, order: 'pre' 指將在處理 HTML 之前應用。order: 'post' 是在所有未定義的 order 的鉤子函數被應用后才應用。QFf28資訊網——每日最新資訊28at.com

const htmlPlugin = () => {  return {    name: 'nanjiu-plugin',    transformIndexHtml(html) {      return html.replace(/<title>(.*?)<//title>/,                          `<title> nanjiu plugin </title>`)    },  }}

handleHotUpdate

執行自定義 HMR 更新處理。鉤子接收一個帶有以下簽名的上下文對象QFf28資訊網——每日最新資訊28at.com

interface HmrContext {  file: string  timestamp: number  modules: Array<ModuleNode>  read: () => string | Promise<string>  server: ViteDevServer}
  • modules 是受更改文件影響的模塊數組。它是一個數組,因為單個文件可能映射到多個服務模塊(例如 Vue 單文件組件)。
  • read 這是一個異步讀函數,它返回文件的內容。之所以這樣做,是因為在某些系統上,文件更改的回調函數可能會在編輯器完成文件更新之前過快地觸發,并 fs.readFile 直接會返回空內容。傳入的 read 函數規范了這種行為。
const hotPlugin = () => {  return {    name: 'nanjiu-plugin',    handleHotUpdate({ server, modules, timestamp}) {      console.log('handleHotUpdate', modules)    },  }}

當我修改App.vue文件時,modules可以獲取到如下信息:QFf28資訊網——每日最新資訊28at.com

圖片圖片QFf28資訊網——每日最新資訊28at.com

插件順序

一個 Vite 插件可以額外指定一個 enforce 屬性(類似于 webpack 加載器)來調整它的應用順序。enforce 的值可以是pre 或 post。解析后的插件將按照以下順序排列:QFf28資訊網——每日最新資訊28at.com

  • Alias
  • 帶有 enforce: 'pre' 的用戶插件
  • Vite 核心插件
  • 沒有 enforce 值的用戶插件
  • Vite 構建用的插件
  • 帶有 enforce: 'post' 的用戶插件
  • Vite 后置構建插件

請注意,這與鉤子的排序是分開的,鉤子的順序仍然會受到它們的 order 屬性的影響,這一點 和 Rollup 鉤子的表現一樣QFf28資訊網——每日最新資訊28at.com

總結

vite 在 開發環境中,會使用 createPluginContainer 方法創建插件容器,插件容器有兩個核心功能:管理插件生命周期、傳遞插件上下文QFf28資訊網——每日最新資訊28at.com

圖片圖片QFf28資訊網——每日最新資訊28at.com

QFf28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-101721-0.html淺析Vite插件機制,你學會了嗎?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 軟件版本號為什么那么奇怪?

下一篇: 基于Netty的自研流系統緩存實現挑戰:內存碎片與OOM困境

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
国产日本亚洲高清| 欧美日韩国产成人在线91| 欧美尤物巨大精品爽| 尤物yw午夜国产精品视频| 欧美午夜理伦三级在线观看| 久久天天躁狠狠躁夜夜av| 在线亚洲一区观看| 亚洲国产一区二区三区在线播 | 欧美电影免费| 欧美一区二区三区四区在线 | 99精品热视频| 亚洲国产高清一区二区三区| 国产人成一区二区三区影院| 欧美日韩视频一区二区| 欧美大成色www永久网站婷| 欧美日韩另类丝袜其他| 欧美国产专区| 欧美激情久久久久| 国产精品日韩一区二区| 国产精品理论片| 欧美午夜激情在线| 欧美性一区二区| 国产精品mm| 含羞草久久爱69一区| 国产一级揄自揄精品视频| 国产欧美一区二区精品秋霞影院 | 免费日韩精品中文字幕视频在线| 裸体丰满少妇做受久久99精品| 欧美一区二区三区四区在线| 欧美激情精品久久久久久黑人| 国产精品一区一区三区| 国产一区二区三区精品欧美日韩一区二区三区 | 国产精品婷婷| 国产免费成人在线视频| 国产日产欧产精品推荐色| 国产视频一区二区三区在线观看| 国产亚洲欧美一区二区三区| 99亚洲精品| 中文亚洲欧美| 奶水喷射视频一区| 免费在线成人| 国产日韩欧美夫妻视频在线观看| 日韩视频不卡中文| 99热免费精品| 亚洲一区尤物| 欧美在线三区| 欧美亚一区二区| 亚洲欧洲一区二区在线播放| 日韩视频免费看| 亚洲欧美日韩一区在线观看| 午夜日韩电影| 久久亚洲一区| 欧美激情第9页| 欧美日本一道本| 亚洲第一精品在线| 亚洲精品1区2区| 久久精品视频免费| 久久在线91| 欧美日韩福利视频| 国产精品久久久久久久久久ktv| 国产精品欧美久久| 国内精品久久久| 国产欧美视频在线观看| 亚洲大胆在线| 欧美韩国一区| 欧美日韩国产综合新一区| 在线精品观看| 久久久久高清| 欧美日韩国产片| 亚洲国产国产亚洲一二三| 久久久国产91| 欧美日韩国产经典色站一区二区三区| 亚洲大胆av| 美女精品在线| 国产精品尤物福利片在线观看| 影视先锋久久| 久久裸体视频| 国产精品一区二区三区四区五区| 一区二区三区产品免费精品久久75| 亚洲欧美久久久| 国产精品久久777777毛茸茸| 激情久久久久久久| 99国内精品| 欧美日韩免费观看一区二区三区 | 欧美第一黄网免费网站| 国产精品推荐精品| 性欧美精品高清| 欧美激情视频在线播放 | 国产视频一区在线| 亚洲美女视频在线免费观看| 欧美黄污视频| 99pao成人国产永久免费视频| 欧美激情1区| 亚洲最新在线视频| 国产精品久久久久久久久婷婷 | 久久久99爱| **欧美日韩vr在线| 欧美高清在线一区| 一区二区三区欧美亚洲| 国产精品久久久一本精品| 欧美一二三区精品| 一区二区三区在线观看视频 | 欧美激情一区二区三区高清视频| 国产亚洲一区在线播放| 午夜在线成人av| 欧美久久一区| 免费观看日韩av| 99精品国产热久久91蜜凸| 欧美日韩一区综合| 亚洲第一网站| 国产精品天天看| 欧美日韩亚洲视频| 欧美人在线视频| 国产精品高清在线观看| 欧美午夜视频| 一区二区三区.www| 欧美日韩视频在线| 亚洲啪啪91| 精品99一区二区| 老鸭窝亚洲一区二区三区| 在线观看日韩专区| 国产一区二区三区在线观看精品| 欧美一区激情| 精品69视频一区二区三区| 久久国产精品一区二区三区四区| 欧美中文日韩| 亚洲欧美日韩成人| 国产精品国产馆在线真实露脸 | 一区二区三区在线视频观看| 欧美理论电影在线播放| 国产日韩在线亚洲字幕中文| 亚洲黄色一区二区三区| 亚洲国产专区校园欧美| 午夜在线成人av| 欧美人成网站| 亚洲欧洲日本专区| 国产美女一区二区| 午夜精品久久久久久久男人的天堂 | 午夜影视日本亚洲欧洲精品| 激情一区二区| 欧美日韩在线高清| 久久精品国产一区二区三| 久久精品国产亚洲高清剧情介绍| 欧美日韩国产综合一区二区| 国产精品高潮久久| 久久gogo国模啪啪人体图| 欧美一区深夜视频| 欧美成人亚洲成人日韩成人| 亚洲人体影院| 亚洲欧美日韩人成在线播放| 欧美一区国产在线| 国产精品vip| 久久夜色撩人精品| 亚洲国产影院| 国产美女精品视频| 欧美日韩高清在线播放| 欧美一区二区三区视频| 99国内精品久久| 在线看不卡av| 国产欧美日韩高清| 欧美日韩国产综合新一区| 久久视频一区二区| 亚洲日本无吗高清不卡| 国产夜色精品一区二区av| 久热这里只精品99re8久| 亚洲午夜羞羞片| 国产精品制服诱惑| 欧美日韩国产探花| 免费成人av资源网| 日韩视频在线观看| 伊人成年综合电影网| 欧美国产欧美综合| 久久精品网址| 亚洲欧美综合另类中字| 一区二区三区四区五区精品| 亚洲激情欧美| 亚洲第一区色| 欧美无乱码久久久免费午夜一区| 午夜激情一区| 一区二区日韩精品| 国产模特精品视频久久久久| 欧美日韩国产电影| 欧美精品一区二区三区四区| 免费欧美在线| 麻豆久久婷婷| 中日韩美女免费视频网址在线观看 | 亚洲国产日本| 在线观看日产精品| 国内精品一区二区| 国产一区二区成人| 国产欧美亚洲精品| 国产伦精品一区二区三区高清 | 国产欧美日韩专区发布| 欧美午夜精品久久久久久孕妇| 欧美日韩1区| 久久国产毛片| 亚洲美女网站| 国产亚洲欧美色| 国产精品揄拍500视频| 欧美午夜免费影院| 欧美日韩中文在线观看| 欧美日韩在线高清| 国产精品久久久久久久9999 | 亚洲精品中文在线|