自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

兩個(gè)簡單的自定義插件,探究Vite的插件機(jī)制

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

?? Vite 插件機(jī)制

Vite 的插件機(jī)制是基于 Rollup 的插件機(jī)制實(shí)現(xiàn)的,但是又進(jìn)行了一些擴(kuò)展。Vite 的插件機(jī)制是通過鉤子函數(shù)實(shí)現(xiàn)的,當(dāng) Vite 運(yùn)行時(shí),會通過鉤子函數(shù)調(diào)用插件中的方法,插件可以在這些方法中干預(yù) Vite 的構(gòu)建過程。

我們主要討論插件的機(jī)制,Api詳情請看官網(wǎng)介紹

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

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

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

?? Rollup 插件機(jī)制

Rollup 的插件機(jī)制實(shí)現(xiàn)主要基于兩點(diǎn):

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

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

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

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

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

?? Vite 的巧妙之處

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

關(guān)鍵的部分源碼如下:

// 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 使用插件時(shí),需要將插件放入 plugins 的數(shù)組中如下:

圖片

插件配置

?? 實(shí)踐得真知

接下來我們自定義幾個(gè)插件,感受下 Vite 的插件機(jī)制。

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

?? 自動切換端口,默認(rèn)8080

Vite 默認(rèn)的端口不是 8080了,有點(diǎn)不太習(xí)慣,所以自己寫個(gè)插件自動切換端口。

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

圖片

修改端口

?? 為文件加上版本號

由于這個(gè)操作是轉(zhuǎn)換 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}"`)
    },
  }
}

圖片

添加版本號

?? 總結(jié)

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

責(zé)任編輯:武曉燕 來源: 萌萌噠草頭將軍
相關(guān)推薦

2021-06-22 06:52:46

Vite 插件機(jī)制Rollup

2011-06-09 17:26:17

Qt 插件 API

2024-07-17 09:23:58

Vite插件機(jī)制

2009-12-11 10:29:03

PHP插件機(jī)制

2010-09-08 14:39:35

2023-11-07 10:19:08

2021-12-28 15:38:46

Traefik中間件插件

2012-11-19 11:07:42

IBMdw

2023-03-31 07:17:16

2022-01-14 09:17:13

PythonAPISIX插件

2011-01-21 15:02:14

jQuerywebJavaScript

2021-12-31 08:43:45

插件KubeScheduler

2010-09-01 08:35:07

Visual Stud

2015-01-14 15:06:48

定義相機(jī)

2011-08-25 11:44:21

LUA腳本魔獸世界

2020-05-22 09:10:10

前端框架插件

2021-03-04 08:19:29

插件機(jī)制代碼

2019-12-19 08:56:21

MybatisSQL執(zhí)行器

2021-07-26 09:00:08

ReactHooks 項(xiàng)目

2020-09-18 10:12:24

KotlinTCP網(wǎng)絡(luò)協(xié)議
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號