日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
兩個簡單的自定義插件,探究Vite的插件機制

Vite 插件機制

Vite 的插件機制是基于 Rollup 的插件機制實現(xiàn)的,但是又進行了一些擴展。Vite 的插件機制是通過鉤子函數(shù)實現(xiàn)的,當 Vite 運行時,會通過鉤子函數(shù)調用插件中的方法,插件可以在這些方法中干預 Vite 的構建過程。

創(chuàng)新互聯(lián)是一家成都網站制作、網站建設,提供網頁設計,網站設計,網站制作,建網站,按需求定制設計,網站開發(fā)公司,從2013年創(chuàng)立是互聯(lián)行業(yè)建設者,服務者。以提升客戶品牌價值為核心業(yè)務,全程參與項目的網站策劃設計制作,前端開發(fā),后臺程序制作以及后期項目運營并提出專業(yè)建議和思路。

我們主要討論插件的機制,Api詳情請看官網介紹

通用的鉤子:https://cn.vitejs.dev/guide/api-plugin.html#universal-hooks

Vite 獨有的鉤子:https://cn.vitejs.dev/guide/api-plugin.html#vite-specific-hooks

下面我們看看插件的原理。

Rollup 插件機制

Rollup 的插件機制實現(xiàn)主要基于兩點:

  • Rollup 維護了各個插件接口的 Hook 列表,插件可以向這些列表中添加回調函數(shù)。
  • 在執(zhí)行對應過程時,Rollup 會依次觸發(fā)這些 Hook 列表中的回調函數(shù)。
const hookLists = {
  load: [] // load hook 列表
}

function addHook(hookName, hook) {
  hookLists[hookName].push(hook)  // 向 hook 列表中添加回調函數(shù)
}

function load(id) {
  for (const hook of hookLists.load) { // 觸發(fā)所有 load 鉤子函數(shù)
    const result = hook(id)  // 調用鉤子函數(shù)
    if (result) return result  // 使用第一個結果并返回
  }
}

插件可以通過 Rollup 提供的 addHook 方法相對應的 Hook 列表中添加回調函數(shù):

export function myPlugin() {
  addHook('load', id => {  // 向 load 列表添加回調函數(shù)
    // ...
  })
}

Vite 的巧妙之處

Vite 主要將用戶插件排序,然后和內置的插件配置合并,傳遞給了 Rollup 打包。

關鍵的部分源碼如下:

// vite/node/config.ts
export async function resolveConfig() {
  
  // ...
  
  // resolve plugins
  const rawUserPlugins = (
    (await asyncFlatten(config.plugins || [])) as Plugin[]
  ).filter(filterPlugin)

  const [prePlugins, normalPlugins, postPlugins] =
    sortUserPlugins(rawUserPlugins)
  
  // run config hooks
  const userPlugins = [...prePlugins, ...normalPlugins, ...postPlugins]
  
  // ...
}
// vite/node/build.ts 
export async function build() {

  const config = await resolveConfig(
    inlineConfig,
    'build',
    'production',
    'production',
  )
  
  //...
  
  const plugins = (
    ssr ? config.plugins.map((p) => injectSsrFlagToHooks(p)) : config.plugins
  ) as Plugin[]
  
  const rollupOptions: RollupOptions = {
    context: 'globalThis',
    preserveEntrySignatures: ssr
      ? 'allow-extension'
      : libOptions
      ? 'strict'
      : false,
    cache: config.build.watch ? undefined : false,
    ...options.rollupOptions,
    input,
    plugins,
    external,
    onwarn(warning, warn) {
      onRollupWarning(warning, warn, config)
    },
  }
  
  // ...

  // write or generate files with rollup
  const { rollup } = await import('rollup')
  bundle = await rollup(rollupOptions)
  
  // ...
}

Vite 使用插件時,需要將插件放入 plugins 的數(shù)組中如下:

插件配置

實踐得真知

接下來我們自定義幾個插件,感受下 Vite 的插件機制。

寫這幾個插件是為了理解插件機制,官方已經提供了相關的配置或者現(xiàn)成的插件

自動切換端口,默認8080

Vite 默認的端口不是 8080了,有點不太習慣,所以自己寫個插件自動切換端口。

import net from 'net'

function getNextPort(port: number) {
  return new Promise((resolve) => {
    const server = net.createServer()
    server.unref()
    server.on('error', () => {
      resolve(getNextPort(port + 1))
    })
    server.listen(port, () => {
      server.close(() => {
        resolve(port)
      })
    })
  })
}

function autoSwitchPortPlugin() {
  let port = 8080

  return {
    name: 'auto-switch-port',
    async configResolved(config: any) {
      port = await getNextPort(port) as number
      config.server.port = port
    },
  }
}

export default autoSwitchPortPlugin

修改端口

為文件加上版本號

由于這個操作是轉換 index.html文件,所以需要使用專用鉤子transformIndexHtml

import { createHash } from "crypto"

export default function autoVersionPlugin() {
  return {
    name: 'auto-version',
    async transformIndexHtml(html: string) {
      const hash = createHash('md5').update(html).digest('hex')
      return html.replace(/(src|href)="(.*?)"/g, `$1="$2?v=${hash}"`)
    },
  }
}

添加版本號

總結

Vite 插件機制主要在整個構建過程的不同時機暴露出鉤子函數(shù)供開發(fā)者靈活自定義構建過程。所以理解構建流程,才能更好的開發(fā)一個優(yōu)秀的插件。


分享名稱:兩個簡單的自定義插件,探究Vite的插件機制
文章路徑:http://m.5511xx.com/article/cogdesh.html