Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support object style hooks #9634

Merged
merged 21 commits into from
Aug 22, 2022
Merged
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@
"prettier": "2.7.1",
"prompts": "^2.4.2",
"rimraf": "^3.0.2",
"rollup": ">=2.75.6 <2.77.0 || ~2.77.0",
"rollup": "~2.78.0",
"semver": "^7.3.7",
"simple-git-hooks": "^2.8.0",
"tslib": "^2.4.0",
2 changes: 1 addition & 1 deletion packages/plugin-vue/package.json
Original file line number Diff line number Diff line change
@@ -42,7 +42,7 @@
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.14",
"debug": "^4.3.4",
"rollup": ">=2.75.6 <2.77.0 || ~2.77.0",
"rollup": "~2.78.0",
"slash": "^4.0.0",
"source-map": "^0.6.1",
"vite": "workspace:*",
2 changes: 1 addition & 1 deletion packages/vite/package.json
Original file line number Diff line number Diff line change
@@ -61,7 +61,7 @@
"esbuild": "^0.14.47",
"postcss": "^8.4.16",
"resolve": "^1.22.1",
"rollup": ">=2.75.6 <2.77.0 || ~2.77.0"
"rollup": "~2.78.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
53 changes: 39 additions & 14 deletions packages/vite/src/node/build.ts
Original file line number Diff line number Diff line change
@@ -16,7 +16,6 @@ import type {
WarningHandler,
WatcherOptions
} from 'rollup'
import type Rollup from 'rollup'
import type { Terser } from 'types/terser'
import commonjsPlugin from '@rollup/plugin-commonjs'
import type { RollupCommonJSOptions } from 'types/commonjs'
@@ -786,34 +785,60 @@ function injectSsrFlagToHooks(plugin: Plugin): Plugin {
}
}

function wrapSsrResolveId(
fn?: Rollup.ResolveIdHook
): Rollup.ResolveIdHook | undefined {
if (!fn) return
function wrapSsrResolveId(hook?: Plugin['resolveId']): Plugin['resolveId'] {
if (!hook) return

return function (id, importer, options) {
const fn = 'handler' in hook ? hook.handler : hook
const handler: Plugin['resolveId'] = function (id, importer, options) {
return fn.call(this, id, importer, injectSsrFlag(options))
}

if ('handler' in hook) {
return {
...hook,
handler
} as Plugin['resolveId']
} else {
return handler
}
}

function wrapSsrLoad(fn?: Rollup.LoadHook): Rollup.LoadHook | undefined {
if (!fn) return
function wrapSsrLoad(hook?: Plugin['load']): Plugin['load'] {
if (!hook) return

return function (id, ...args) {
const fn = 'handler' in hook ? hook.handler : 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]))
}

if ('handler' in hook) {
return {
...hook,
handler
} as Plugin['load']
} else {
return handler
}
}

function wrapSsrTransform(
fn?: Rollup.TransformHook
): Rollup.TransformHook | undefined {
if (!fn) return
function wrapSsrTransform(hook?: Plugin['transform']): Plugin['transform'] {
if (!hook) return

return function (code, importer, ...args) {
const fn = 'handler' in hook ? hook.handler : 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]))
}

if ('handler' in hook) {
return {
...hook,
handler
} as Plugin['transform']
} else {
return handler
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it is worth extracting a helper for these three functions to avoid repeating the function or object handling?

}

function injectSsrFlag<T extends Record<string, any>>(
66 changes: 44 additions & 22 deletions packages/vite/src/node/config.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import type { Alias, AliasOptions } from 'types/alias'
import aliasPlugin from '@rollup/plugin-alias'
import { build } from 'esbuild'
import type { RollupOptions } from 'rollup'
import type { Plugin } from './plugin'
import type { HookHandler, Plugin } from './plugin'
import type {
BuildOptions,
RenderBuiltAssetUrl,
@@ -33,7 +33,11 @@ import {
normalizeAlias,
normalizePath
} from './utils'
import { resolvePlugins } from './plugins'
import {
createPluginHookUtils,
getSortedPluginsByHook,
resolvePlugins
} from './plugins'
import type { ESBuildOptions } from './plugins/esbuild'
import {
CLIENT_ENTRY,
@@ -289,7 +293,7 @@ export interface LegacyOptions {
buildSsrCjsExternalHeuristics?: boolean
}

export interface ResolveWorkerOptions {
export interface ResolveWorkerOptions extends PluginHookUtils {
format: 'es' | 'iife'
plugins: Plugin[]
rollupOptions: RollupOptions
@@ -334,9 +338,16 @@ export type ResolvedConfig = Readonly<
worker: ResolveWorkerOptions
appType: AppType
experimental: ExperimentalOptions
}
} & PluginHookUtils
>

export interface PluginHookUtils {
getSortedPlugins: (hookName: keyof Plugin) => Plugin[]
getSortedPluginHooks: <K extends keyof Plugin>(
hookName: K
) => NonNullable<HookHandler<Plugin[K]>>[]
}

export type ResolveFn = (
id: string,
importer?: string,
@@ -431,9 +442,11 @@ export async function resolveConfig(

// run config hooks
const userPlugins = [...prePlugins, ...normalPlugins, ...postPlugins]
for (const p of userPlugins) {
if (p.config) {
const res = await p.config(config, configEnv)
for (const p of getSortedPluginsByHook('config', userPlugins)) {
const hook = p.config
const handler = hook && 'handler' in hook ? hook.handler : hook
if (handler) {
const res = await handler(config, configEnv)
if (res) {
config = mergeConfig(config, res)
}
@@ -598,9 +611,11 @@ export async function resolveConfig(
...workerNormalPlugins,
...workerPostPlugins
]
for (const p of workerUserPlugins) {
if (p.config) {
const res = await p.config(workerConfig, configEnv)
for (const p of getSortedPluginsByHook('config', workerUserPlugins)) {
const hook = p.config
const handler = hook && 'handler' in hook ? hook.handler : hook
if (handler) {
const res = await handler(workerConfig, configEnv)
if (res) {
workerConfig = mergeConfig(workerConfig, res)
}
@@ -609,7 +624,9 @@ export async function resolveConfig(
const resolvedWorkerOptions: ResolveWorkerOptions = {
format: workerConfig.worker?.format || 'iife',
plugins: [],
rollupOptions: workerConfig.worker?.rollupOptions || {}
rollupOptions: workerConfig.worker?.rollupOptions || {},
getSortedPlugins: undefined!,
getSortedPluginHooks: undefined!
}

const resolvedConfig: ResolvedConfig = {
@@ -660,7 +677,9 @@ export async function resolveConfig(
importGlobRestoreExtension: false,
hmrPartialAccept: false,
...config.experimental
}
},
getSortedPlugins: undefined!,
getSortedPluginHooks: undefined!
}
const resolved: ResolvedConfig = {
...config,
@@ -673,31 +692,34 @@ export async function resolveConfig(
normalPlugins,
postPlugins
)
Object.assign(resolved, createPluginHookUtils(resolved.plugins))

const workerResolved: ResolvedConfig = {
...workerConfig,
...resolvedConfig,
isWorker: true,
mainConfig: resolved
}

resolvedConfig.worker.plugins = await resolvePlugins(
workerResolved,
workerPrePlugins,
workerNormalPlugins,
workerPostPlugins
)
Object.assign(
resolvedConfig.worker,
createPluginHookUtils(resolvedConfig.worker.plugins)
)

// call configResolved hooks
await Promise.all(
userPlugins
.map((p) => p.configResolved?.(resolved))
.concat(
resolvedConfig.worker.plugins.map((p) =>
p.configResolved?.(workerResolved)
)
)
)
await Promise.all([
...resolved
.getSortedPluginHooks('configResolved')
.map((hook) => hook(resolved)),
Copy link
Member

@csr632 csr632 Sep 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this inside the hook no loger points to the plugin object:
#10031

...resolvedConfig.worker
.getSortedPluginHooks('configResolved')
.map((hook) => hook(workerResolved))
])

// validate config

2 changes: 1 addition & 1 deletion packages/vite/src/node/index.ts
Original file line number Diff line number Diff line change
@@ -50,7 +50,7 @@ export type {
SSRFormat,
SSRTarget
} from './ssr'
export type { Plugin } from './plugin'
export type { Plugin, HookHandler } from './plugin'
export type { PackageCache, PackageData } from './packages'
export type {
Logger,
83 changes: 48 additions & 35 deletions packages/vite/src/node/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
CustomPluginOptions,
LoadResult,
ObjectHook,
PluginContext,
ResolveIdResult,
Plugin as RollupPlugin,
@@ -63,14 +64,16 @@ export interface Plugin extends RollupPlugin {
* Note: User plugins are resolved before running this hook so injecting other
* plugins inside the `config` hook will have no effect.
*/
config?: (
config: UserConfig,
env: ConfigEnv
) => UserConfig | null | void | Promise<UserConfig | null | void>
config?: ObjectHook<
(
config: UserConfig,
env: ConfigEnv
) => UserConfig | null | void | Promise<UserConfig | null | void>
>
/**
* Use this hook to read and store the final resolved vite config.
*/
configResolved?: (config: ResolvedConfig) => void | Promise<void>
configResolved?: ObjectHook<(config: ResolvedConfig) => void | Promise<void>>
/**
* Configure the vite server. The hook receives the {@link ViteDevServer}
* instance. This can also be used to store a reference to the server
@@ -80,7 +83,7 @@ export interface Plugin extends RollupPlugin {
* can return a post hook that will be called after internal middlewares
* are applied. Hook can be async functions and will be called in series.
*/
configureServer?: ServerHook
configureServer?: ObjectHook<ServerHook>
/**
* Configure the preview server. The hook receives the connect server and
* its underlying http server.
@@ -89,7 +92,7 @@ export interface Plugin extends RollupPlugin {
* return a post hook that will be called after other middlewares are
* applied. Hooks can be async functions and will be called in series.
*/
configurePreviewServer?: PreviewServerHook
configurePreviewServer?: ObjectHook<PreviewServerHook>
/**
* Transform index.html.
* The hook receives the following arguments:
@@ -121,36 +124,46 @@ export interface Plugin extends RollupPlugin {
* - If the hook doesn't return a value, the hmr update will be performed as
* normal.
*/
handleHotUpdate?(
ctx: HmrContext
): Array<ModuleNode> | void | Promise<Array<ModuleNode> | void>
handleHotUpdate?: ObjectHook<
(
ctx: HmrContext
) => Array<ModuleNode> | void | Promise<Array<ModuleNode> | void>
>

/**
* extend hooks with ssr flag
*/
resolveId?: (
this: PluginContext,
source: string,
importer: string | undefined,
options: {
custom?: CustomPluginOptions
ssr?: boolean
/**
* @internal
*/
scan?: boolean
isEntry: boolean
}
) => Promise<ResolveIdResult> | ResolveIdResult
load?: (
this: PluginContext,
id: string,
options?: { ssr?: boolean }
) => Promise<LoadResult> | LoadResult
transform?: (
this: TransformPluginContext,
code: string,
id: string,
options?: { ssr?: boolean }
) => Promise<TransformResult> | TransformResult
resolveId?: ObjectHook<
(
this: PluginContext,
source: string,
importer: string | undefined,
options: {
custom?: CustomPluginOptions
ssr?: boolean
/**
* @internal
*/
scan?: boolean
isEntry: boolean
}
) => Promise<ResolveIdResult> | ResolveIdResult
>
load?: ObjectHook<
(
this: PluginContext,
id: string,
options?: { ssr?: boolean }
) => Promise<LoadResult> | LoadResult
>
transform?: ObjectHook<
(
this: TransformPluginContext,
code: string,
id: string,
options?: { ssr?: boolean }
) => Promise<TransformResult> | TransformResult
>
}

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