Skip to content

Commit

Permalink
chore: add PluginWithRequiredHook type & extract getHookHandler f…
Browse files Browse the repository at this point in the history
…unction (#14845)
  • Loading branch information
lzt1008 authored Nov 2, 2023
1 parent 66caef3 commit 997f2d5
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 35 deletions.
7 changes: 4 additions & 3 deletions packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import { resolveChokidarOptions } from './watch'
import { completeSystemWrapPlugin } from './plugins/completeSystemWrap'
import { mergeConfig } from './publicUtils'
import { webWorkerPostPlugin } from './plugins/worker'
import { getHookHandler } from './plugins'

export interface BuildOptions {
/**
Expand Down Expand Up @@ -959,7 +960,7 @@ function injectSsrFlagToHooks(plugin: Plugin): Plugin {
function wrapSsrResolveId(hook?: Plugin['resolveId']): Plugin['resolveId'] {
if (!hook) return

const fn = 'handler' in hook ? hook.handler : hook
const fn = getHookHandler(hook)
const handler: Plugin['resolveId'] = function (id, importer, options) {
return fn.call(this, id, importer, injectSsrFlag(options))
}
Expand All @@ -977,7 +978,7 @@ function wrapSsrResolveId(hook?: Plugin['resolveId']): Plugin['resolveId'] {
function wrapSsrLoad(hook?: Plugin['load']): Plugin['load'] {
if (!hook) return

const fn = 'handler' in hook ? hook.handler : hook
const fn = getHookHandler(hook)
const handler: Plugin['load'] = function (id, ...args) {
// @ts-expect-error: Receiving options param to be future-proof if Rollup adds it
return fn.call(this, id, injectSsrFlag(args[0]))
Expand All @@ -996,7 +997,7 @@ function wrapSsrLoad(hook?: Plugin['load']): Plugin['load'] {
function wrapSsrTransform(hook?: Plugin['transform']): Plugin['transform'] {
if (!hook) return

const fn = 'handler' in hook ? hook.handler : hook
const fn = getHookHandler(hook)
const handler: Plugin['transform'] = function (code, importer, ...args) {
// @ts-expect-error: Receiving options param to be future-proof if Rollup adds it
return fn.call(this, code, importer, injectSsrFlag(args[0]))
Expand Down
9 changes: 6 additions & 3 deletions packages/vite/src/node/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { Alias, AliasOptions } from 'dep-types/alias'
import aliasPlugin from '@rollup/plugin-alias'
import { build } from 'esbuild'
import type { RollupOptions } from 'rollup'
import type { HookHandler, Plugin } from './plugin'
import type { HookHandler, Plugin, PluginWithRequiredHook } from './plugin'
import type {
BuildOptions,
RenderBuiltAssetUrl,
Expand Down Expand Up @@ -43,6 +43,7 @@ import {
} from './utils'
import {
createPluginHookUtils,
getHookHandler,
getSortedPluginsByHook,
resolvePlugins,
} from './plugins'
Expand Down Expand Up @@ -383,7 +384,9 @@ export type ResolvedConfig = Readonly<
>

export interface PluginHookUtils {
getSortedPlugins: (hookName: keyof Plugin) => Plugin[]
getSortedPlugins: <K extends keyof Plugin>(
hookName: K,
) => PluginWithRequiredHook<K>[]
getSortedPluginHooks: <K extends keyof Plugin>(
hookName: K,
) => NonNullable<HookHandler<Plugin[K]>>[]
Expand Down Expand Up @@ -1207,7 +1210,7 @@ async function runConfigHook(

for (const p of getSortedPluginsByHook('config', plugins)) {
const hook = p.config
const handler = hook && 'handler' in hook ? hook.handler : hook
const handler = getHookHandler(hook)
if (handler) {
const res = await handler(conf, configEnv)
if (res) {
Expand Down
4 changes: 4 additions & 0 deletions packages/vite/src/node/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,7 @@ export interface Plugin<A = any> extends RollupPlugin<A> {
}

export type HookHandler<T> = T extends ObjectHook<infer H> ? H : T

export type PluginWithRequiredHook<K extends keyof Plugin> = Plugin & {
[P in K]: NonNullable<Plugin[P]>
}
33 changes: 18 additions & 15 deletions packages/vite/src/node/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import aliasPlugin from '@rollup/plugin-alias'
import type { ObjectHook } from 'rollup'
import type { PluginHookUtils, ResolvedConfig } from '../config'
import { isDepsOptimizerEnabled } from '../config'
import type { HookHandler, Plugin } from '../plugin'
import type { HookHandler, Plugin, PluginWithRequiredHook } from '../plugin'
import { getDepsOptimizer } from '../optimizer'
import { shouldExternalizeForSSR } from '../ssr/ssrExternal'
import { watchPackageDataPlugin } from '../packages'
Expand Down Expand Up @@ -106,9 +107,11 @@ export function createPluginHookUtils(
): PluginHookUtils {
// sort plugins per hook
const sortedPluginsCache = new Map<keyof Plugin, Plugin[]>()
function getSortedPlugins(hookName: keyof Plugin): Plugin[] {
function getSortedPlugins<K extends keyof Plugin>(
hookName: K,
): PluginWithRequiredHook<K>[] {
if (sortedPluginsCache.has(hookName))
return sortedPluginsCache.get(hookName)!
return sortedPluginsCache.get(hookName) as PluginWithRequiredHook<K>[]
const sorted = getSortedPluginsByHook(hookName, plugins)
sortedPluginsCache.set(hookName, sorted)
return sorted
Expand All @@ -117,14 +120,7 @@ export function createPluginHookUtils(
hookName: K,
): NonNullable<HookHandler<Plugin[K]>>[] {
const plugins = getSortedPlugins(hookName)
return plugins
.map((p) => {
const hook = p[hookName]!
return typeof hook === 'object' && 'handler' in hook
? hook.handler
: hook
})
.filter(Boolean)
return plugins.map((p) => getHookHandler(p[hookName])).filter(Boolean)
}

return {
Expand All @@ -133,10 +129,10 @@ export function createPluginHookUtils(
}
}

export function getSortedPluginsByHook(
hookName: keyof Plugin,
export function getSortedPluginsByHook<K extends keyof Plugin>(
hookName: K,
plugins: readonly Plugin[],
): Plugin[] {
): PluginWithRequiredHook<K>[] {
const pre: Plugin[] = []
const normal: Plugin[] = []
const post: Plugin[] = []
Expand All @@ -156,5 +152,12 @@ export function getSortedPluginsByHook(
normal.push(plugin)
}
}
return [...pre, ...normal, ...post]

return [...pre, ...normal, ...post] as PluginWithRequiredHook<K>[]
}

export function getHookHandler<T extends ObjectHook<Function>>(
hook: T,
): HookHandler<T> {
return (typeof hook === 'object' ? hook.handler : hook) as HookHandler<T>
}
20 changes: 6 additions & 14 deletions packages/vite/src/node/server/pluginContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ import {
unwrapId,
} from '../utils'
import type { ResolvedConfig } from '../config'
import { createPluginHookUtils } from '../plugins'
import { createPluginHookUtils, getHookHandler } from '../plugins'
import { buildErrorMessage } from './middlewares/error'
import type { ModuleGraph } from './moduleGraph'

Expand Down Expand Up @@ -217,9 +217,8 @@ export async function createPluginContainer(
// Don't throw here if closed, so buildEnd and closeBundle hooks can finish running
const hook = plugin[hookName]
if (!hook) continue
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore hook is not a primitive
const handler: Function = 'handler' in hook ? hook.handler : hook

const handler: Function = getHookHandler(hook)
if ((hook as { sequential?: boolean }).sequential) {
await Promise.all(parallelPromises)
parallelPromises.length = 0
Expand Down Expand Up @@ -654,10 +653,7 @@ export async function createPluginContainer(
ctx._activePlugin = plugin

const pluginResolveStart = debugPluginResolve ? performance.now() : 0
const handler =
'handler' in plugin.resolveId
? plugin.resolveId.handler
: plugin.resolveId
const handler = getHookHandler(plugin.resolveId)
const result = await handleHookPromise(
handler.call(ctx as any, rawId, importer, {
attributes: options?.attributes ?? {},
Expand Down Expand Up @@ -715,8 +711,7 @@ export async function createPluginContainer(
if (closed && !ssr) throwClosedServerError()
if (!plugin.load) continue
ctx._activePlugin = plugin
const handler =
'handler' in plugin.load ? plugin.load.handler : plugin.load
const handler = getHookHandler(plugin.load)
const result = await handleHookPromise(
handler.call(ctx as any, id, { ssr }),
)
Expand All @@ -743,10 +738,7 @@ export async function createPluginContainer(
ctx._activeCode = code
const start = debugPluginTransform ? performance.now() : 0
let result: TransformResult | string | undefined
const handler =
'handler' in plugin.transform
? plugin.transform.handler
: plugin.transform
const handler = getHookHandler(plugin.transform)
try {
result = await handleHookPromise(
handler.call(ctx as any, code, id, { ssr }),
Expand Down

0 comments on commit 997f2d5

Please sign in to comment.