Skip to content

Commit 757a92f

Browse files
authored
feat: support object style hooks (#9634)
1 parent aca6ac2 commit 757a92f

20 files changed

+398
-223
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
"prettier": "2.7.1",
7878
"prompts": "^2.4.2",
7979
"rimraf": "^3.0.2",
80-
"rollup": ">=2.75.6 <2.77.0 || ~2.77.0",
80+
"rollup": "~2.78.0",
8181
"semver": "^7.3.7",
8282
"simple-git-hooks": "^2.8.0",
8383
"tslib": "^2.4.0",

packages/plugin-vue/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"@jridgewell/gen-mapping": "^0.3.2",
4343
"@jridgewell/trace-mapping": "^0.3.15",
4444
"debug": "^4.3.4",
45-
"rollup": ">=2.75.6 <2.77.0 || ~2.77.0",
45+
"rollup": "~2.78.0",
4646
"slash": "^4.0.0",
4747
"source-map": "^0.6.1",
4848
"vite": "workspace:*",

packages/vite/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
"esbuild": "^0.14.47",
6262
"postcss": "^8.4.16",
6363
"resolve": "^1.22.1",
64-
"rollup": ">=2.75.6 <2.77.0 || ~2.77.0"
64+
"rollup": "~2.78.0"
6565
},
6666
"optionalDependencies": {
6767
"fsevents": "~2.3.2"

packages/vite/src/node/build.ts

+39-14
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import type {
1616
WarningHandler,
1717
WatcherOptions
1818
} from 'rollup'
19-
import type Rollup from 'rollup'
2019
import type { Terser } from 'types/terser'
2120
import commonjsPlugin from '@rollup/plugin-commonjs'
2221
import type { RollupCommonJSOptions } from 'types/commonjs'
@@ -788,34 +787,60 @@ function injectSsrFlagToHooks(plugin: Plugin): Plugin {
788787
}
789788
}
790789

791-
function wrapSsrResolveId(
792-
fn?: Rollup.ResolveIdHook
793-
): Rollup.ResolveIdHook | undefined {
794-
if (!fn) return
790+
function wrapSsrResolveId(hook?: Plugin['resolveId']): Plugin['resolveId'] {
791+
if (!hook) return
795792

796-
return function (id, importer, options) {
793+
const fn = 'handler' in hook ? hook.handler : hook
794+
const handler: Plugin['resolveId'] = function (id, importer, options) {
797795
return fn.call(this, id, importer, injectSsrFlag(options))
798796
}
797+
798+
if ('handler' in hook) {
799+
return {
800+
...hook,
801+
handler
802+
} as Plugin['resolveId']
803+
} else {
804+
return handler
805+
}
799806
}
800807

801-
function wrapSsrLoad(fn?: Rollup.LoadHook): Rollup.LoadHook | undefined {
802-
if (!fn) return
808+
function wrapSsrLoad(hook?: Plugin['load']): Plugin['load'] {
809+
if (!hook) return
803810

804-
return function (id, ...args) {
811+
const fn = 'handler' in hook ? hook.handler : hook
812+
const handler: Plugin['load'] = function (id, ...args) {
805813
// @ts-expect-error: Receiving options param to be future-proof if Rollup adds it
806814
return fn.call(this, id, injectSsrFlag(args[0]))
807815
}
816+
817+
if ('handler' in hook) {
818+
return {
819+
...hook,
820+
handler
821+
} as Plugin['load']
822+
} else {
823+
return handler
824+
}
808825
}
809826

810-
function wrapSsrTransform(
811-
fn?: Rollup.TransformHook
812-
): Rollup.TransformHook | undefined {
813-
if (!fn) return
827+
function wrapSsrTransform(hook?: Plugin['transform']): Plugin['transform'] {
828+
if (!hook) return
814829

815-
return function (code, importer, ...args) {
830+
const fn = 'handler' in hook ? hook.handler : hook
831+
const handler: Plugin['transform'] = function (code, importer, ...args) {
816832
// @ts-expect-error: Receiving options param to be future-proof if Rollup adds it
817833
return fn.call(this, code, importer, injectSsrFlag(args[0]))
818834
}
835+
836+
if ('handler' in hook) {
837+
return {
838+
...hook,
839+
handler
840+
} as Plugin['transform']
841+
} else {
842+
return handler
843+
}
819844
}
820845

821846
function injectSsrFlag<T extends Record<string, any>>(

packages/vite/src/node/config.ts

+44-22
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { Alias, AliasOptions } from 'types/alias'
88
import aliasPlugin from '@rollup/plugin-alias'
99
import { build } from 'esbuild'
1010
import type { RollupOptions } from 'rollup'
11-
import type { Plugin } from './plugin'
11+
import type { HookHandler, Plugin } from './plugin'
1212
import type {
1313
BuildOptions,
1414
RenderBuiltAssetUrl,
@@ -33,7 +33,11 @@ import {
3333
normalizeAlias,
3434
normalizePath
3535
} from './utils'
36-
import { resolvePlugins } from './plugins'
36+
import {
37+
createPluginHookUtils,
38+
getSortedPluginsByHook,
39+
resolvePlugins
40+
} from './plugins'
3741
import type { ESBuildOptions } from './plugins/esbuild'
3842
import {
3943
CLIENT_ENTRY,
@@ -289,7 +293,7 @@ export interface LegacyOptions {
289293
buildSsrCjsExternalHeuristics?: boolean
290294
}
291295

292-
export interface ResolveWorkerOptions {
296+
export interface ResolveWorkerOptions extends PluginHookUtils {
293297
format: 'es' | 'iife'
294298
plugins: Plugin[]
295299
rollupOptions: RollupOptions
@@ -334,9 +338,16 @@ export type ResolvedConfig = Readonly<
334338
worker: ResolveWorkerOptions
335339
appType: AppType
336340
experimental: ExperimentalOptions
337-
}
341+
} & PluginHookUtils
338342
>
339343

344+
export interface PluginHookUtils {
345+
getSortedPlugins: (hookName: keyof Plugin) => Plugin[]
346+
getSortedPluginHooks: <K extends keyof Plugin>(
347+
hookName: K
348+
) => NonNullable<HookHandler<Plugin[K]>>[]
349+
}
350+
340351
export type ResolveFn = (
341352
id: string,
342353
importer?: string,
@@ -431,9 +442,11 @@ export async function resolveConfig(
431442

432443
// run config hooks
433444
const userPlugins = [...prePlugins, ...normalPlugins, ...postPlugins]
434-
for (const p of userPlugins) {
435-
if (p.config) {
436-
const res = await p.config(config, configEnv)
445+
for (const p of getSortedPluginsByHook('config', userPlugins)) {
446+
const hook = p.config
447+
const handler = hook && 'handler' in hook ? hook.handler : hook
448+
if (handler) {
449+
const res = await handler(config, configEnv)
437450
if (res) {
438451
config = mergeConfig(config, res)
439452
}
@@ -598,9 +611,11 @@ export async function resolveConfig(
598611
...workerNormalPlugins,
599612
...workerPostPlugins
600613
]
601-
for (const p of workerUserPlugins) {
602-
if (p.config) {
603-
const res = await p.config(workerConfig, configEnv)
614+
for (const p of getSortedPluginsByHook('config', workerUserPlugins)) {
615+
const hook = p.config
616+
const handler = hook && 'handler' in hook ? hook.handler : hook
617+
if (handler) {
618+
const res = await handler(workerConfig, configEnv)
604619
if (res) {
605620
workerConfig = mergeConfig(workerConfig, res)
606621
}
@@ -609,7 +624,9 @@ export async function resolveConfig(
609624
const resolvedWorkerOptions: ResolveWorkerOptions = {
610625
format: workerConfig.worker?.format || 'iife',
611626
plugins: [],
612-
rollupOptions: workerConfig.worker?.rollupOptions || {}
627+
rollupOptions: workerConfig.worker?.rollupOptions || {},
628+
getSortedPlugins: undefined!,
629+
getSortedPluginHooks: undefined!
613630
}
614631

615632
const resolvedConfig: ResolvedConfig = {
@@ -660,7 +677,9 @@ export async function resolveConfig(
660677
importGlobRestoreExtension: false,
661678
hmrPartialAccept: false,
662679
...config.experimental
663-
}
680+
},
681+
getSortedPlugins: undefined!,
682+
getSortedPluginHooks: undefined!
664683
}
665684
const resolved: ResolvedConfig = {
666685
...config,
@@ -673,31 +692,34 @@ export async function resolveConfig(
673692
normalPlugins,
674693
postPlugins
675694
)
695+
Object.assign(resolved, createPluginHookUtils(resolved.plugins))
676696

677697
const workerResolved: ResolvedConfig = {
678698
...workerConfig,
679699
...resolvedConfig,
680700
isWorker: true,
681701
mainConfig: resolved
682702
}
683-
684703
resolvedConfig.worker.plugins = await resolvePlugins(
685704
workerResolved,
686705
workerPrePlugins,
687706
workerNormalPlugins,
688707
workerPostPlugins
689708
)
709+
Object.assign(
710+
resolvedConfig.worker,
711+
createPluginHookUtils(resolvedConfig.worker.plugins)
712+
)
690713

691714
// call configResolved hooks
692-
await Promise.all(
693-
userPlugins
694-
.map((p) => p.configResolved?.(resolved))
695-
.concat(
696-
resolvedConfig.worker.plugins.map((p) =>
697-
p.configResolved?.(workerResolved)
698-
)
699-
)
700-
)
715+
await Promise.all([
716+
...resolved
717+
.getSortedPluginHooks('configResolved')
718+
.map((hook) => hook(resolved)),
719+
...resolvedConfig.worker
720+
.getSortedPluginHooks('configResolved')
721+
.map((hook) => hook(workerResolved))
722+
])
701723

702724
// validate config
703725

packages/vite/src/node/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export type {
5050
SSRFormat,
5151
SSRTarget
5252
} from './ssr'
53-
export type { Plugin } from './plugin'
53+
export type { Plugin, HookHandler } from './plugin'
5454
export type { PackageCache, PackageData } from './packages'
5555
export type {
5656
Logger,

packages/vite/src/node/plugin.ts

+48-35
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {
22
CustomPluginOptions,
33
LoadResult,
4+
ObjectHook,
45
PluginContext,
56
ResolveIdResult,
67
Plugin as RollupPlugin,
@@ -63,14 +64,16 @@ export interface Plugin extends RollupPlugin {
6364
* Note: User plugins are resolved before running this hook so injecting other
6465
* plugins inside the `config` hook will have no effect.
6566
*/
66-
config?: (
67-
config: UserConfig,
68-
env: ConfigEnv
69-
) => UserConfig | null | void | Promise<UserConfig | null | void>
67+
config?: ObjectHook<
68+
(
69+
config: UserConfig,
70+
env: ConfigEnv
71+
) => UserConfig | null | void | Promise<UserConfig | null | void>
72+
>
7073
/**
7174
* Use this hook to read and store the final resolved vite config.
7275
*/
73-
configResolved?: (config: ResolvedConfig) => void | Promise<void>
76+
configResolved?: ObjectHook<(config: ResolvedConfig) => void | Promise<void>>
7477
/**
7578
* Configure the vite server. The hook receives the {@link ViteDevServer}
7679
* instance. This can also be used to store a reference to the server
@@ -80,7 +83,7 @@ export interface Plugin extends RollupPlugin {
8083
* can return a post hook that will be called after internal middlewares
8184
* are applied. Hook can be async functions and will be called in series.
8285
*/
83-
configureServer?: ServerHook
86+
configureServer?: ObjectHook<ServerHook>
8487
/**
8588
* Configure the preview server. The hook receives the connect server and
8689
* its underlying http server.
@@ -89,7 +92,7 @@ export interface Plugin extends RollupPlugin {
8992
* return a post hook that will be called after other middlewares are
9093
* applied. Hooks can be async functions and will be called in series.
9194
*/
92-
configurePreviewServer?: PreviewServerHook
95+
configurePreviewServer?: ObjectHook<PreviewServerHook>
9396
/**
9497
* Transform index.html.
9598
* The hook receives the following arguments:
@@ -121,36 +124,46 @@ export interface Plugin extends RollupPlugin {
121124
* - If the hook doesn't return a value, the hmr update will be performed as
122125
* normal.
123126
*/
124-
handleHotUpdate?(
125-
ctx: HmrContext
126-
): Array<ModuleNode> | void | Promise<Array<ModuleNode> | void>
127+
handleHotUpdate?: ObjectHook<
128+
(
129+
ctx: HmrContext
130+
) => Array<ModuleNode> | void | Promise<Array<ModuleNode> | void>
131+
>
127132

128133
/**
129134
* extend hooks with ssr flag
130135
*/
131-
resolveId?: (
132-
this: PluginContext,
133-
source: string,
134-
importer: string | undefined,
135-
options: {
136-
custom?: CustomPluginOptions
137-
ssr?: boolean
138-
/**
139-
* @internal
140-
*/
141-
scan?: boolean
142-
isEntry: boolean
143-
}
144-
) => Promise<ResolveIdResult> | ResolveIdResult
145-
load?: (
146-
this: PluginContext,
147-
id: string,
148-
options?: { ssr?: boolean }
149-
) => Promise<LoadResult> | LoadResult
150-
transform?: (
151-
this: TransformPluginContext,
152-
code: string,
153-
id: string,
154-
options?: { ssr?: boolean }
155-
) => Promise<TransformResult> | TransformResult
136+
resolveId?: ObjectHook<
137+
(
138+
this: PluginContext,
139+
source: string,
140+
importer: string | undefined,
141+
options: {
142+
custom?: CustomPluginOptions
143+
ssr?: boolean
144+
/**
145+
* @internal
146+
*/
147+
scan?: boolean
148+
isEntry: boolean
149+
}
150+
) => Promise<ResolveIdResult> | ResolveIdResult
151+
>
152+
load?: ObjectHook<
153+
(
154+
this: PluginContext,
155+
id: string,
156+
options?: { ssr?: boolean }
157+
) => Promise<LoadResult> | LoadResult
158+
>
159+
transform?: ObjectHook<
160+
(
161+
this: TransformPluginContext,
162+
code: string,
163+
id: string,
164+
options?: { ssr?: boolean }
165+
) => Promise<TransformResult> | TransformResult
166+
>
156167
}
168+
169+
export type HookHandler<T> = T extends ObjectHook<infer H> ? H : T

0 commit comments

Comments
 (0)