From 8895b098c69ec0c0acc0f0cbb34c74f11b365d1d Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Fri, 2 Aug 2024 12:08:36 +0800 Subject: [PATCH 01/15] feat: add environment compiler hooks --- .../plugin-hooks/environments.test.ts | 190 ++++++++++++++++ .../plugin-api/plugin-hooks/index.test.ts | 12 + packages/compat/webpack/src/build.ts | 32 +-- packages/compat/webpack/src/createCompiler.ts | 33 ++- packages/compat/webpack/src/shared.ts | 4 +- packages/core/src/helpers.ts | 87 -------- packages/core/src/hooks.ts | 209 ++++++++++++++++++ packages/core/src/initHooks.ts | 12 + packages/core/src/initPlugins.ts | 15 ++ packages/core/src/internal.ts | 9 +- packages/core/src/provider/build.ts | 39 +--- packages/core/src/provider/createCompiler.ts | 32 ++- packages/core/src/server/devServer.ts | 58 +++-- packages/core/src/types/hooks.ts | 49 +++- packages/core/src/types/plugin.ts | 6 + .../tests/__snapshots__/hooks.test.ts.snap | 3 + website/docs/en/plugins/dev/hooks.mdx | 73 ++++++ .../en/shared/onAfterEnvironmentBuild.mdx | 16 ++ .../en/shared/onBeforeEnvironmentBuild.mdx | 18 ++ .../en/shared/onDevCompileEnvironmentDone.mdx | 13 ++ website/docs/zh/plugins/dev/hooks.mdx | 73 ++++++ .../zh/shared/onAfterEnvironmentBuild.mdx | 16 ++ .../zh/shared/onBeforeEnvironmentBuild.mdx | 18 ++ .../zh/shared/onDevCompileEnvironmentDone.mdx | 13 ++ 24 files changed, 832 insertions(+), 198 deletions(-) create mode 100644 e2e/cases/plugin-api/plugin-hooks/environments.test.ts create mode 100644 packages/core/src/hooks.ts create mode 100644 website/docs/en/shared/onAfterEnvironmentBuild.mdx create mode 100644 website/docs/en/shared/onBeforeEnvironmentBuild.mdx create mode 100644 website/docs/en/shared/onDevCompileEnvironmentDone.mdx create mode 100644 website/docs/zh/shared/onAfterEnvironmentBuild.mdx create mode 100644 website/docs/zh/shared/onBeforeEnvironmentBuild.mdx create mode 100644 website/docs/zh/shared/onDevCompileEnvironmentDone.mdx diff --git a/e2e/cases/plugin-api/plugin-hooks/environments.test.ts b/e2e/cases/plugin-api/plugin-hooks/environments.test.ts new file mode 100644 index 0000000000..528eb57319 --- /dev/null +++ b/e2e/cases/plugin-api/plugin-hooks/environments.test.ts @@ -0,0 +1,190 @@ +import { gotoPage, rspackOnlyTest } from '@e2e/helper'; +import { expect } from '@playwright/test'; +import { type RsbuildPlugin, createRsbuild } from '@rsbuild/core'; + +const createPlugin = () => { + const names: string[] = []; + + const plugin: RsbuildPlugin = { + name: 'test-plugin', + setup(api) { + api.modifyRspackConfig((_config, { environment }) => { + names.push(`ModifyBundlerConfig ${environment.name}`); + }); + api.modifyWebpackChain((_config, { environment }) => { + names.push(`ModifyBundlerConfig ${environment.name}`); + }); + api.modifyRsbuildConfig(() => { + names.push('ModifyRsbuildConfig'); + }); + api.modifyEnvironmentConfig((_config, { name }) => { + names.push(`ModifyEnvironmentConfig ${name}`); + }); + api.modifyBundlerChain((_chain, { environment }) => { + names.push(`ModifyBundlerChain ${environment.name}`); + }); + api.modifyHTMLTags((tags, { environment }) => { + names.push(`ModifyHTMLTags ${environment.name}`); + return tags; + }); + api.onBeforeStartDevServer(() => { + names.push('BeforeStartDevServer'); + }); + api.onAfterStartDevServer(() => { + names.push('AfterStartDevServer'); + }); + api.onBeforeCreateCompiler(() => { + names.push('BeforeCreateCompiler'); + }); + api.onAfterCreateCompiler(() => { + names.push('AfterCreateCompiler'); + }); + api.onBeforeBuild(() => { + names.push('BeforeBuild'); + }); + api.onAfterBuild(() => { + names.push('AfterBuild'); + }); + api.onBeforeEnvironmentBuild(({ environment }) => { + names.push(`BeforeEnvironmentBuild ${environment.name}`); + }); + api.onAfterEnvironmentBuild(({ stats, environment }) => { + expect(stats?.compilation.name).toBe(environment.name); + names.push(`AfterEnvironmentBuild ${environment.name}`); + }); + api.onBeforeStartProdServer(() => { + names.push('BeforeStartProdServer'); + }); + api.onCloseDevServer(() => { + names.push('OnCloseDevServer'); + }); + api.onAfterStartProdServer(() => { + names.push('AfterStartProdServer'); + }); + api.onDevCompileDone(() => { + names.push('OnDevCompileDone'); + }); + api.onDevCompileEnvironmentDone(({ stats, environment }) => { + expect(stats?.compilation.name).toBe(environment.name); + names.push(`DevCompileEnvironmentDone ${environment.name}`); + }); + }, + }; + + return { plugin, names }; +}; + +rspackOnlyTest( + 'should run plugin hooks correctly when running build with multiple environments', + async () => { + const { plugin, names } = createPlugin(); + const rsbuild = await createRsbuild({ + cwd: __dirname, + rsbuildConfig: { + plugins: [plugin], + environments: { + web: {}, + node: {}, + }, + }, + }); + + await rsbuild.build(); + + // Test environment hook is always called twice + expect(names.filter((name) => name.includes(' web')).length).toBe( + names.filter((name) => name.includes(' node')).length, + ); + + // The execution order between different Environments of the same hook is not fixed + // Therefore, we only test the execution order of a single Environment + expect(names.filter((name) => !name.includes(' node'))).toEqual([ + 'ModifyRsbuildConfig', + 'ModifyEnvironmentConfig web', + 'ModifyBundlerChain web', + 'ModifyBundlerConfig web', + 'BeforeCreateCompiler', + 'AfterCreateCompiler', + 'BeforeEnvironmentBuild web', + 'BeforeBuild', + 'ModifyHTMLTags web', + 'AfterEnvironmentBuild web', + 'AfterBuild', + ]); + + expect(names.filter((name) => !name.includes(' web'))).toEqual([ + 'ModifyRsbuildConfig', + 'ModifyEnvironmentConfig node', + 'ModifyBundlerChain node', + 'ModifyBundlerConfig node', + 'BeforeCreateCompiler', + 'AfterCreateCompiler', + 'BeforeEnvironmentBuild node', + 'BeforeBuild', + 'ModifyHTMLTags node', + 'AfterEnvironmentBuild node', + 'AfterBuild', + ]); + }, +); + +rspackOnlyTest( + 'should run plugin hooks correctly when running startDevServer with multiple environments', + async ({ page }) => { + process.env.NODE_ENV = 'development'; + + const { plugin, names } = createPlugin(); + const rsbuild = await createRsbuild({ + cwd: __dirname, + rsbuildConfig: { + plugins: [plugin], + environments: { + web: {}, + node: {}, + }, + }, + }); + + const result = await rsbuild.startDevServer(); + + await gotoPage(page, result); + + await result.server.close(); + + expect(names.filter((name) => name.includes(' web')).length).toBe( + names.filter((name) => name.includes(' node')).length, + ); + + expect(names.filter((name) => !name.includes(' node'))).toEqual([ + 'ModifyRsbuildConfig', + 'ModifyEnvironmentConfig web', + 'BeforeStartDevServer', + 'ModifyBundlerChain web', + 'ModifyBundlerConfig web', + 'BeforeCreateCompiler', + 'AfterCreateCompiler', + 'AfterStartDevServer', + 'ModifyHTMLTags web', + 'DevCompileEnvironmentDone web', + 'OnDevCompileDone', + 'OnCloseDevServer', + ]); + + expect(names.filter((name) => !name.includes(' web'))).toEqual([ + 'ModifyRsbuildConfig', + 'ModifyEnvironmentConfig node', + 'BeforeStartDevServer', + 'ModifyBundlerChain node', + 'ModifyBundlerConfig node', + 'BeforeCreateCompiler', + 'AfterCreateCompiler', + 'AfterStartDevServer', + 'ModifyHTMLTags node', + 'DevCompileEnvironmentDone node', + 'OnDevCompileDone', + 'OnCloseDevServer', + ]); + + process.env.NODE_ENV = 'test'; + }, +); diff --git a/e2e/cases/plugin-api/plugin-hooks/index.test.ts b/e2e/cases/plugin-api/plugin-hooks/index.test.ts index 39f495d7f8..adc3c32e4d 100644 --- a/e2e/cases/plugin-api/plugin-hooks/index.test.ts +++ b/e2e/cases/plugin-api/plugin-hooks/index.test.ts @@ -45,6 +45,12 @@ const createPlugin = () => { api.onAfterBuild(() => { names.push('AfterBuild'); }); + api.onBeforeEnvironmentBuild(() => { + names.push('BeforeEnvironmentBuild'); + }); + api.onAfterEnvironmentBuild(() => { + names.push('AfterEnvironmentBuild'); + }); api.onBeforeStartProdServer(() => { names.push('BeforeStartProdServer'); }); @@ -57,6 +63,9 @@ const createPlugin = () => { api.onDevCompileDone(() => { names.push('OnDevCompileDone'); }); + api.onDevCompileEnvironmentDone(() => { + names.push('DevCompileEnvironmentDone'); + }); }, }; @@ -83,8 +92,10 @@ rspackOnlyTest( 'ModifyBundlerConfig', 'BeforeCreateCompiler', 'AfterCreateCompiler', + 'BeforeEnvironmentBuild', 'BeforeBuild', 'ModifyHTMLTags', + 'AfterEnvironmentBuild', 'AfterBuild', ]); }, @@ -119,6 +130,7 @@ rspackOnlyTest( 'AfterCreateCompiler', 'AfterStartDevServer', 'ModifyHTMLTags', + 'DevCompileEnvironmentDone', 'OnDevCompileDone', 'OnCloseDevServer', ]); diff --git a/packages/compat/webpack/src/build.ts b/packages/compat/webpack/src/build.ts index 3ea278d813..2b088d9a0d 100644 --- a/packages/compat/webpack/src/build.ts +++ b/packages/compat/webpack/src/build.ts @@ -4,7 +4,7 @@ import type { Configuration as WebpackConfig } from 'webpack'; import WebpackMultiStats from 'webpack/lib/MultiStats.js'; import { createCompiler } from './createCompiler'; import { type InitConfigsOptions, initConfigs } from './initConfigs'; -import { onBeforeBuild, onCompileDone } from './shared'; +import { registerBuildHook } from './shared'; export const build = async ( initOptions: InitConfigsOptions, @@ -34,29 +34,13 @@ export const build = async ( bundlerConfigs = webpackConfigs; } - let isFirstCompile = true; - const beforeBuild = async () => - await context.hooks.onBeforeBuild.call({ - bundlerConfigs: bundlerConfigs as Rspack.Configuration[], - environments: context.environments, - isWatch: Boolean(watch), - isFirstCompile, - }); - - const onDone = async (stats: Rspack.Stats | Rspack.MultiStats) => { - const p = context.hooks.onAfterBuild.call({ - isFirstCompile, - stats, - environments: context.environments, - isWatch: Boolean(watch), - }); - isFirstCompile = false; - await p; - }; - - onBeforeBuild(compiler, beforeBuild, watch); - - onCompileDone(compiler, onDone, WebpackMultiStats); + registerBuildHook({ + context, + bundlerConfigs: bundlerConfigs as any, + compiler, + isWatch: Boolean(watch), + MultiStatsCtor: WebpackMultiStats, + }); if (watch) { const watching = compiler.watch({}, (err) => { diff --git a/packages/compat/webpack/src/createCompiler.ts b/packages/compat/webpack/src/createCompiler.ts index a26134e7b5..cd232f9852 100644 --- a/packages/compat/webpack/src/createCompiler.ts +++ b/packages/compat/webpack/src/createCompiler.ts @@ -1,4 +1,4 @@ -import { type Rspack, logger } from '@rsbuild/core'; +import { type EnvironmentContext, type Rspack, logger } from '@rsbuild/core'; import WebpackMultiStats from 'webpack/lib/MultiStats.js'; import { type InitConfigsOptions, initConfigs } from './initConfigs'; import { @@ -31,6 +31,8 @@ export async function createCompiler({ | Rspack.Compiler | Rspack.MultiCompiler; + let isFirstCompile = true; + const done = async (stats: unknown) => { const { message, level } = formatStats( stats as Rspack.Stats, @@ -55,9 +57,34 @@ export async function createCompiler({ isFirstCompile = false; }; - let isFirstCompile = true; + const environmentArr = Object.values(context.environments).reduce< + EnvironmentContext[] + >((prev, curr) => { + prev[curr.index] = curr; + return prev; + }, []); + + const onEnvironmentDone = async (index: number, stats: Rspack.Stats) => { + if (process.env.NODE_ENV === 'development') { + await context.hooks.onDevCompileEnvironmentDone.callInEnvironment({ + environment: environmentArr[index].name, + args: [ + { + isFirstCompile, + stats, + environment: environmentArr[index], + }, + ], + }); + } + }; - onCompileDone(compiler, done, WebpackMultiStats); + onCompileDone({ + compiler, + onDone: done, + onEnvironmentDone, + MultiStatsCtor: WebpackMultiStats, + }); await context.hooks.onAfterCreateCompiler.call({ compiler, diff --git a/packages/compat/webpack/src/shared.ts b/packages/compat/webpack/src/shared.ts index ae5cd3a525..6ed405defa 100644 --- a/packages/compat/webpack/src/shared.ts +++ b/packages/compat/webpack/src/shared.ts @@ -12,8 +12,8 @@ const { getRsbuildInspectConfig, chainToConfig, modifyBundlerChain, - onBeforeBuild, onCompileDone, + registerBuildHook, prettyTime, } = __internalHelper; @@ -29,7 +29,7 @@ export { chainToConfig, modifyBundlerChain, onCompileDone, - onBeforeBuild, + registerBuildHook, prettyTime, getRsbuildInspectConfig, }; diff --git a/packages/core/src/helpers.ts b/packages/core/src/helpers.ts index 7bf3d3d062..bfa49f39c4 100644 --- a/packages/core/src/helpers.ts +++ b/packages/core/src/helpers.ts @@ -565,93 +565,6 @@ export const isMultiCompiler = < return compiler.constructor.name === 'MultiCompiler'; }; -export const onBeforeBuild = ( - compiler: Rspack.Compiler | Rspack.MultiCompiler, - onBefore: () => Promise, - isWatch?: boolean, -): void => { - const name = 'rsbuild:beforeCompile'; - - if (isMultiCompiler(compiler)) { - const { compilers } = compiler; - - let doneCompilers = 0; - - for (let index = 0; index < compilers.length; index++) { - const compiler = compilers[index]; - let compilerDone = false; - - (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( - name, - async () => { - if (!compilerDone) { - compilerDone = true; - doneCompilers++; - } - - if (doneCompilers === compilers.length) { - await onBefore(); - } - }, - ); - - compiler.hooks.invalid.tap(name, () => { - if (compilerDone) { - compilerDone = false; - doneCompilers--; - } - }); - } - } else { - (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( - name, - onBefore, - ); - } -}; - -export const onCompileDone = ( - compiler: Rspack.Compiler | Rspack.MultiCompiler, - onDone: (stats: Rspack.Stats | Rspack.MultiStats) => Promise, - MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats, -): void => { - // The MultiCompiler of Rspack does not supports `done.tapPromise`, - // so we need to use the `done` hook of `MultiCompiler.compilers` to implement it. - if (isMultiCompiler(compiler)) { - const { compilers } = compiler; - const compilerStats: Rspack.Stats[] = []; - let doneCompilers = 0; - - for (let index = 0; index < compilers.length; index++) { - const compiler = compilers[index]; - const compilerIndex = index; - let compilerDone = false; - - compiler.hooks.done.tapPromise('rsbuild:done', async (stats) => { - if (!compilerDone) { - compilerDone = true; - doneCompilers++; - } - - compilerStats[compilerIndex] = stats; - - if (doneCompilers === compilers.length) { - await onDone(new MultiStatsCtor(compilerStats)); - } - }); - - compiler.hooks.invalid.tap('rsbuild:done', () => { - if (compilerDone) { - compilerDone = false; - doneCompilers--; - } - }); - } - } else { - compiler.hooks.done.tapPromise('rsbuild:done', onDone); - } -}; - export function pick( obj: T, keys: ReadonlyArray, diff --git a/packages/core/src/hooks.ts b/packages/core/src/hooks.ts new file mode 100644 index 0000000000..c8dfa5102d --- /dev/null +++ b/packages/core/src/hooks.ts @@ -0,0 +1,209 @@ +import { isMultiCompiler } from './helpers'; +import type { + EnvironmentContext, + InternalContext, + MultiStats, + Rspack, + RspackConfig, + Stats, +} from './types'; + +const onBeforeBuild = ({ + compiler, + beforeBuild, + beforeEnvironmentBuild, + isWatch, +}: { + compiler: Rspack.Compiler | Rspack.MultiCompiler; + beforeBuild: () => Promise; + beforeEnvironmentBuild: (buildIndex: number) => Promise; + isWatch?: boolean; +}): void => { + const name = 'rsbuild:beforeCompile'; + + if (isMultiCompiler(compiler)) { + const { compilers } = compiler; + console.log('compilers', compilers.length); + + let doneCompilers = 0; + + for (let index = 0; index < compilers.length; index++) { + const compiler = compilers[index]; + let compilerDone = false; + + (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( + name, + async () => { + if (!compilerDone) { + compilerDone = true; + doneCompilers++; + } + // ensure only last compiler done will trigger beforeBuild hook + // avoid other compiler done triggers when executing async beforeEnvironmentBuild hook + const lastCompilerDone = doneCompilers === compilers.length; + + await beforeEnvironmentBuild(index); + + if (lastCompilerDone) { + await beforeBuild(); + } + }, + ); + + compiler.hooks.invalid.tap(name, () => { + if (compilerDone) { + compilerDone = false; + doneCompilers--; + } + }); + } + } else { + (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( + name, + async () => { + await beforeEnvironmentBuild(0); + await beforeBuild(); + }, + ); + } +}; + +export const onCompileDone = ({ + compiler, + onDone, + onEnvironmentDone, + MultiStatsCtor, +}: { + compiler: Rspack.Compiler | Rspack.MultiCompiler; + onDone: (stats: Rspack.Stats | Rspack.MultiStats) => Promise; + onEnvironmentDone: (buildIndex: number, stats: Rspack.Stats) => Promise; + MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; +}): void => { + // The MultiCompiler of Rspack does not supports `done.tapPromise`, + // so we need to use the `done` hook of `MultiCompiler.compilers` to implement it. + if (isMultiCompiler(compiler)) { + const { compilers } = compiler; + const compilerStats: Rspack.Stats[] = []; + let doneCompilers = 0; + + for (let index = 0; index < compilers.length; index++) { + const compiler = compilers[index]; + const compilerIndex = index; + let compilerDone = false; + + compiler.hooks.done.tapPromise('rsbuild:done', async (stats) => { + if (!compilerDone) { + compilerDone = true; + doneCompilers++; + } + + compilerStats[compilerIndex] = stats; + + const lastCompilerDone = doneCompilers === compilers.length; + + await onEnvironmentDone(index, stats); + + if (lastCompilerDone) { + await onDone(new MultiStatsCtor(compilerStats)); + } + }); + + compiler.hooks.invalid.tap('rsbuild:done', () => { + if (compilerDone) { + compilerDone = false; + doneCompilers--; + } + }); + } + } else { + compiler.hooks.done.tapPromise('rsbuild:done', async (stats) => { + await onEnvironmentDone(0, stats); + await onDone(stats); + }); + } +}; + +export const registerBuildHook = ({ + context, + isWatch, + compiler, + bundlerConfigs, + MultiStatsCtor, +}: { + bundlerConfigs?: RspackConfig[]; + context: InternalContext; + compiler: Rspack.Compiler | Rspack.MultiCompiler; + isWatch: boolean; + MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; +}): void => { + let isFirstCompile = true; + + const environmentArr = Object.values(context.environments).reduce< + EnvironmentContext[] + >((prev, curr) => { + prev[curr.index] = curr; + return prev; + }, []); + + const beforeBuild = async () => + await context.hooks.onBeforeBuild.call({ + bundlerConfigs, + environments: context.environments, + isWatch, + isFirstCompile, + }); + + const beforeEnvironmentBuild = async (buildIndex: number) => + await context.hooks.onBeforeEnvironmentBuild.callInEnvironment({ + environment: environmentArr[buildIndex].name, + args: [ + { + bundlerConfig: bundlerConfigs?.[buildIndex] as Rspack.Configuration, + environment: environmentArr[buildIndex], + isWatch, + isFirstCompile, + }, + ], + }); + + const onDone = async (stats: Stats | MultiStats) => { + const p = context.hooks.onAfterBuild.call({ + isFirstCompile, + stats, + environments: context.environments, + isWatch, + }); + isFirstCompile = false; + await p; + }; + + const onEnvironmentDone = async (buildIndex: number, stats: Stats) => { + const p = context.hooks.onAfterEnvironmentBuild.callInEnvironment({ + environment: environmentArr[buildIndex].name, + args: [ + { + isFirstCompile, + stats, + environment: environmentArr[buildIndex], + isWatch, + }, + ], + }); + isFirstCompile = false; + await p; + }; + + onBeforeBuild({ + compiler, + beforeBuild, + beforeEnvironmentBuild, + isWatch, + }); + + onCompileDone({ + compiler, + onDone, + onEnvironmentDone, + MultiStatsCtor, + }); +}; diff --git a/packages/core/src/initHooks.ts b/packages/core/src/initHooks.ts index 5776b66013..12685e5c9e 100644 --- a/packages/core/src/initHooks.ts +++ b/packages/core/src/initHooks.ts @@ -13,14 +13,17 @@ import type { ModifyWebpackConfigFn, OnAfterBuildFn, OnAfterCreateCompilerFn, + OnAfterEnvironmentBuildFn, OnAfterStartDevServerFn, OnAfterStartProdServerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, + OnBeforeEnvironmentBuildFn, OnBeforeStartDevServerFn, OnBeforeStartProdServerFn, OnCloseDevServerFn, OnDevCompileDoneFn, + OnDevCompileEnvironmentDoneFn, OnExitFn, } from './types'; @@ -162,6 +165,9 @@ export function initHooks(): { modifyWebpackConfig: EnvironmentAsyncHook; modifyRsbuildConfig: AsyncHook; modifyEnvironmentConfig: EnvironmentAsyncHook; + onBeforeEnvironmentBuild: EnvironmentAsyncHook; + onAfterEnvironmentBuild: EnvironmentAsyncHook; + onDevCompileEnvironmentDone: EnvironmentAsyncHook; } { return { onExit: createAsyncHook(), @@ -183,6 +189,12 @@ export function initHooks(): { modifyRsbuildConfig: createAsyncHook(), modifyEnvironmentConfig: createEnvironmentAsyncHook(), + onBeforeEnvironmentBuild: + createEnvironmentAsyncHook(), + onAfterEnvironmentBuild: + createEnvironmentAsyncHook(), + onDevCompileEnvironmentDone: + createEnvironmentAsyncHook(), }; } diff --git a/packages/core/src/initPlugins.ts b/packages/core/src/initPlugins.ts index 7b2ca009b4..c9d6241f69 100644 --- a/packages/core/src/initPlugins.ts +++ b/packages/core/src/initPlugins.ts @@ -319,5 +319,20 @@ export function initPluginAPI({ environment, handler, }), + onAfterEnvironmentBuild: (handler) => + hooks.onAfterEnvironmentBuild.tapEnvironment({ + environment, + handler, + }), + onBeforeEnvironmentBuild: (handler) => + hooks.onBeforeEnvironmentBuild.tapEnvironment({ + environment, + handler, + }), + onDevCompileEnvironmentDone: (handler) => + hooks.onDevCompileEnvironmentDone.tapEnvironment({ + environment, + handler, + }), }); } diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index cdbc10a663..9a471daf02 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -16,13 +16,8 @@ export { } from './config'; export type { InternalContext } from './types'; export { setHTMLPlugin, getHTMLPlugin } from './pluginHelper'; -export { - formatStats, - getStatsOptions, - onCompileDone, - onBeforeBuild, - prettyTime, -} from './helpers'; +export { formatStats, getStatsOptions, prettyTime } from './helpers'; +export { registerBuildHook, onCompileDone } from './hooks'; export { getChainUtils, getConfigUtils } from './provider/rspackConfig'; export { chainToConfig, modifyBundlerChain } from './configChain'; export { applySwcDecoratorConfig } from './plugins/swc'; diff --git a/packages/core/src/provider/build.ts b/packages/core/src/provider/build.ts index d578202df5..dad9cfcf95 100644 --- a/packages/core/src/provider/build.ts +++ b/packages/core/src/provider/build.ts @@ -1,10 +1,6 @@ import { rspack } from '@rspack/core'; -import { - getNodeEnv, - onBeforeBuild, - onCompileDone, - setNodeEnv, -} from '../helpers'; +import { getNodeEnv, setNodeEnv } from '../helpers'; +import { registerBuildHook } from '../hooks'; import { logger } from '../logger'; import type { BuildOptions, @@ -42,30 +38,13 @@ export const build = async ( bundlerConfigs = rspackConfigs; } - let isFirstCompile = true; - - const beforeBuild = async () => - await context.hooks.onBeforeBuild.call({ - bundlerConfigs, - environments: context.environments, - isWatch: Boolean(watch), - isFirstCompile, - }); - - const onDone = async (stats: Stats | MultiStats) => { - const p = context.hooks.onAfterBuild.call({ - isFirstCompile, - stats, - environments: context.environments, - isWatch: Boolean(watch), - }); - isFirstCompile = false; - await p; - }; - - onBeforeBuild(compiler, beforeBuild, watch); - - onCompileDone(compiler, onDone, rspack.MultiStats); + registerBuildHook({ + context, + bundlerConfigs, + compiler, + isWatch: Boolean(watch), + MultiStatsCtor: rspack.MultiStats, + }); if (watch) { const watching = compiler.watch({}, (err) => { diff --git a/packages/core/src/provider/createCompiler.ts b/packages/core/src/provider/createCompiler.ts index 852bcae294..ff5629e586 100644 --- a/packages/core/src/provider/createCompiler.ts +++ b/packages/core/src/provider/createCompiler.ts @@ -7,14 +7,15 @@ import { isDev, isProd, isSatisfyRspackVersion, - onCompileDone, prettyTime, rspackMinVersion, } from '../helpers'; +import { onCompileDone } from '../hooks'; import { logger } from '../logger'; import type { DevMiddlewareAPI } from '../server/devMiddleware'; import type { DevConfig, + EnvironmentContext, InternalContext, MultiStats, Rspack, @@ -118,7 +119,34 @@ export async function createCompiler({ isFirstCompile = false; }; - onCompileDone(compiler, done, rspack.MultiStats); + const environmentArr = Object.values(context.environments).reduce< + EnvironmentContext[] + >((prev, curr) => { + prev[curr.index] = curr; + return prev; + }, []); + + const onEnvironmentDone = async (index: number, stats: Stats) => { + if (isDev()) { + await context.hooks.onDevCompileEnvironmentDone.callInEnvironment({ + environment: environmentArr[index].name, + args: [ + { + isFirstCompile, + stats, + environment: environmentArr[index], + }, + ], + }); + } + }; + + onCompileDone({ + compiler, + onDone: done, + onEnvironmentDone, + MultiStatsCtor: rspack.MultiStats, + }); await context.hooks.onAfterCreateCompiler.call({ compiler, diff --git a/packages/core/src/server/devServer.ts b/packages/core/src/server/devServer.ts index a6050eb223..6e99a7dd34 100644 --- a/packages/core/src/server/devServer.ts +++ b/packages/core/src/server/devServer.ts @@ -233,38 +233,34 @@ export async function createDevServer< }; const environmentAPI = Object.fromEntries( - Object.entries(options.context.environments).map( - ([name, environment], index) => { - return [ - name, - { - getStats: async () => { - if (!runCompile) { - throw new Error( - "can't get stats info when runCompile is false", - ); - } - await waitFirstCompileDone; - return lastStats[index]; - }, - loadBundle: async (entryName: string) => { - await waitFirstCompileDone; - return loadBundle(lastStats[index], entryName, { - readFileSync, - environment, - }); - }, - getTransformedHtml: async (entryName: string) => { - await waitFirstCompileDone; - return getTransformedHtml(entryName, { - readFileSync, - environment, - }); - }, + Object.entries(options.context.environments).map(([name, environment]) => { + return [ + name, + { + getStats: async () => { + if (!runCompile) { + throw new Error("can't get stats info when runCompile is false"); + } + await waitFirstCompileDone; + return lastStats[environment.index]; + }, + loadBundle: async (entryName: string) => { + await waitFirstCompileDone; + return loadBundle(lastStats[environment.index], entryName, { + readFileSync, + environment, + }); + }, + getTransformedHtml: async (entryName: string) => { + await waitFirstCompileDone; + return getTransformedHtml(entryName, { + readFileSync, + environment, + }); }, - ]; - }, - ), + }, + ]; + }), ); const devMiddlewares = await getMiddlewares({ diff --git a/packages/core/src/types/hooks.ts b/packages/core/src/types/hooks.ts index 5af9549524..bb6f0664d7 100644 --- a/packages/core/src/types/hooks.ts +++ b/packages/core/src/types/hooks.ts @@ -13,24 +13,49 @@ import type { MultiStats, Stats } from './stats'; import type { HtmlRspackPlugin, WebpackConfig } from './thirdParty'; import type { MaybePromise, NodeEnv } from './utils'; -export type OnBeforeBuildFn = (params: { +type BuildCommonParams = { isFirstCompile: boolean; isWatch: boolean; - bundlerConfigs?: B extends 'rspack' - ? Rspack.Configuration[] - : WebpackConfig[]; - environments: Record; -}) => MaybePromise; +}; -export type OnAfterBuildFn = (params: { - isFirstCompile: boolean; - isWatch: boolean; - stats?: Stats | MultiStats; - environments: Record; -}) => MaybePromise; +export type OnBeforeEnvironmentBuildFn = ( + params: BuildCommonParams & { + environment: EnvironmentContext; + bundlerConfig?: B extends 'rspack' ? Rspack.Configuration : WebpackConfig; + }, +) => MaybePromise; + +export type OnBeforeBuildFn = ( + params: BuildCommonParams & { + environments: Record; + bundlerConfigs?: B extends 'rspack' + ? Rspack.Configuration[] + : WebpackConfig[]; + }, +) => MaybePromise; + +export type OnAfterEnvironmentBuildFn = ( + params: BuildCommonParams & { + stats?: Stats; + environment: EnvironmentContext; + }, +) => MaybePromise; + +export type OnAfterBuildFn = ( + params: BuildCommonParams & { + stats?: Stats | MultiStats; + environments: Record; + }, +) => MaybePromise; export type OnCloseDevServerFn = () => MaybePromise; +export type OnDevCompileEnvironmentDoneFn = (params: { + isFirstCompile: boolean; + stats: Stats; + environment: EnvironmentContext; +}) => MaybePromise; + export type OnDevCompileDoneFn = (params: { isFirstCompile: boolean; stats: Stats | MultiStats; diff --git a/packages/core/src/types/plugin.ts b/packages/core/src/types/plugin.ts index eee54bc46f..f491e2e35f 100644 --- a/packages/core/src/types/plugin.ts +++ b/packages/core/src/types/plugin.ts @@ -21,14 +21,17 @@ import type { ModifyRsbuildConfigFn, OnAfterBuildFn, OnAfterCreateCompilerFn, + OnAfterEnvironmentBuildFn, OnAfterStartDevServerFn, OnAfterStartProdServerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, + OnBeforeEnvironmentBuildFn, OnBeforeStartDevServerFn, OnBeforeStartProdServerFn, OnCloseDevServerFn, OnDevCompileDoneFn, + OnDevCompileEnvironmentDoneFn, OnExitFn, } from './hooks'; import type { RsbuildTarget } from './rsbuild'; @@ -385,7 +388,10 @@ export type RsbuildPluginAPI = Readonly<{ onExit: PluginHook; onAfterBuild: PluginHook; onBeforeBuild: PluginHook; + onAfterEnvironmentBuild: PluginHook; + onBeforeEnvironmentBuild: PluginHook; onCloseDevServer: PluginHook; + onDevCompileEnvironmentDone: PluginHook; onDevCompileDone: PluginHook; onAfterStartDevServer: PluginHook; onBeforeStartDevServer: PluginHook; diff --git a/packages/core/tests/__snapshots__/hooks.test.ts.snap b/packages/core/tests/__snapshots__/hooks.test.ts.snap index dadd36275a..941c599dc2 100644 --- a/packages/core/tests/__snapshots__/hooks.test.ts.snap +++ b/packages/core/tests/__snapshots__/hooks.test.ts.snap @@ -20,5 +20,8 @@ exports[`initHooks > should init hooks correctly 1`] = ` "modifyWebpackConfig", "modifyRsbuildConfig", "modifyEnvironmentConfig", + "onBeforeEnvironmentBuild", + "onAfterEnvironmentBuild", + "onDevCompileEnvironmentDone", ] `; diff --git a/website/docs/en/plugins/dev/hooks.mdx b/website/docs/en/plugins/dev/hooks.mdx index 6231419fab..2a726bdd10 100644 --- a/website/docs/en/plugins/dev/hooks.mdx +++ b/website/docs/en/plugins/dev/hooks.mdx @@ -22,13 +22,16 @@ Called only when running the `rsbuild dev` command or the `rsbuild.startDevServe - [onBeforeStartDevServer](#onbeforestartdevserver): Called before starting the dev server. - [onAfterStartDevServer](#onafterstartdevserver): Called after starting the dev server. - [onCloseDevServer](#onclosedevserver): Called when the dev server is closed. +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone): Called after each build of a single environment during development. - [onDevCompileDone](#ondevcompiledone): Called after each build during development. ### Build Hooks Called only when running the `rsbuild build` command or the `rsbuild.build()` method. +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild): Called before running the production build of a single environment. - [onBeforeBuild](#onbeforebuild): Called before running the production build. +- [onAfterEnvironmentBuild](#onafterenvironmentbuild): Called after running the production build of a single environment. You can get the build result information. - [onAfterBuild](#onafterbuild): Called after running the production build. You can get the build result information. ### Preview Hooks @@ -53,6 +56,7 @@ When the `rsbuild dev` command or `rsbuild.startDevServer()` method is executed, - [onAfterCreateCompiler](#onaftercreatecompiler) - [onAfterStartDevServer](#onafterstartdevserver) - [modifyHTMLTags](#modifyhtmltags) +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) - [onDevCompileDone](#ondevcompiledone) - [onCloseDevServer](#onclosedevserver) - [onExit](#onexit) @@ -60,6 +64,7 @@ When the `rsbuild dev` command or `rsbuild.startDevServer()` method is executed, When rebuilding, the following hooks will be triggered again: - [modifyHTMLTags](#modifyhtmltags) +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) - [onDevCompileDone](#ondevcompiledone) ### Build Hooks @@ -72,16 +77,20 @@ When the `rsbuild build` command or `rsbuild.build()` method is executed, Rsbuil - [modifyRspackConfig](#modifyrspackconfig) - [onBeforeCreateCompiler](#onbeforecreatecompiler) - [onAfterCreateCompiler](#onaftercreatecompiler) +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) +- [onAfterEnvironmentBuild](#onafterenvironmentbuild) - [onAfterBuild](#onafterbuild) - [onExit](#onexit) When rebuilding, the following hooks will be triggered again: +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) - [onAfterBuild](#onafterbuild) +- [onAfterEnvironmentBuild](#onafterenvironmentbuild) ### Preview Hooks @@ -123,6 +132,9 @@ Correspondingly, there are some plugin hooks that are related to the current env - [modifyBundlerChain](#modifybundlerchain) - [modifyRspackConfig](#modifyrspackconfig) - [modifyHTMLTags](#modifyhtmltags) +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) +- [onAfterEnvironmentBuild](#onafterenvironmentbuild) +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) ## Callback Order @@ -526,6 +538,27 @@ const myPlugin = () => ({ ## Build Hooks +### onBeforeEnvironmentBuild + +import OnBeforeEnvironmentBuild from '@en/shared/onBeforeEnvironmentBuild.mdx'; + + + +- **Example:** + +```ts +const myPlugin = () => ({ + setup: (api) => { + api.onBeforeEnvironmentBuild(({ bundlerConfig, environment }) => { + console.log( + `the bundler config for the ${environment.name} is `, + bundlerConfig, + ); + }); + }, +}); +``` + ### onBeforeBuild import OnBeforeBuild from '@en/shared/onBeforeBuild.mdx'; @@ -544,6 +577,24 @@ const myPlugin = () => ({ }); ``` +### onAfterEnvironmentBuild + +import OnAfterEnvironmentBuild from '@en/shared/onAfterEnvironmentBuild.mdx'; + + + +- **Example:** + +```ts +const myPlugin = () => ({ + setup: (api) => { + api.onAfterEnvironmentBuild(({ isFirstCompile, stats }) => { + console.log(stats?.toJson(), isFirstCompile); + }); + }, +}); +``` + ### onAfterBuild import OnAfterBuild from '@en/shared/onAfterBuild.mdx'; @@ -601,6 +652,28 @@ const myPlugin = () => ({ }); ``` +### onDevCompileEnvironmentDone + +import OnDevCompileEnvironmentDone from '@en/shared/onDevCompileEnvironmentDone.mdx'; + + + +- **Example:** + +```ts +const myPlugin = () => ({ + setup: (api) => { + api.onDevCompileEnvironmentDone(({ isFirstCompile }) => { + if (isFirstCompile) { + console.log('first compile!'); + } else { + console.log('re-compile!'); + } + }); + }, +}); +``` + ### onDevCompileDone import OnDevCompileDone from '@en/shared/onDevCompileDone.mdx'; diff --git a/website/docs/en/shared/onAfterEnvironmentBuild.mdx b/website/docs/en/shared/onAfterEnvironmentBuild.mdx new file mode 100644 index 0000000000..59ac44233d --- /dev/null +++ b/website/docs/en/shared/onAfterEnvironmentBuild.mdx @@ -0,0 +1,16 @@ +`onAfterEnvironmentBuild` is a callback function that is triggered after running the production build of a single environment. You can access the build result information via the [stats](https://webpack.js.org/api/node/#stats-object) parameter. + +Moreover, you can use `isWatch` to determine whether it is watch mode, and use `isFirstCompile` to determine whether it is the first build on watch mode. + +- **Type:** + +```ts +function OnAfterEnvironmentBuild( + callback: (params: { + isFirstCompile: boolean; + isWatch: boolean; + stats?: Stats; + environment: EnvironmentContext; + }) => Promise | void, +): void; +``` diff --git a/website/docs/en/shared/onBeforeEnvironmentBuild.mdx b/website/docs/en/shared/onBeforeEnvironmentBuild.mdx new file mode 100644 index 0000000000..6f0243c254 --- /dev/null +++ b/website/docs/en/shared/onBeforeEnvironmentBuild.mdx @@ -0,0 +1,18 @@ +`onBeforeEnvironmentBuild` is a callback function that is triggered before the production build is executed of a single environment. + +You can access the Rspack configuration array through the `bundlerConfigs` parameter. The array may contain one or more [Rspack configurations](https://rspack.dev/config/). It depends on whether multiple [environments](/config/environments) are configured. + +Moreover, you can use `isWatch` to determine whether it is watch mode, and use `isFirstCompile` to determine whether it is the first build on watch mode. + +- **Type:** + +```ts +function OnBeforeEnvironmentBuild( + callback: (params: { + isWatch: boolean; + isFirstCompile: boolean; + bundlerConfig?: RspackConfig | WebpackConfig; + environment: EnvironmentContext; + }) => Promise | void, +): void; +``` diff --git a/website/docs/en/shared/onDevCompileEnvironmentDone.mdx b/website/docs/en/shared/onDevCompileEnvironmentDone.mdx new file mode 100644 index 0000000000..0149a8ea38 --- /dev/null +++ b/website/docs/en/shared/onDevCompileEnvironmentDone.mdx @@ -0,0 +1,13 @@ +Called after each build of a single environment during development, you can use `isFirstCompile` to determine whether it is the first build. + +- **Type:** + +```ts +function OnDevCompileEnvironmentDone( + callback: (params: { + isFirstCompile: boolean; + stats: Stats; + environment: EnvironmentContext; + }) => Promise | void, +): void; +``` diff --git a/website/docs/zh/plugins/dev/hooks.mdx b/website/docs/zh/plugins/dev/hooks.mdx index 99d025fb22..d4c293a932 100644 --- a/website/docs/zh/plugins/dev/hooks.mdx +++ b/website/docs/zh/plugins/dev/hooks.mdx @@ -21,6 +21,7 @@ - [onBeforeStartDevServer](#onbeforestartdevserver):在启动开发服务器前调用。 - [onAfterStartDevServer](#onafterstartdevserver):在启动开发服务器后调用。 +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone): 在每次单个 environment 的开发环境构建结束后调用。 - [onDevCompileDone](#ondevcompiledone):在每次开发环境构建结束后调用。 - [onCloseDevServer](#onclosedevserver):在关闭开发服务器时调用。 @@ -28,7 +29,9 @@ 仅在执行 `rsbuild build` 命令或 `rsbuild.build()` 方法时调用。 +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild): 在执行单个 environment 的生产环境构建前调用。 - [onBeforeBuild](#onbeforebuild):在执行生产环境构建前调用。 +- [onAfterEnvironmentBuild](#onafterenvironmentbuild): 在执行单个 environment 的生产环境构建后调用,可以获取到单个 environment 的构建结果信息。 - [onAfterBuild](#onafterbuild):在执行生产环境构建后调用,可以获取到构建结果信息。 ### Preview Hooks @@ -53,6 +56,7 @@ - [onAfterCreateCompiler](#onaftercreatecompiler) - [onAfterStartDevServer](#onafterstartdevserver) - [modifyHTMLTags](#modifyhtmltags) +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) - [onDevCompileDone](#ondevcompiledone) - [onCloseDevServer](#onclosedevserver) - [onExit](#onexit) @@ -60,6 +64,7 @@ 当 rebuild 时,以下 hooks 会再次触发: - [modifyHTMLTags](#modifyhtmltags) +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) - [onDevCompileDone](#ondevcompiledone) ### Build Hooks @@ -72,15 +77,19 @@ - [modifyRspackConfig](#modifyrspackconfig) - [onBeforeCreateCompiler](#onbeforecreatecompiler) - [onAfterCreateCompiler](#onaftercreatecompiler) +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) +- [onAfterEnvironmentBuild](#onafterenvironmentbuild) - [onAfterBuild](#onafterbuild) - [onExit](#onexit) 当 rebuild 时,以下 hooks 会再次触发: +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) +- [onAfterEnvironmentBuild](#onafterenvironmentbuild) - [onAfterBuild](#onafterbuild) ### Preview Hooks @@ -123,6 +132,9 @@ - [modifyBundlerChain](#modifybundlerchain) - [modifyRspackConfig](#modifyrspackconfig) - [modifyHTMLTags](#modifyhtmltags) +- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) +- [onAfterEnvironmentBuild](#onafterenvironmentbuild) +- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) ## 回调函数顺序 @@ -522,6 +534,27 @@ const myPlugin = () => ({ ## Build Hooks +### onBeforeEnvironmentBuild + +import OnBeforeEnvironmentBuild from '@zh/shared/onBeforeEnvironmentBuild.mdx'; + + + +- **示例:** + +```ts +const myPlugin = () => ({ + setup: (api) => { + api.onBeforeEnvironmentBuild(({ bundlerConfig, environment }) => { + console.log( + `the bundler config for the ${environment.name} is `, + bundlerConfig, + ); + }); + }, +}); +``` + ### onBeforeBuild import OnBeforeBuild from '@zh/shared/onBeforeBuild.mdx'; @@ -540,6 +573,24 @@ const myPlugin = () => ({ }); ``` +### onAfterEnvironmentBuild + +import OnAfterEnvironmentBuild from '@zh/shared/onAfterEnvironmentBuild.mdx'; + + + +- **示例:** + +```ts +const myPlugin = () => ({ + setup: (api) => { + api.onAfterEnvironmentBuild(({ isFirstCompile, stats }) => { + console.log(stats?.toJson(), isFirstCompile); + }); + }, +}); +``` + ### onAfterBuild import OnAfterBuild from '@zh/shared/onAfterBuild.mdx'; @@ -597,6 +648,28 @@ const myPlugin = () => ({ }); ``` +### onDevCompileEnvironmentDone + +import OnDevCompileEnvironmentDone from '@zh/shared/onDevCompileEnvironmentDone.mdx'; + + + +- **示例:** + +```ts +const myPlugin = () => ({ + setup: (api) => { + api.onDevCompileEnvironmentDone(({ isFirstCompile }) => { + if (isFirstCompile) { + console.log('first compile!'); + } else { + console.log('re-compile!'); + } + }); + }, +}); +``` + ### onDevCompileDone import OnDevCompileDone from '@zh/shared/onDevCompileDone.mdx'; diff --git a/website/docs/zh/shared/onAfterEnvironmentBuild.mdx b/website/docs/zh/shared/onAfterEnvironmentBuild.mdx new file mode 100644 index 0000000000..bd34b99301 --- /dev/null +++ b/website/docs/zh/shared/onAfterEnvironmentBuild.mdx @@ -0,0 +1,16 @@ +`onAfterEnvironmentBuild` 是在执行单个 environment 的生产环境构建后触发的回调函数,你可以通过 [stats](https://webpack.js.org/api/node/#stats-object) 参数获取到构建结果信息。 + +另外,你可以通过 `isWatch` 判断是否是 watch 模式,并在 watch 模式下通过 `isFirstCompile` 来判断是否为首次构建。 + +- **类型:** + +```ts +function OnAfterEnvironmentBuild( + callback: (params: { + isFirstCompile: boolean; + isWatch: boolean; + stats?: Stats; + environment: EnvironmentContext; + }) => Promise | void, +): void; +``` diff --git a/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx b/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx new file mode 100644 index 0000000000..55105754e4 --- /dev/null +++ b/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx @@ -0,0 +1,18 @@ +`onBeforeEnvironmentBuild` 是在执行单个 environment 的生产环境构建前触发的回调函数。 + +你可以通过 `bundlerConfig` 参数获取到当前 environment 对应的 Rspack 配置(https://rspack.dev/config/)。 + +另外,你可以通过 `isWatch` 判断是否是 watch 模式,并在 watch 模式下通过 `isFirstCompile` 来判断是否为首次构建。 + +- **类型:** + +```ts +function OnBeforeEnvironmentBuild( + callback: (params: { + isWatch: boolean; + isFirstCompile: boolean; + bundlerConfig?: RspackConfig | WebpackConfig; + environment: EnvironmentContext; + }) => Promise | void, +): void; +``` diff --git a/website/docs/zh/shared/onDevCompileEnvironmentDone.mdx b/website/docs/zh/shared/onDevCompileEnvironmentDone.mdx new file mode 100644 index 0000000000..352113a8d7 --- /dev/null +++ b/website/docs/zh/shared/onDevCompileEnvironmentDone.mdx @@ -0,0 +1,13 @@ +在每次单个 environment 的开发环境构建结束后调用,你可以通过 `isFirstCompile` 来判断是否为首次构建。 + +- **类型:** + +```ts +function OnDevCompileEnvironmentDone( + callback: (params: { + isFirstCompile: boolean; + stats: Stats; + environment: EnvironmentContext; + }) => Promise | void, +): void; +``` From 47f7d8575778fc7cb817b8aad2b576c71361037a Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Mon, 5 Aug 2024 16:44:07 +0800 Subject: [PATCH 02/15] chore: onBeforeEnvironmentCompile & onAfterEnvironmentCompile --- .../plugin-hooks/environments.test.ts | 32 +++--- .../plugin-api/plugin-hooks/index.test.ts | 24 ++-- packages/compat/webpack/src/createCompiler.ts | 56 +++------ packages/compat/webpack/src/shared.ts | 4 +- packages/core/src/hooks.ts | 107 ++++++++++++++---- packages/core/src/initHooks.ts | 20 ++-- packages/core/src/initPlugins.ts | 13 +-- packages/core/src/internal.ts | 2 +- packages/core/src/provider/createCompiler.ts | 53 +++------ packages/core/src/types/hooks.ts | 20 ++-- packages/core/src/types/plugin.ts | 10 +- .../tests/__snapshots__/hooks.test.ts.snap | 5 +- website/docs/en/plugins/dev/hooks.mdx | 62 +++++----- .../en/shared/onAfterEnvironmentBuild.mdx | 6 +- ...ild.mdx => onBeforeEnvironmentCompile.mdx} | 6 +- .../en/shared/onDevCompileEnvironmentDone.mdx | 13 --- website/docs/zh/plugins/dev/hooks.mdx | 62 +++++----- .../zh/shared/onAfterEnvironmentBuild.mdx | 6 +- .../zh/shared/onBeforeEnvironmentBuild.mdx | 6 +- 19 files changed, 247 insertions(+), 260 deletions(-) rename website/docs/en/shared/{onBeforeEnvironmentBuild.mdx => onBeforeEnvironmentCompile.mdx} (60%) delete mode 100644 website/docs/en/shared/onDevCompileEnvironmentDone.mdx diff --git a/e2e/cases/plugin-api/plugin-hooks/environments.test.ts b/e2e/cases/plugin-api/plugin-hooks/environments.test.ts index 528eb57319..9f18b7b700 100644 --- a/e2e/cases/plugin-api/plugin-hooks/environments.test.ts +++ b/e2e/cases/plugin-api/plugin-hooks/environments.test.ts @@ -1,4 +1,4 @@ -import { gotoPage, rspackOnlyTest } from '@e2e/helper'; +import { getRandomPort, gotoPage, rspackOnlyTest } from '@e2e/helper'; import { expect } from '@playwright/test'; import { type RsbuildPlugin, createRsbuild } from '@rsbuild/core'; @@ -45,12 +45,12 @@ const createPlugin = () => { api.onAfterBuild(() => { names.push('AfterBuild'); }); - api.onBeforeEnvironmentBuild(({ environment }) => { - names.push(`BeforeEnvironmentBuild ${environment.name}`); + api.onBeforeEnvironmentCompile(({ environment }) => { + names.push(`BeforeEnvironmentCompile ${environment.name}`); }); - api.onAfterEnvironmentBuild(({ stats, environment }) => { + api.onAfterEnvironmentCompile(({ stats, environment }) => { expect(stats?.compilation.name).toBe(environment.name); - names.push(`AfterEnvironmentBuild ${environment.name}`); + names.push(`AfterEnvironmentCompile ${environment.name}`); }); api.onBeforeStartProdServer(() => { names.push('BeforeStartProdServer'); @@ -64,10 +64,6 @@ const createPlugin = () => { api.onDevCompileDone(() => { names.push('OnDevCompileDone'); }); - api.onDevCompileEnvironmentDone(({ stats, environment }) => { - expect(stats?.compilation.name).toBe(environment.name); - names.push(`DevCompileEnvironmentDone ${environment.name}`); - }); }, }; @@ -105,10 +101,10 @@ rspackOnlyTest( 'ModifyBundlerConfig web', 'BeforeCreateCompiler', 'AfterCreateCompiler', - 'BeforeEnvironmentBuild web', + 'BeforeEnvironmentCompile web', 'BeforeBuild', 'ModifyHTMLTags web', - 'AfterEnvironmentBuild web', + 'AfterEnvironmentCompile web', 'AfterBuild', ]); @@ -119,10 +115,10 @@ rspackOnlyTest( 'ModifyBundlerConfig node', 'BeforeCreateCompiler', 'AfterCreateCompiler', - 'BeforeEnvironmentBuild node', + 'BeforeEnvironmentCompile node', 'BeforeBuild', 'ModifyHTMLTags node', - 'AfterEnvironmentBuild node', + 'AfterEnvironmentCompile node', 'AfterBuild', ]); }, @@ -132,12 +128,16 @@ rspackOnlyTest( 'should run plugin hooks correctly when running startDevServer with multiple environments', async ({ page }) => { process.env.NODE_ENV = 'development'; + const port = await getRandomPort(); const { plugin, names } = createPlugin(); const rsbuild = await createRsbuild({ cwd: __dirname, rsbuildConfig: { plugins: [plugin], + server: { + port, + }, environments: { web: {}, node: {}, @@ -163,9 +163,10 @@ rspackOnlyTest( 'ModifyBundlerConfig web', 'BeforeCreateCompiler', 'AfterCreateCompiler', + 'BeforeEnvironmentCompile web', 'AfterStartDevServer', 'ModifyHTMLTags web', - 'DevCompileEnvironmentDone web', + 'AfterEnvironmentCompile web', 'OnDevCompileDone', 'OnCloseDevServer', ]); @@ -178,9 +179,10 @@ rspackOnlyTest( 'ModifyBundlerConfig node', 'BeforeCreateCompiler', 'AfterCreateCompiler', + 'BeforeEnvironmentCompile node', 'AfterStartDevServer', 'ModifyHTMLTags node', - 'DevCompileEnvironmentDone node', + 'AfterEnvironmentCompile node', 'OnDevCompileDone', 'OnCloseDevServer', ]); diff --git a/e2e/cases/plugin-api/plugin-hooks/index.test.ts b/e2e/cases/plugin-api/plugin-hooks/index.test.ts index adc3c32e4d..b380038b74 100644 --- a/e2e/cases/plugin-api/plugin-hooks/index.test.ts +++ b/e2e/cases/plugin-api/plugin-hooks/index.test.ts @@ -1,4 +1,4 @@ -import { gotoPage, rspackOnlyTest } from '@e2e/helper'; +import { getRandomPort, gotoPage, rspackOnlyTest } from '@e2e/helper'; import { expect } from '@playwright/test'; import { type RsbuildPlugin, createRsbuild } from '@rsbuild/core'; @@ -45,11 +45,11 @@ const createPlugin = () => { api.onAfterBuild(() => { names.push('AfterBuild'); }); - api.onBeforeEnvironmentBuild(() => { - names.push('BeforeEnvironmentBuild'); + api.onBeforeEnvironmentCompile(() => { + names.push('BeforeEnvironmentCompile'); }); - api.onAfterEnvironmentBuild(() => { - names.push('AfterEnvironmentBuild'); + api.onAfterEnvironmentCompile(() => { + names.push('AfterEnvironmentCompile'); }); api.onBeforeStartProdServer(() => { names.push('BeforeStartProdServer'); @@ -63,9 +63,6 @@ const createPlugin = () => { api.onDevCompileDone(() => { names.push('OnDevCompileDone'); }); - api.onDevCompileEnvironmentDone(() => { - names.push('DevCompileEnvironmentDone'); - }); }, }; @@ -92,10 +89,10 @@ rspackOnlyTest( 'ModifyBundlerConfig', 'BeforeCreateCompiler', 'AfterCreateCompiler', - 'BeforeEnvironmentBuild', + 'BeforeEnvironmentCompile', 'BeforeBuild', 'ModifyHTMLTags', - 'AfterEnvironmentBuild', + 'AfterEnvironmentCompile', 'AfterBuild', ]); }, @@ -105,12 +102,16 @@ rspackOnlyTest( 'should run plugin hooks correctly when running startDevServer', async ({ page }) => { process.env.NODE_ENV = 'development'; + const port = await getRandomPort(); const { plugin, names } = createPlugin(); const rsbuild = await createRsbuild({ cwd: __dirname, rsbuildConfig: { plugins: [plugin], + server: { + port, + }, }, }); @@ -128,9 +129,10 @@ rspackOnlyTest( 'ModifyBundlerConfig', 'BeforeCreateCompiler', 'AfterCreateCompiler', + 'BeforeEnvironmentCompile', 'AfterStartDevServer', 'ModifyHTMLTags', - 'DevCompileEnvironmentDone', + 'AfterEnvironmentCompile', 'OnDevCompileDone', 'OnCloseDevServer', ]); diff --git a/packages/compat/webpack/src/createCompiler.ts b/packages/compat/webpack/src/createCompiler.ts index cd232f9852..6de3f1758b 100644 --- a/packages/compat/webpack/src/createCompiler.ts +++ b/packages/compat/webpack/src/createCompiler.ts @@ -1,4 +1,4 @@ -import { type EnvironmentContext, type Rspack, logger } from '@rsbuild/core'; +import { type Rspack, logger } from '@rsbuild/core'; import WebpackMultiStats from 'webpack/lib/MultiStats.js'; import { type InitConfigsOptions, initConfigs } from './initConfigs'; import { @@ -6,8 +6,8 @@ import { formatStats, getDevMiddleware, getStatsOptions, + registerDevHook, } from './shared'; -import { onCompileDone } from './shared'; import type { WebpackConfig } from './types'; export async function createCompiler({ @@ -31,9 +31,7 @@ export async function createCompiler({ | Rspack.Compiler | Rspack.MultiCompiler; - let isFirstCompile = true; - - const done = async (stats: unknown) => { + const done = (stats: unknown) => { const { message, level } = formatStats( stats as Rspack.Stats, getStatsOptions(compiler), @@ -45,47 +43,21 @@ export async function createCompiler({ if (level === 'warning') { logger.warn(message); } - - if (process.env.NODE_ENV === 'development') { - await context.hooks.onDevCompileDone.call({ - isFirstCompile, - stats: stats as Rspack.Stats, - environments: context.environments, - }); - } - - isFirstCompile = false; - }; - - const environmentArr = Object.values(context.environments).reduce< - EnvironmentContext[] - >((prev, curr) => { - prev[curr.index] = curr; - return prev; - }, []); - - const onEnvironmentDone = async (index: number, stats: Rspack.Stats) => { - if (process.env.NODE_ENV === 'development') { - await context.hooks.onDevCompileEnvironmentDone.callInEnvironment({ - environment: environmentArr[index].name, - args: [ - { - isFirstCompile, - stats, - environment: environmentArr[index], - }, - ], - }); - } }; - onCompileDone({ - compiler, - onDone: done, - onEnvironmentDone, - MultiStatsCtor: WebpackMultiStats, + compiler.hooks.done.tap('rsbuild:done', (stats: unknown) => { + done(stats); }); + if (process.env.NODE_ENV === 'development') { + registerDevHook({ + compiler, + context, + bundlerConfigs: webpackConfigs as any, + MultiStatsCtor: WebpackMultiStats, + }); + } + await context.hooks.onAfterCreateCompiler.call({ compiler, environments: context.environments, diff --git a/packages/compat/webpack/src/shared.ts b/packages/compat/webpack/src/shared.ts index 6ed405defa..37e1e7404d 100644 --- a/packages/compat/webpack/src/shared.ts +++ b/packages/compat/webpack/src/shared.ts @@ -12,7 +12,7 @@ const { getRsbuildInspectConfig, chainToConfig, modifyBundlerChain, - onCompileDone, + registerDevHook, registerBuildHook, prettyTime, } = __internalHelper; @@ -28,7 +28,7 @@ export { outputInspectConfigFiles, chainToConfig, modifyBundlerChain, - onCompileDone, + registerDevHook, registerBuildHook, prettyTime, getRsbuildInspectConfig, diff --git a/packages/core/src/hooks.ts b/packages/core/src/hooks.ts index c8dfa5102d..1a9ca4a2ed 100644 --- a/packages/core/src/hooks.ts +++ b/packages/core/src/hooks.ts @@ -8,15 +8,15 @@ import type { Stats, } from './types'; -const onBeforeBuild = ({ +const onBeforeCompile = ({ compiler, - beforeBuild, - beforeEnvironmentBuild, + beforeCompile, + beforeEnvironmentCompiler, isWatch, }: { compiler: Rspack.Compiler | Rspack.MultiCompiler; - beforeBuild: () => Promise; - beforeEnvironmentBuild: (buildIndex: number) => Promise; + beforeCompile?: () => Promise; + beforeEnvironmentCompiler: (buildIndex: number) => Promise; isWatch?: boolean; }): void => { const name = 'rsbuild:beforeCompile'; @@ -38,14 +38,14 @@ const onBeforeBuild = ({ compilerDone = true; doneCompilers++; } - // ensure only last compiler done will trigger beforeBuild hook - // avoid other compiler done triggers when executing async beforeEnvironmentBuild hook + // ensure only last compiler done will trigger beforeCompile hook + // avoid other compiler done triggers when executing async beforeEnvironmentCompiler hook const lastCompilerDone = doneCompilers === compilers.length; - await beforeEnvironmentBuild(index); + await beforeEnvironmentCompiler(index); if (lastCompilerDone) { - await beforeBuild(); + await beforeCompile?.(); } }, ); @@ -61,8 +61,8 @@ const onBeforeBuild = ({ (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( name, async () => { - await beforeEnvironmentBuild(0); - await beforeBuild(); + await beforeEnvironmentCompiler(0); + await beforeCompile?.(); }, ); } @@ -145,7 +145,7 @@ export const registerBuildHook = ({ return prev; }, []); - const beforeBuild = async () => + const beforeCompile = async () => await context.hooks.onBeforeBuild.call({ bundlerConfigs, environments: context.environments, @@ -153,8 +153,8 @@ export const registerBuildHook = ({ isFirstCompile, }); - const beforeEnvironmentBuild = async (buildIndex: number) => - await context.hooks.onBeforeEnvironmentBuild.callInEnvironment({ + const beforeEnvironmentCompiler = async (buildIndex: number) => + await context.hooks.onBeforeEnvironmentCompile.callInEnvironment({ environment: environmentArr[buildIndex].name, args: [ { @@ -178,7 +178,7 @@ export const registerBuildHook = ({ }; const onEnvironmentDone = async (buildIndex: number, stats: Stats) => { - const p = context.hooks.onAfterEnvironmentBuild.callInEnvironment({ + await context.hooks.onAfterEnvironmentCompile.callInEnvironment({ environment: environmentArr[buildIndex].name, args: [ { @@ -189,15 +189,84 @@ export const registerBuildHook = ({ }, ], }); + }; + + onBeforeCompile({ + compiler, + beforeCompile, + beforeEnvironmentCompiler, + isWatch, + }); + + onCompileDone({ + compiler, + onDone, + onEnvironmentDone, + MultiStatsCtor, + }); +}; + +export const registerDevHook = ({ + context, + compiler, + bundlerConfigs, + MultiStatsCtor, +}: { + bundlerConfigs?: RspackConfig[]; + context: InternalContext; + compiler: Rspack.Compiler | Rspack.MultiCompiler; + MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; +}): void => { + let isFirstCompile = true; + + const environmentArr = Object.values(context.environments).reduce< + EnvironmentContext[] + >((prev, curr) => { + prev[curr.index] = curr; + return prev; + }, []); + + const beforeEnvironmentCompiler = async (buildIndex: number) => + await context.hooks.onBeforeEnvironmentCompile.callInEnvironment({ + environment: environmentArr[buildIndex].name, + args: [ + { + bundlerConfig: bundlerConfigs?.[buildIndex] as Rspack.Configuration, + environment: environmentArr[buildIndex], + isWatch: true, + isFirstCompile, + }, + ], + }); + + const onDone = async (stats: Stats | MultiStats) => { + const p = context.hooks.onDevCompileDone.call({ + isFirstCompile, + stats, + environments: context.environments, + }); isFirstCompile = false; await p; }; - onBeforeBuild({ + const onEnvironmentDone = async (buildIndex: number, stats: Stats) => { + await context.hooks.onAfterEnvironmentCompile.callInEnvironment({ + environment: environmentArr[buildIndex].name, + args: [ + { + isFirstCompile, + stats, + environment: environmentArr[buildIndex], + isWatch: true, + }, + ], + }); + }; + + onBeforeCompile({ compiler, - beforeBuild, - beforeEnvironmentBuild, - isWatch, + beforeEnvironmentCompiler, + isWatch: true, }); onCompileDone({ diff --git a/packages/core/src/initHooks.ts b/packages/core/src/initHooks.ts index 12685e5c9e..afea900d64 100644 --- a/packages/core/src/initHooks.ts +++ b/packages/core/src/initHooks.ts @@ -13,17 +13,16 @@ import type { ModifyWebpackConfigFn, OnAfterBuildFn, OnAfterCreateCompilerFn, - OnAfterEnvironmentBuildFn, + OnAfterEnvironmentCompileFn, OnAfterStartDevServerFn, OnAfterStartProdServerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, - OnBeforeEnvironmentBuildFn, + OnBeforeEnvironmentCompile, OnBeforeStartDevServerFn, OnBeforeStartProdServerFn, OnCloseDevServerFn, OnDevCompileDoneFn, - OnDevCompileEnvironmentDoneFn, OnExitFn, } from './types'; @@ -165,9 +164,8 @@ export function initHooks(): { modifyWebpackConfig: EnvironmentAsyncHook; modifyRsbuildConfig: AsyncHook; modifyEnvironmentConfig: EnvironmentAsyncHook; - onBeforeEnvironmentBuild: EnvironmentAsyncHook; - onAfterEnvironmentBuild: EnvironmentAsyncHook; - onDevCompileEnvironmentDone: EnvironmentAsyncHook; + onBeforeEnvironmentCompile: EnvironmentAsyncHook; + onAfterEnvironmentCompile: EnvironmentAsyncHook; } { return { onExit: createAsyncHook(), @@ -189,12 +187,10 @@ export function initHooks(): { modifyRsbuildConfig: createAsyncHook(), modifyEnvironmentConfig: createEnvironmentAsyncHook(), - onBeforeEnvironmentBuild: - createEnvironmentAsyncHook(), - onAfterEnvironmentBuild: - createEnvironmentAsyncHook(), - onDevCompileEnvironmentDone: - createEnvironmentAsyncHook(), + onBeforeEnvironmentCompile: + createEnvironmentAsyncHook(), + onAfterEnvironmentCompile: + createEnvironmentAsyncHook(), }; } diff --git a/packages/core/src/initPlugins.ts b/packages/core/src/initPlugins.ts index c9d6241f69..e03441c944 100644 --- a/packages/core/src/initPlugins.ts +++ b/packages/core/src/initPlugins.ts @@ -319,18 +319,13 @@ export function initPluginAPI({ environment, handler, }), - onAfterEnvironmentBuild: (handler) => - hooks.onAfterEnvironmentBuild.tapEnvironment({ + onAfterEnvironmentCompile: (handler) => + hooks.onAfterEnvironmentCompile.tapEnvironment({ environment, handler, }), - onBeforeEnvironmentBuild: (handler) => - hooks.onBeforeEnvironmentBuild.tapEnvironment({ - environment, - handler, - }), - onDevCompileEnvironmentDone: (handler) => - hooks.onDevCompileEnvironmentDone.tapEnvironment({ + onBeforeEnvironmentCompile: (handler) => + hooks.onBeforeEnvironmentCompile.tapEnvironment({ environment, handler, }), diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index 9a471daf02..ab71975c70 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -17,7 +17,7 @@ export { export type { InternalContext } from './types'; export { setHTMLPlugin, getHTMLPlugin } from './pluginHelper'; export { formatStats, getStatsOptions, prettyTime } from './helpers'; -export { registerBuildHook, onCompileDone } from './hooks'; +export { registerBuildHook, registerDevHook, onCompileDone } from './hooks'; export { getChainUtils, getConfigUtils } from './provider/rspackConfig'; export { chainToConfig, modifyBundlerChain } from './configChain'; export { applySwcDecoratorConfig } from './plugins/swc'; diff --git a/packages/core/src/provider/createCompiler.ts b/packages/core/src/provider/createCompiler.ts index ff5629e586..8e02f6d6e3 100644 --- a/packages/core/src/provider/createCompiler.ts +++ b/packages/core/src/provider/createCompiler.ts @@ -10,12 +10,11 @@ import { prettyTime, rspackMinVersion, } from '../helpers'; -import { onCompileDone } from '../hooks'; +import { registerDevHook } from '../hooks'; import { logger } from '../logger'; import type { DevMiddlewareAPI } from '../server/devMiddleware'; import type { DevConfig, - EnvironmentContext, InternalContext, MultiStats, Rspack, @@ -50,7 +49,6 @@ export async function createCompiler({ ? rspack(rspackConfigs[0]) : rspack(rspackConfigs); - let isFirstCompile = true; let isVersionLogged = false; let isCompiling = false; @@ -73,7 +71,7 @@ export async function createCompiler({ compiler.hooks.run.tap('rsbuild:run', logRspackVersion); } - const done = async (stats: Stats | MultiStats) => { + const done = (stats: Stats | MultiStats) => { const statsJson = stats.toJson({ all: false, timings: true, @@ -107,47 +105,22 @@ export async function createCompiler({ logger.warn(message); } - if (isDev()) { - await context.hooks.onDevCompileDone.call({ - isFirstCompile, - stats: stats, - environments: context.environments, - }); - } - isCompiling = false; - isFirstCompile = false; - }; - - const environmentArr = Object.values(context.environments).reduce< - EnvironmentContext[] - >((prev, curr) => { - prev[curr.index] = curr; - return prev; - }, []); - - const onEnvironmentDone = async (index: number, stats: Stats) => { - if (isDev()) { - await context.hooks.onDevCompileEnvironmentDone.callInEnvironment({ - environment: environmentArr[index].name, - args: [ - { - isFirstCompile, - stats, - environment: environmentArr[index], - }, - ], - }); - } }; - onCompileDone({ - compiler, - onDone: done, - onEnvironmentDone, - MultiStatsCtor: rspack.MultiStats, + compiler.hooks.done.tap('rsbuild:done', (stats: Stats | MultiStats) => { + done(stats); }); + if (isDev()) { + registerDevHook({ + context, + compiler, + bundlerConfigs: rspackConfigs, + MultiStatsCtor: rspack.MultiStats, + }); + } + await context.hooks.onAfterCreateCompiler.call({ compiler, environments: context.environments, diff --git a/packages/core/src/types/hooks.ts b/packages/core/src/types/hooks.ts index bb6f0664d7..f85536f53c 100644 --- a/packages/core/src/types/hooks.ts +++ b/packages/core/src/types/hooks.ts @@ -13,20 +13,20 @@ import type { MultiStats, Stats } from './stats'; import type { HtmlRspackPlugin, WebpackConfig } from './thirdParty'; import type { MaybePromise, NodeEnv } from './utils'; -type BuildCommonParams = { +type CompileCommonParams = { isFirstCompile: boolean; isWatch: boolean; }; -export type OnBeforeEnvironmentBuildFn = ( - params: BuildCommonParams & { +export type OnBeforeEnvironmentCompile = ( + params: CompileCommonParams & { environment: EnvironmentContext; bundlerConfig?: B extends 'rspack' ? Rspack.Configuration : WebpackConfig; }, ) => MaybePromise; export type OnBeforeBuildFn = ( - params: BuildCommonParams & { + params: CompileCommonParams & { environments: Record; bundlerConfigs?: B extends 'rspack' ? Rspack.Configuration[] @@ -34,15 +34,15 @@ export type OnBeforeBuildFn = ( }, ) => MaybePromise; -export type OnAfterEnvironmentBuildFn = ( - params: BuildCommonParams & { +export type OnAfterEnvironmentCompileFn = ( + params: CompileCommonParams & { stats?: Stats; environment: EnvironmentContext; }, ) => MaybePromise; export type OnAfterBuildFn = ( - params: BuildCommonParams & { + params: CompileCommonParams & { stats?: Stats | MultiStats; environments: Record; }, @@ -50,12 +50,6 @@ export type OnAfterBuildFn = ( export type OnCloseDevServerFn = () => MaybePromise; -export type OnDevCompileEnvironmentDoneFn = (params: { - isFirstCompile: boolean; - stats: Stats; - environment: EnvironmentContext; -}) => MaybePromise; - export type OnDevCompileDoneFn = (params: { isFirstCompile: boolean; stats: Stats | MultiStats; diff --git a/packages/core/src/types/plugin.ts b/packages/core/src/types/plugin.ts index f491e2e35f..a6d976a54b 100644 --- a/packages/core/src/types/plugin.ts +++ b/packages/core/src/types/plugin.ts @@ -21,17 +21,16 @@ import type { ModifyRsbuildConfigFn, OnAfterBuildFn, OnAfterCreateCompilerFn, - OnAfterEnvironmentBuildFn, + OnAfterEnvironmentCompileFn, OnAfterStartDevServerFn, OnAfterStartProdServerFn, OnBeforeBuildFn, OnBeforeCreateCompilerFn, - OnBeforeEnvironmentBuildFn, + OnBeforeEnvironmentCompile, OnBeforeStartDevServerFn, OnBeforeStartProdServerFn, OnCloseDevServerFn, OnDevCompileDoneFn, - OnDevCompileEnvironmentDoneFn, OnExitFn, } from './hooks'; import type { RsbuildTarget } from './rsbuild'; @@ -388,10 +387,9 @@ export type RsbuildPluginAPI = Readonly<{ onExit: PluginHook; onAfterBuild: PluginHook; onBeforeBuild: PluginHook; - onAfterEnvironmentBuild: PluginHook; - onBeforeEnvironmentBuild: PluginHook; + onAfterEnvironmentCompile: PluginHook; + onBeforeEnvironmentCompile: PluginHook; onCloseDevServer: PluginHook; - onDevCompileEnvironmentDone: PluginHook; onDevCompileDone: PluginHook; onAfterStartDevServer: PluginHook; onBeforeStartDevServer: PluginHook; diff --git a/packages/core/tests/__snapshots__/hooks.test.ts.snap b/packages/core/tests/__snapshots__/hooks.test.ts.snap index 941c599dc2..f373fc7536 100644 --- a/packages/core/tests/__snapshots__/hooks.test.ts.snap +++ b/packages/core/tests/__snapshots__/hooks.test.ts.snap @@ -20,8 +20,7 @@ exports[`initHooks > should init hooks correctly 1`] = ` "modifyWebpackConfig", "modifyRsbuildConfig", "modifyEnvironmentConfig", - "onBeforeEnvironmentBuild", - "onAfterEnvironmentBuild", - "onDevCompileEnvironmentDone", + "onBeforeEnvironmentCompile", + "onAfterEnvironmentCompile", ] `; diff --git a/website/docs/en/plugins/dev/hooks.mdx b/website/docs/en/plugins/dev/hooks.mdx index 2a726bdd10..63893c5227 100644 --- a/website/docs/en/plugins/dev/hooks.mdx +++ b/website/docs/en/plugins/dev/hooks.mdx @@ -13,6 +13,8 @@ This chapter introduces the plugin hooks available for Rsbuild plugins. - [modifyHTMLTags](#modifyhtmltags): Modify the tags that are injected into the HTML. - [onBeforeCreateCompiler](#onbeforecreatecompiler): Called before creating a compiler instance. - [onAfterCreateCompiler](#onaftercreatecompiler): Called after creating a compiler instance and before building. +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile): Called before running the compile of a single environment. +- [onAfterEnvironmentCompile](#onafterenvironmentcompile): Called after running the compile of a single environment. You can get the build result information. - [onExit](#onexit): Called when the process is about to exit. ### Dev Hooks @@ -22,16 +24,13 @@ Called only when running the `rsbuild dev` command or the `rsbuild.startDevServe - [onBeforeStartDevServer](#onbeforestartdevserver): Called before starting the dev server. - [onAfterStartDevServer](#onafterstartdevserver): Called after starting the dev server. - [onCloseDevServer](#onclosedevserver): Called when the dev server is closed. -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone): Called after each build of a single environment during development. - [onDevCompileDone](#ondevcompiledone): Called after each build during development. ### Build Hooks Called only when running the `rsbuild build` command or the `rsbuild.build()` method. -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild): Called before running the production build of a single environment. - [onBeforeBuild](#onbeforebuild): Called before running the production build. -- [onAfterEnvironmentBuild](#onafterenvironmentbuild): Called after running the production build of a single environment. You can get the build result information. - [onAfterBuild](#onafterbuild): Called after running the production build. You can get the build result information. ### Preview Hooks @@ -54,17 +53,19 @@ When the `rsbuild dev` command or `rsbuild.startDevServer()` method is executed, - [modifyRspackConfig](#modifyrspackconfig) - [onBeforeCreateCompiler](#onbeforecreatecompiler) - [onAfterCreateCompiler](#onaftercreatecompiler) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [onAfterStartDevServer](#onafterstartdevserver) - [modifyHTMLTags](#modifyhtmltags) -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) - [onDevCompileDone](#ondevcompiledone) - [onCloseDevServer](#onclosedevserver) - [onExit](#onexit) When rebuilding, the following hooks will be triggered again: +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [modifyHTMLTags](#modifyhtmltags) -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) - [onDevCompileDone](#ondevcompiledone) ### Build Hooks @@ -77,20 +78,20 @@ When the `rsbuild build` command or `rsbuild.build()` method is executed, Rsbuil - [modifyRspackConfig](#modifyrspackconfig) - [onBeforeCreateCompiler](#onbeforecreatecompiler) - [onAfterCreateCompiler](#onaftercreatecompiler) -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) -- [onAfterEnvironmentBuild](#onafterenvironmentbuild) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) - [onAfterBuild](#onafterbuild) - [onExit](#onexit) When rebuilding, the following hooks will be triggered again: -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) - [onAfterBuild](#onafterbuild) -- [onAfterEnvironmentBuild](#onafterenvironmentbuild) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) ### Preview Hooks @@ -132,9 +133,8 @@ Correspondingly, there are some plugin hooks that are related to the current env - [modifyBundlerChain](#modifybundlerchain) - [modifyRspackConfig](#modifyrspackconfig) - [modifyHTMLTags](#modifyhtmltags) -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) -- [onAfterEnvironmentBuild](#onafterenvironmentbuild) -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) ## Callback Order @@ -536,20 +536,18 @@ const myPlugin = () => ({ }); ``` -## Build Hooks - -### onBeforeEnvironmentBuild +### onBeforeEnvironmentCompile -import OnBeforeEnvironmentBuild from '@en/shared/onBeforeEnvironmentBuild.mdx'; +import OnBeforeEnvironmentCompile from '@en/shared/onBeforeEnvironmentCompile.mdx'; - + - **Example:** ```ts const myPlugin = () => ({ setup: (api) => { - api.onBeforeEnvironmentBuild(({ bundlerConfig, environment }) => { + api.onBeforeEnvironmentCompile(({ bundlerConfig, environment }) => { console.log( `the bundler config for the ${environment.name} is `, bundlerConfig, @@ -559,37 +557,39 @@ const myPlugin = () => ({ }); ``` -### onBeforeBuild +### onAfterEnvironmentCompile -import OnBeforeBuild from '@en/shared/onBeforeBuild.mdx'; +import OnAfterEnvironmentCompile from '@en/shared/onAfterEnvironmentCompile.mdx'; - + - **Example:** ```ts const myPlugin = () => ({ setup: (api) => { - api.onBeforeBuild(({ bundlerConfigs }) => { - console.log('the bundler config is ', bundlerConfigs); + api.onAfterEnvironmentCompile(({ isFirstCompile, stats }) => { + console.log(stats?.toJson(), isFirstCompile); }); }, }); ``` -### onAfterEnvironmentBuild +## Build Hooks + +### onBeforeBuild -import OnAfterEnvironmentBuild from '@en/shared/onAfterEnvironmentBuild.mdx'; +import OnBeforeBuild from '@en/shared/onBeforeBuild.mdx'; - + - **Example:** ```ts const myPlugin = () => ({ setup: (api) => { - api.onAfterEnvironmentBuild(({ isFirstCompile, stats }) => { - console.log(stats?.toJson(), isFirstCompile); + api.onBeforeBuild(({ bundlerConfigs }) => { + console.log('the bundler config is ', bundlerConfigs); }); }, }); @@ -652,9 +652,9 @@ const myPlugin = () => ({ }); ``` -### onDevCompileEnvironmentDone +### onAfterEnvironmentCompile -import OnDevCompileEnvironmentDone from '@en/shared/onDevCompileEnvironmentDone.mdx'; +import OnDevCompileEnvironmentDone from '@en/shared/onAfterEnvironmentCompile.mdx'; @@ -663,7 +663,7 @@ import OnDevCompileEnvironmentDone from '@en/shared/onDevCompileEnvironmentDone. ```ts const myPlugin = () => ({ setup: (api) => { - api.onDevCompileEnvironmentDone(({ isFirstCompile }) => { + api.onAfterEnvironmentCompile(({ isFirstCompile }) => { if (isFirstCompile) { console.log('first compile!'); } else { diff --git a/website/docs/en/shared/onAfterEnvironmentBuild.mdx b/website/docs/en/shared/onAfterEnvironmentBuild.mdx index 59ac44233d..47abb5d904 100644 --- a/website/docs/en/shared/onAfterEnvironmentBuild.mdx +++ b/website/docs/en/shared/onAfterEnvironmentBuild.mdx @@ -1,11 +1,11 @@ -`onAfterEnvironmentBuild` is a callback function that is triggered after running the production build of a single environment. You can access the build result information via the [stats](https://webpack.js.org/api/node/#stats-object) parameter. +`onAfterEnvironmentCompile` is a callback function that is triggered after running compile of a single environment. You can access the build result information via the [stats](https://webpack.js.org/api/node/#stats-object) parameter. -Moreover, you can use `isWatch` to determine whether it is watch mode, and use `isFirstCompile` to determine whether it is the first build on watch mode. +Moreover, you can use `isWatch` to determine whether it is dev or build watch mode, and use `isFirstCompile` to determine whether it is the first build. - **Type:** ```ts -function OnAfterEnvironmentBuild( +function OnAfterEnvironmentCompile( callback: (params: { isFirstCompile: boolean; isWatch: boolean; diff --git a/website/docs/en/shared/onBeforeEnvironmentBuild.mdx b/website/docs/en/shared/onBeforeEnvironmentCompile.mdx similarity index 60% rename from website/docs/en/shared/onBeforeEnvironmentBuild.mdx rename to website/docs/en/shared/onBeforeEnvironmentCompile.mdx index 6f0243c254..88eb441fa0 100644 --- a/website/docs/en/shared/onBeforeEnvironmentBuild.mdx +++ b/website/docs/en/shared/onBeforeEnvironmentCompile.mdx @@ -1,13 +1,13 @@ -`onBeforeEnvironmentBuild` is a callback function that is triggered before the production build is executed of a single environment. +`onBeforeEnvironmentCompile` is a callback function that is triggered before compile is executed of a single environment. You can access the Rspack configuration array through the `bundlerConfigs` parameter. The array may contain one or more [Rspack configurations](https://rspack.dev/config/). It depends on whether multiple [environments](/config/environments) are configured. -Moreover, you can use `isWatch` to determine whether it is watch mode, and use `isFirstCompile` to determine whether it is the first build on watch mode. +Moreover, you can use `isWatch` to determine whether it is dev or build watch mode, and use `isFirstCompile` to determine whether it is the first build. - **Type:** ```ts -function OnBeforeEnvironmentBuild( +function OnBeforeEnvironmentCompile( callback: (params: { isWatch: boolean; isFirstCompile: boolean; diff --git a/website/docs/en/shared/onDevCompileEnvironmentDone.mdx b/website/docs/en/shared/onDevCompileEnvironmentDone.mdx deleted file mode 100644 index 0149a8ea38..0000000000 --- a/website/docs/en/shared/onDevCompileEnvironmentDone.mdx +++ /dev/null @@ -1,13 +0,0 @@ -Called after each build of a single environment during development, you can use `isFirstCompile` to determine whether it is the first build. - -- **Type:** - -```ts -function OnDevCompileEnvironmentDone( - callback: (params: { - isFirstCompile: boolean; - stats: Stats; - environment: EnvironmentContext; - }) => Promise | void, -): void; -``` diff --git a/website/docs/zh/plugins/dev/hooks.mdx b/website/docs/zh/plugins/dev/hooks.mdx index d4c293a932..b642a8d5c4 100644 --- a/website/docs/zh/plugins/dev/hooks.mdx +++ b/website/docs/zh/plugins/dev/hooks.mdx @@ -13,6 +13,8 @@ - [modifyHTMLTags](#modifyhtmltags):修改注入到 HTML 中的标签。 - [onBeforeCreateCompiler](#onbeforecreatecompiler):在创建 compiler 实例前调用。 - [onAfterCreateCompiler](#onaftercreatecompiler):在创建 compiler 实例后、执行构建前调用。 +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile): 在每次执行单个 environment 的构建前调用。 +- [onAfterEnvironmentCompile](#onafterenvironmentcompile): 在每次单个 environment 的构建结束后调用。 - [onExit](#onexit):在进程即将退出时调用。 ### Dev Hooks @@ -21,7 +23,6 @@ - [onBeforeStartDevServer](#onbeforestartdevserver):在启动开发服务器前调用。 - [onAfterStartDevServer](#onafterstartdevserver):在启动开发服务器后调用。 -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone): 在每次单个 environment 的开发环境构建结束后调用。 - [onDevCompileDone](#ondevcompiledone):在每次开发环境构建结束后调用。 - [onCloseDevServer](#onclosedevserver):在关闭开发服务器时调用。 @@ -29,9 +30,7 @@ 仅在执行 `rsbuild build` 命令或 `rsbuild.build()` 方法时调用。 -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild): 在执行单个 environment 的生产环境构建前调用。 - [onBeforeBuild](#onbeforebuild):在执行生产环境构建前调用。 -- [onAfterEnvironmentBuild](#onafterenvironmentbuild): 在执行单个 environment 的生产环境构建后调用,可以获取到单个 environment 的构建结果信息。 - [onAfterBuild](#onafterbuild):在执行生产环境构建后调用,可以获取到构建结果信息。 ### Preview Hooks @@ -54,17 +53,19 @@ - [modifyRspackConfig](#modifyrspackconfig) - [onBeforeCreateCompiler](#onbeforecreatecompiler) - [onAfterCreateCompiler](#onaftercreatecompiler) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [onAfterStartDevServer](#onafterstartdevserver) - [modifyHTMLTags](#modifyhtmltags) -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) - [onDevCompileDone](#ondevcompiledone) - [onCloseDevServer](#onclosedevserver) - [onExit](#onexit) 当 rebuild 时,以下 hooks 会再次触发: +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [modifyHTMLTags](#modifyhtmltags) -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) - [onDevCompileDone](#ondevcompiledone) ### Build Hooks @@ -77,19 +78,19 @@ - [modifyRspackConfig](#modifyrspackconfig) - [onBeforeCreateCompiler](#onbeforecreatecompiler) - [onAfterCreateCompiler](#onaftercreatecompiler) -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) -- [onAfterEnvironmentBuild](#onafterenvironmentbuild) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) - [onAfterBuild](#onafterbuild) - [onExit](#onexit) 当 rebuild 时,以下 hooks 会再次触发: -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) - [onBeforeBuild](#onbeforebuild) - [modifyHTMLTags](#modifyhtmltags) -- [onAfterEnvironmentBuild](#onafterenvironmentbuild) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) - [onAfterBuild](#onafterbuild) ### Preview Hooks @@ -132,9 +133,8 @@ - [modifyBundlerChain](#modifybundlerchain) - [modifyRspackConfig](#modifyrspackconfig) - [modifyHTMLTags](#modifyhtmltags) -- [onBeforeEnvironmentBuild](#onbeforeenvironmentbuild) -- [onAfterEnvironmentBuild](#onafterenvironmentbuild) -- [onDevCompileEnvironmentDone](#ondevcompileenvironmentdone) +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile) +- [onAfterEnvironmentCompile](#onafterenvironmentcompile) ## 回调函数顺序 @@ -532,20 +532,18 @@ const myPlugin = () => ({ }); ``` -## Build Hooks - -### onBeforeEnvironmentBuild +### onBeforeEnvironmentCompile -import OnBeforeEnvironmentBuild from '@zh/shared/onBeforeEnvironmentBuild.mdx'; +import OnBeforeEnvironmentCompile from '@zh/shared/onBeforeEnvironmentCompile.mdx'; - + - **示例:** ```ts const myPlugin = () => ({ setup: (api) => { - api.onBeforeEnvironmentBuild(({ bundlerConfig, environment }) => { + api.onBeforeEnvironmentCompile(({ bundlerConfig, environment }) => { console.log( `the bundler config for the ${environment.name} is `, bundlerConfig, @@ -555,37 +553,39 @@ const myPlugin = () => ({ }); ``` -### onBeforeBuild +### onAfterEnvironmentCompile -import OnBeforeBuild from '@zh/shared/onBeforeBuild.mdx'; +import OnAfterEnvironmentCompile from '@zh/shared/onAfterEnvironmentCompile.mdx'; - + - **示例:** ```ts const myPlugin = () => ({ setup: (api) => { - api.onBeforeBuild(({ bundlerConfigs }) => { - console.log('the bundler config is ', bundlerConfigs); + api.onAfterEnvironmentCompile(({ isFirstCompile, stats }) => { + console.log(stats?.toJson(), isFirstCompile); }); }, }); ``` -### onAfterEnvironmentBuild +## Build Hooks + +### onBeforeBuild -import OnAfterEnvironmentBuild from '@zh/shared/onAfterEnvironmentBuild.mdx'; +import OnBeforeBuild from '@zh/shared/onBeforeBuild.mdx'; - + - **示例:** ```ts const myPlugin = () => ({ setup: (api) => { - api.onAfterEnvironmentBuild(({ isFirstCompile, stats }) => { - console.log(stats?.toJson(), isFirstCompile); + api.onBeforeBuild(({ bundlerConfigs }) => { + console.log('the bundler config is ', bundlerConfigs); }); }, }); @@ -648,9 +648,9 @@ const myPlugin = () => ({ }); ``` -### onDevCompileEnvironmentDone +### onAfterEnvironmentCompile -import OnDevCompileEnvironmentDone from '@zh/shared/onDevCompileEnvironmentDone.mdx'; +import OnDevCompileEnvironmentDone from '@zh/shared/onAfterEnvironmentCompile.mdx'; @@ -659,7 +659,7 @@ import OnDevCompileEnvironmentDone from '@zh/shared/onDevCompileEnvironmentDone. ```ts const myPlugin = () => ({ setup: (api) => { - api.onDevCompileEnvironmentDone(({ isFirstCompile }) => { + api.onAfterEnvironmentCompile(({ isFirstCompile }) => { if (isFirstCompile) { console.log('first compile!'); } else { diff --git a/website/docs/zh/shared/onAfterEnvironmentBuild.mdx b/website/docs/zh/shared/onAfterEnvironmentBuild.mdx index bd34b99301..2765b3683e 100644 --- a/website/docs/zh/shared/onAfterEnvironmentBuild.mdx +++ b/website/docs/zh/shared/onAfterEnvironmentBuild.mdx @@ -1,11 +1,11 @@ -`onAfterEnvironmentBuild` 是在执行单个 environment 的生产环境构建后触发的回调函数,你可以通过 [stats](https://webpack.js.org/api/node/#stats-object) 参数获取到构建结果信息。 +`onAfterEnvironmentCompile` 是在执行单个 environment 的构建后触发的回调函数,你可以通过 [stats](https://webpack.js.org/api/node/#stats-object) 参数获取到构建结果信息。 -另外,你可以通过 `isWatch` 判断是否是 watch 模式,并在 watch 模式下通过 `isFirstCompile` 来判断是否为首次构建。 +另外,你可以通过 `isWatch` 判断是否是 dev 或者 build watch 模式,并通过 `isFirstCompile` 来判断是否为首次构建。 - **类型:** ```ts -function OnAfterEnvironmentBuild( +function OnAfterEnvironmentCompile( callback: (params: { isFirstCompile: boolean; isWatch: boolean; diff --git a/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx b/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx index 55105754e4..06f1244155 100644 --- a/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx +++ b/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx @@ -1,13 +1,13 @@ -`onBeforeEnvironmentBuild` 是在执行单个 environment 的生产环境构建前触发的回调函数。 +`onBeforeEnvironmentCompile` 是在执行单个 environment 的构建前触发的回调函数。 你可以通过 `bundlerConfig` 参数获取到当前 environment 对应的 Rspack 配置(https://rspack.dev/config/)。 -另外,你可以通过 `isWatch` 判断是否是 watch 模式,并在 watch 模式下通过 `isFirstCompile` 来判断是否为首次构建。 +另外,你可以通过 `isWatch` 判断是否是 dev 或者 build watch 模式,并在 watch 模式下通过 `isFirstCompile` 来判断是否为首次构建。 - **类型:** ```ts -function OnBeforeEnvironmentBuild( +function OnBeforeEnvironmentCompile( callback: (params: { isWatch: boolean; isFirstCompile: boolean; From c1fed063fe16b7a11fec50ab022cfc997904feeb Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Mon, 5 Aug 2024 16:44:49 +0800 Subject: [PATCH 03/15] fix: debug log --- packages/core/src/hooks.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/core/src/hooks.ts b/packages/core/src/hooks.ts index 1a9ca4a2ed..ce18872538 100644 --- a/packages/core/src/hooks.ts +++ b/packages/core/src/hooks.ts @@ -23,7 +23,6 @@ const onBeforeCompile = ({ if (isMultiCompiler(compiler)) { const { compilers } = compiler; - console.log('compilers', compilers.length); let doneCompilers = 0; From 0a8e551e326ad5586dce0bf3dc49e55f5e70bdc8 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Mon, 5 Aug 2024 16:53:55 +0800 Subject: [PATCH 04/15] docs: fix file name --- ...{onAfterEnvironmentBuild.mdx => onAfterEnvironmentCompile.mdx} | 0 ...{onAfterEnvironmentBuild.mdx => onAfterEnvironmentCompile.mdx} | 0 ...nBeforeEnvironmentBuild.mdx => onBeforeEnvironmentCompile.mdx} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename website/docs/en/shared/{onAfterEnvironmentBuild.mdx => onAfterEnvironmentCompile.mdx} (100%) rename website/docs/zh/shared/{onAfterEnvironmentBuild.mdx => onAfterEnvironmentCompile.mdx} (100%) rename website/docs/zh/shared/{onBeforeEnvironmentBuild.mdx => onBeforeEnvironmentCompile.mdx} (100%) diff --git a/website/docs/en/shared/onAfterEnvironmentBuild.mdx b/website/docs/en/shared/onAfterEnvironmentCompile.mdx similarity index 100% rename from website/docs/en/shared/onAfterEnvironmentBuild.mdx rename to website/docs/en/shared/onAfterEnvironmentCompile.mdx diff --git a/website/docs/zh/shared/onAfterEnvironmentBuild.mdx b/website/docs/zh/shared/onAfterEnvironmentCompile.mdx similarity index 100% rename from website/docs/zh/shared/onAfterEnvironmentBuild.mdx rename to website/docs/zh/shared/onAfterEnvironmentCompile.mdx diff --git a/website/docs/zh/shared/onBeforeEnvironmentBuild.mdx b/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx similarity index 100% rename from website/docs/zh/shared/onBeforeEnvironmentBuild.mdx rename to website/docs/zh/shared/onBeforeEnvironmentCompile.mdx From 9f26bed135b5d41dd647c1922162b046983f9c80 Mon Sep 17 00:00:00 2001 From: gaoyuan Date: Mon, 5 Aug 2024 17:46:52 +0800 Subject: [PATCH 05/15] Update website/docs/zh/shared/onBeforeEnvironmentCompile.mdx Co-authored-by: neverland --- website/docs/zh/shared/onBeforeEnvironmentCompile.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx b/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx index 06f1244155..43f5497370 100644 --- a/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx +++ b/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx @@ -11,7 +11,7 @@ function OnBeforeEnvironmentCompile( callback: (params: { isWatch: boolean; isFirstCompile: boolean; - bundlerConfig?: RspackConfig | WebpackConfig; + bundlerConfig?: RspackConfig; environment: EnvironmentContext; }) => Promise | void, ): void; From e68031b392f5540ea4745a5631028ffb097e440c Mon Sep 17 00:00:00 2001 From: gaoyuan Date: Mon, 5 Aug 2024 17:47:01 +0800 Subject: [PATCH 06/15] Update website/docs/en/shared/onBeforeEnvironmentCompile.mdx Co-authored-by: neverland --- website/docs/en/shared/onBeforeEnvironmentCompile.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/en/shared/onBeforeEnvironmentCompile.mdx b/website/docs/en/shared/onBeforeEnvironmentCompile.mdx index 88eb441fa0..3f2e57b6be 100644 --- a/website/docs/en/shared/onBeforeEnvironmentCompile.mdx +++ b/website/docs/en/shared/onBeforeEnvironmentCompile.mdx @@ -11,7 +11,7 @@ function OnBeforeEnvironmentCompile( callback: (params: { isWatch: boolean; isFirstCompile: boolean; - bundlerConfig?: RspackConfig | WebpackConfig; + bundlerConfig?: RspackConfig; environment: EnvironmentContext; }) => Promise | void, ): void; From 6a2a5315f59dbc494b6ff7af07e9919db8a53726 Mon Sep 17 00:00:00 2001 From: gaoyuan Date: Mon, 5 Aug 2024 17:52:24 +0800 Subject: [PATCH 07/15] Update website/docs/zh/shared/onBeforeEnvironmentCompile.mdx Co-authored-by: neverland --- website/docs/zh/shared/onBeforeEnvironmentCompile.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx b/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx index 43f5497370..e1855d107c 100644 --- a/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx +++ b/website/docs/zh/shared/onBeforeEnvironmentCompile.mdx @@ -1,6 +1,6 @@ `onBeforeEnvironmentCompile` 是在执行单个 environment 的构建前触发的回调函数。 -你可以通过 `bundlerConfig` 参数获取到当前 environment 对应的 Rspack 配置(https://rspack.dev/config/)。 +你可以通过 `bundlerConfig` 参数获取到当前 environment 对应的 Rspack 配置(https://rspack.dev/config/)。 另外,你可以通过 `isWatch` 判断是否是 dev 或者 build watch 模式,并在 watch 模式下通过 `isFirstCompile` 来判断是否为首次构建。 From 0dc317ca0945c9d27f05f740a3694bf52d0f8850 Mon Sep 17 00:00:00 2001 From: gaoyuan Date: Mon, 5 Aug 2024 17:52:57 +0800 Subject: [PATCH 08/15] Update website/docs/en/plugins/dev/hooks.mdx Co-authored-by: neverland --- website/docs/en/plugins/dev/hooks.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/en/plugins/dev/hooks.mdx b/website/docs/en/plugins/dev/hooks.mdx index 63893c5227..27f6cef2b2 100644 --- a/website/docs/en/plugins/dev/hooks.mdx +++ b/website/docs/en/plugins/dev/hooks.mdx @@ -14,7 +14,7 @@ This chapter introduces the plugin hooks available for Rsbuild plugins. - [onBeforeCreateCompiler](#onbeforecreatecompiler): Called before creating a compiler instance. - [onAfterCreateCompiler](#onaftercreatecompiler): Called after creating a compiler instance and before building. - [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile): Called before running the compile of a single environment. -- [onAfterEnvironmentCompile](#onafterenvironmentcompile): Called after running the compile of a single environment. You can get the build result information. +- [onAfterEnvironmentCompile](#onafterenvironmentcompile): Called after the compilation of a single environment. You can get the build result information. - [onExit](#onexit): Called when the process is about to exit. ### Dev Hooks From 8108c215d74b6bd89d83fa6733b249a40698c3e8 Mon Sep 17 00:00:00 2001 From: gaoyuan Date: Mon, 5 Aug 2024 17:53:04 +0800 Subject: [PATCH 09/15] Update website/docs/en/plugins/dev/hooks.mdx Co-authored-by: neverland --- website/docs/en/plugins/dev/hooks.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/en/plugins/dev/hooks.mdx b/website/docs/en/plugins/dev/hooks.mdx index 27f6cef2b2..bfef00c0e8 100644 --- a/website/docs/en/plugins/dev/hooks.mdx +++ b/website/docs/en/plugins/dev/hooks.mdx @@ -13,7 +13,7 @@ This chapter introduces the plugin hooks available for Rsbuild plugins. - [modifyHTMLTags](#modifyhtmltags): Modify the tags that are injected into the HTML. - [onBeforeCreateCompiler](#onbeforecreatecompiler): Called before creating a compiler instance. - [onAfterCreateCompiler](#onaftercreatecompiler): Called after creating a compiler instance and before building. -- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile): Called before running the compile of a single environment. +- [onBeforeEnvironmentCompile](#onbeforeenvironmentcompile): Called before the compilation of a single environment. - [onAfterEnvironmentCompile](#onafterenvironmentcompile): Called after the compilation of a single environment. You can get the build result information. - [onExit](#onexit): Called when the process is about to exit. From c20012dcd8ea982fd31eb8129f991e81ee054c1b Mon Sep 17 00:00:00 2001 From: gaoyuan Date: Mon, 5 Aug 2024 17:53:11 +0800 Subject: [PATCH 10/15] Update website/docs/en/shared/onAfterEnvironmentCompile.mdx Co-authored-by: neverland --- website/docs/en/shared/onAfterEnvironmentCompile.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/en/shared/onAfterEnvironmentCompile.mdx b/website/docs/en/shared/onAfterEnvironmentCompile.mdx index 47abb5d904..79a71d57b5 100644 --- a/website/docs/en/shared/onAfterEnvironmentCompile.mdx +++ b/website/docs/en/shared/onAfterEnvironmentCompile.mdx @@ -1,4 +1,4 @@ -`onAfterEnvironmentCompile` is a callback function that is triggered after running compile of a single environment. You can access the build result information via the [stats](https://webpack.js.org/api/node/#stats-object) parameter. +`onAfterEnvironmentCompile` is a callback function that is triggered after the compilation of a single environment. You can access the build result information via the [stats](https://webpack.js.org/api/node/#stats-object) parameter. Moreover, you can use `isWatch` to determine whether it is dev or build watch mode, and use `isFirstCompile` to determine whether it is the first build. From ef1b8edd67f385a8ec9f17a966ec0345a463268a Mon Sep 17 00:00:00 2001 From: gaoyuan Date: Mon, 5 Aug 2024 17:53:18 +0800 Subject: [PATCH 11/15] Update website/docs/en/shared/onBeforeEnvironmentCompile.mdx Co-authored-by: neverland --- website/docs/en/shared/onBeforeEnvironmentCompile.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/en/shared/onBeforeEnvironmentCompile.mdx b/website/docs/en/shared/onBeforeEnvironmentCompile.mdx index 3f2e57b6be..d0a3410042 100644 --- a/website/docs/en/shared/onBeforeEnvironmentCompile.mdx +++ b/website/docs/en/shared/onBeforeEnvironmentCompile.mdx @@ -1,4 +1,4 @@ -`onBeforeEnvironmentCompile` is a callback function that is triggered before compile is executed of a single environment. +`onBeforeEnvironmentCompile` is a callback function that is triggered before the compilation of a single environment. You can access the Rspack configuration array through the `bundlerConfigs` parameter. The array may contain one or more [Rspack configurations](https://rspack.dev/config/). It depends on whether multiple [environments](/config/environments) are configured. From 5244dd43250bc74f4af905eaabe8b3af481b69f3 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Mon, 5 Aug 2024 17:57:58 +0800 Subject: [PATCH 12/15] fix: merge module --- packages/core/src/hooks.ts | 277 ------------------- packages/core/src/initHooks.ts | 276 +++++++++++++++++- packages/core/src/internal.ts | 2 +- packages/core/src/provider/build.ts | 2 +- packages/core/src/provider/createCompiler.ts | 2 +- 5 files changed, 278 insertions(+), 281 deletions(-) delete mode 100644 packages/core/src/hooks.ts diff --git a/packages/core/src/hooks.ts b/packages/core/src/hooks.ts deleted file mode 100644 index ce18872538..0000000000 --- a/packages/core/src/hooks.ts +++ /dev/null @@ -1,277 +0,0 @@ -import { isMultiCompiler } from './helpers'; -import type { - EnvironmentContext, - InternalContext, - MultiStats, - Rspack, - RspackConfig, - Stats, -} from './types'; - -const onBeforeCompile = ({ - compiler, - beforeCompile, - beforeEnvironmentCompiler, - isWatch, -}: { - compiler: Rspack.Compiler | Rspack.MultiCompiler; - beforeCompile?: () => Promise; - beforeEnvironmentCompiler: (buildIndex: number) => Promise; - isWatch?: boolean; -}): void => { - const name = 'rsbuild:beforeCompile'; - - if (isMultiCompiler(compiler)) { - const { compilers } = compiler; - - let doneCompilers = 0; - - for (let index = 0; index < compilers.length; index++) { - const compiler = compilers[index]; - let compilerDone = false; - - (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( - name, - async () => { - if (!compilerDone) { - compilerDone = true; - doneCompilers++; - } - // ensure only last compiler done will trigger beforeCompile hook - // avoid other compiler done triggers when executing async beforeEnvironmentCompiler hook - const lastCompilerDone = doneCompilers === compilers.length; - - await beforeEnvironmentCompiler(index); - - if (lastCompilerDone) { - await beforeCompile?.(); - } - }, - ); - - compiler.hooks.invalid.tap(name, () => { - if (compilerDone) { - compilerDone = false; - doneCompilers--; - } - }); - } - } else { - (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( - name, - async () => { - await beforeEnvironmentCompiler(0); - await beforeCompile?.(); - }, - ); - } -}; - -export const onCompileDone = ({ - compiler, - onDone, - onEnvironmentDone, - MultiStatsCtor, -}: { - compiler: Rspack.Compiler | Rspack.MultiCompiler; - onDone: (stats: Rspack.Stats | Rspack.MultiStats) => Promise; - onEnvironmentDone: (buildIndex: number, stats: Rspack.Stats) => Promise; - MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; -}): void => { - // The MultiCompiler of Rspack does not supports `done.tapPromise`, - // so we need to use the `done` hook of `MultiCompiler.compilers` to implement it. - if (isMultiCompiler(compiler)) { - const { compilers } = compiler; - const compilerStats: Rspack.Stats[] = []; - let doneCompilers = 0; - - for (let index = 0; index < compilers.length; index++) { - const compiler = compilers[index]; - const compilerIndex = index; - let compilerDone = false; - - compiler.hooks.done.tapPromise('rsbuild:done', async (stats) => { - if (!compilerDone) { - compilerDone = true; - doneCompilers++; - } - - compilerStats[compilerIndex] = stats; - - const lastCompilerDone = doneCompilers === compilers.length; - - await onEnvironmentDone(index, stats); - - if (lastCompilerDone) { - await onDone(new MultiStatsCtor(compilerStats)); - } - }); - - compiler.hooks.invalid.tap('rsbuild:done', () => { - if (compilerDone) { - compilerDone = false; - doneCompilers--; - } - }); - } - } else { - compiler.hooks.done.tapPromise('rsbuild:done', async (stats) => { - await onEnvironmentDone(0, stats); - await onDone(stats); - }); - } -}; - -export const registerBuildHook = ({ - context, - isWatch, - compiler, - bundlerConfigs, - MultiStatsCtor, -}: { - bundlerConfigs?: RspackConfig[]; - context: InternalContext; - compiler: Rspack.Compiler | Rspack.MultiCompiler; - isWatch: boolean; - MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; -}): void => { - let isFirstCompile = true; - - const environmentArr = Object.values(context.environments).reduce< - EnvironmentContext[] - >((prev, curr) => { - prev[curr.index] = curr; - return prev; - }, []); - - const beforeCompile = async () => - await context.hooks.onBeforeBuild.call({ - bundlerConfigs, - environments: context.environments, - isWatch, - isFirstCompile, - }); - - const beforeEnvironmentCompiler = async (buildIndex: number) => - await context.hooks.onBeforeEnvironmentCompile.callInEnvironment({ - environment: environmentArr[buildIndex].name, - args: [ - { - bundlerConfig: bundlerConfigs?.[buildIndex] as Rspack.Configuration, - environment: environmentArr[buildIndex], - isWatch, - isFirstCompile, - }, - ], - }); - - const onDone = async (stats: Stats | MultiStats) => { - const p = context.hooks.onAfterBuild.call({ - isFirstCompile, - stats, - environments: context.environments, - isWatch, - }); - isFirstCompile = false; - await p; - }; - - const onEnvironmentDone = async (buildIndex: number, stats: Stats) => { - await context.hooks.onAfterEnvironmentCompile.callInEnvironment({ - environment: environmentArr[buildIndex].name, - args: [ - { - isFirstCompile, - stats, - environment: environmentArr[buildIndex], - isWatch, - }, - ], - }); - }; - - onBeforeCompile({ - compiler, - beforeCompile, - beforeEnvironmentCompiler, - isWatch, - }); - - onCompileDone({ - compiler, - onDone, - onEnvironmentDone, - MultiStatsCtor, - }); -}; - -export const registerDevHook = ({ - context, - compiler, - bundlerConfigs, - MultiStatsCtor, -}: { - bundlerConfigs?: RspackConfig[]; - context: InternalContext; - compiler: Rspack.Compiler | Rspack.MultiCompiler; - MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; -}): void => { - let isFirstCompile = true; - - const environmentArr = Object.values(context.environments).reduce< - EnvironmentContext[] - >((prev, curr) => { - prev[curr.index] = curr; - return prev; - }, []); - - const beforeEnvironmentCompiler = async (buildIndex: number) => - await context.hooks.onBeforeEnvironmentCompile.callInEnvironment({ - environment: environmentArr[buildIndex].name, - args: [ - { - bundlerConfig: bundlerConfigs?.[buildIndex] as Rspack.Configuration, - environment: environmentArr[buildIndex], - isWatch: true, - isFirstCompile, - }, - ], - }); - - const onDone = async (stats: Stats | MultiStats) => { - const p = context.hooks.onDevCompileDone.call({ - isFirstCompile, - stats, - environments: context.environments, - }); - isFirstCompile = false; - await p; - }; - - const onEnvironmentDone = async (buildIndex: number, stats: Stats) => { - await context.hooks.onAfterEnvironmentCompile.callInEnvironment({ - environment: environmentArr[buildIndex].name, - args: [ - { - isFirstCompile, - stats, - environment: environmentArr[buildIndex], - isWatch: true, - }, - ], - }); - }; - - onBeforeCompile({ - compiler, - beforeEnvironmentCompiler, - isWatch: true, - }); - - onCompileDone({ - compiler, - onDone, - onEnvironmentDone, - MultiStatsCtor, - }); -}; diff --git a/packages/core/src/initHooks.ts b/packages/core/src/initHooks.ts index afea900d64..88312850d3 100644 --- a/packages/core/src/initHooks.ts +++ b/packages/core/src/initHooks.ts @@ -1,9 +1,11 @@ -import { isFunction } from './helpers'; +import { isFunction, isMultiCompiler } from './helpers'; import { isPluginMatchEnvironment } from './pluginManager'; import type { AsyncHook, EnvironmentAsyncHook, + EnvironmentContext, HookDescriptor, + InternalContext, ModifyBundlerChainFn, ModifyEnvironmentConfigFn, ModifyHTMLTagsFn, @@ -11,6 +13,7 @@ import type { ModifyRspackConfigFn, ModifyWebpackChainFn, ModifyWebpackConfigFn, + MultiStats, OnAfterBuildFn, OnAfterCreateCompilerFn, OnAfterEnvironmentCompileFn, @@ -24,6 +27,9 @@ import type { OnCloseDevServerFn, OnDevCompileDoneFn, OnExitFn, + Rspack, + RspackConfig, + Stats, } from './types'; export function createEnvironmentAsyncHook< @@ -195,3 +201,271 @@ export function initHooks(): { } export type Hooks = ReturnType; + +const onBeforeCompile = ({ + compiler, + beforeCompile, + beforeEnvironmentCompiler, + isWatch, +}: { + compiler: Rspack.Compiler | Rspack.MultiCompiler; + beforeCompile?: () => Promise; + beforeEnvironmentCompiler: (buildIndex: number) => Promise; + isWatch?: boolean; +}): void => { + const name = 'rsbuild:beforeCompile'; + + if (isMultiCompiler(compiler)) { + const { compilers } = compiler; + + let doneCompilers = 0; + + for (let index = 0; index < compilers.length; index++) { + const compiler = compilers[index]; + let compilerDone = false; + + (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( + name, + async () => { + if (!compilerDone) { + compilerDone = true; + doneCompilers++; + } + // ensure only last compiler done will trigger beforeCompile hook + // avoid other compiler done triggers when executing async beforeEnvironmentCompiler hook + const lastCompilerDone = doneCompilers === compilers.length; + + await beforeEnvironmentCompiler(index); + + if (lastCompilerDone) { + await beforeCompile?.(); + } + }, + ); + + compiler.hooks.invalid.tap(name, () => { + if (compilerDone) { + compilerDone = false; + doneCompilers--; + } + }); + } + } else { + (isWatch ? compiler.hooks.watchRun : compiler.hooks.run).tapPromise( + name, + async () => { + await beforeEnvironmentCompiler(0); + await beforeCompile?.(); + }, + ); + } +}; + +export const onCompileDone = ({ + compiler, + onDone, + onEnvironmentDone, + MultiStatsCtor, +}: { + compiler: Rspack.Compiler | Rspack.MultiCompiler; + onDone: (stats: Rspack.Stats | Rspack.MultiStats) => Promise; + onEnvironmentDone: (buildIndex: number, stats: Rspack.Stats) => Promise; + MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; +}): void => { + // The MultiCompiler of Rspack does not supports `done.tapPromise`, + // so we need to use the `done` hook of `MultiCompiler.compilers` to implement it. + if (isMultiCompiler(compiler)) { + const { compilers } = compiler; + const compilerStats: Rspack.Stats[] = []; + let doneCompilers = 0; + + for (let index = 0; index < compilers.length; index++) { + const compiler = compilers[index]; + const compilerIndex = index; + let compilerDone = false; + + compiler.hooks.done.tapPromise('rsbuild:done', async (stats) => { + if (!compilerDone) { + compilerDone = true; + doneCompilers++; + } + + compilerStats[compilerIndex] = stats; + + const lastCompilerDone = doneCompilers === compilers.length; + + await onEnvironmentDone(index, stats); + + if (lastCompilerDone) { + await onDone(new MultiStatsCtor(compilerStats)); + } + }); + + compiler.hooks.invalid.tap('rsbuild:done', () => { + if (compilerDone) { + compilerDone = false; + doneCompilers--; + } + }); + } + } else { + compiler.hooks.done.tapPromise('rsbuild:done', async (stats) => { + await onEnvironmentDone(0, stats); + await onDone(stats); + }); + } +}; + +export const registerBuildHook = ({ + context, + isWatch, + compiler, + bundlerConfigs, + MultiStatsCtor, +}: { + bundlerConfigs?: RspackConfig[]; + context: InternalContext; + compiler: Rspack.Compiler | Rspack.MultiCompiler; + isWatch: boolean; + MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; +}): void => { + let isFirstCompile = true; + + const environmentList = Object.values(context.environments).reduce< + EnvironmentContext[] + >((prev, curr) => { + prev[curr.index] = curr; + return prev; + }, []); + + const beforeCompile = async () => + await context.hooks.onBeforeBuild.call({ + bundlerConfigs, + environments: context.environments, + isWatch, + isFirstCompile, + }); + + const beforeEnvironmentCompiler = async (buildIndex: number) => + await context.hooks.onBeforeEnvironmentCompile.callInEnvironment({ + environment: environmentList[buildIndex].name, + args: [ + { + bundlerConfig: bundlerConfigs?.[buildIndex] as Rspack.Configuration, + environment: environmentList[buildIndex], + isWatch, + isFirstCompile, + }, + ], + }); + + const onDone = async (stats: Stats | MultiStats) => { + const p = context.hooks.onAfterBuild.call({ + isFirstCompile, + stats, + environments: context.environments, + isWatch, + }); + isFirstCompile = false; + await p; + }; + + const onEnvironmentDone = async (buildIndex: number, stats: Stats) => { + await context.hooks.onAfterEnvironmentCompile.callInEnvironment({ + environment: environmentList[buildIndex].name, + args: [ + { + isFirstCompile, + stats, + environment: environmentList[buildIndex], + isWatch, + }, + ], + }); + }; + + onBeforeCompile({ + compiler, + beforeCompile, + beforeEnvironmentCompiler, + isWatch, + }); + + onCompileDone({ + compiler, + onDone, + onEnvironmentDone, + MultiStatsCtor, + }); +}; + +export const registerDevHook = ({ + context, + compiler, + bundlerConfigs, + MultiStatsCtor, +}: { + bundlerConfigs?: RspackConfig[]; + context: InternalContext; + compiler: Rspack.Compiler | Rspack.MultiCompiler; + MultiStatsCtor: new (stats: Rspack.Stats[]) => Rspack.MultiStats; +}): void => { + let isFirstCompile = true; + + const environmentList = Object.values(context.environments).reduce< + EnvironmentContext[] + >((prev, curr) => { + prev[curr.index] = curr; + return prev; + }, []); + + const beforeEnvironmentCompiler = async (buildIndex: number) => + await context.hooks.onBeforeEnvironmentCompile.callInEnvironment({ + environment: environmentList[buildIndex].name, + args: [ + { + bundlerConfig: bundlerConfigs?.[buildIndex] as Rspack.Configuration, + environment: environmentList[buildIndex], + isWatch: true, + isFirstCompile, + }, + ], + }); + + const onDone = async (stats: Stats | MultiStats) => { + const p = context.hooks.onDevCompileDone.call({ + isFirstCompile, + stats, + environments: context.environments, + }); + isFirstCompile = false; + await p; + }; + + const onEnvironmentDone = async (buildIndex: number, stats: Stats) => { + await context.hooks.onAfterEnvironmentCompile.callInEnvironment({ + environment: environmentList[buildIndex].name, + args: [ + { + isFirstCompile, + stats, + environment: environmentList[buildIndex], + isWatch: true, + }, + ], + }); + }; + + onBeforeCompile({ + compiler, + beforeEnvironmentCompiler, + isWatch: true, + }); + + onCompileDone({ + compiler, + onDone, + onEnvironmentDone, + MultiStatsCtor, + }); +}; diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index ab71975c70..d5c331d88f 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -17,7 +17,7 @@ export { export type { InternalContext } from './types'; export { setHTMLPlugin, getHTMLPlugin } from './pluginHelper'; export { formatStats, getStatsOptions, prettyTime } from './helpers'; -export { registerBuildHook, registerDevHook, onCompileDone } from './hooks'; +export { registerBuildHook, registerDevHook, onCompileDone } from './initHooks'; export { getChainUtils, getConfigUtils } from './provider/rspackConfig'; export { chainToConfig, modifyBundlerChain } from './configChain'; export { applySwcDecoratorConfig } from './plugins/swc'; diff --git a/packages/core/src/provider/build.ts b/packages/core/src/provider/build.ts index dad9cfcf95..a24c8e59cf 100644 --- a/packages/core/src/provider/build.ts +++ b/packages/core/src/provider/build.ts @@ -1,6 +1,6 @@ import { rspack } from '@rspack/core'; import { getNodeEnv, setNodeEnv } from '../helpers'; -import { registerBuildHook } from '../hooks'; +import { registerBuildHook } from '../initHooks'; import { logger } from '../logger'; import type { BuildOptions, diff --git a/packages/core/src/provider/createCompiler.ts b/packages/core/src/provider/createCompiler.ts index 8e02f6d6e3..6744bd5344 100644 --- a/packages/core/src/provider/createCompiler.ts +++ b/packages/core/src/provider/createCompiler.ts @@ -10,7 +10,7 @@ import { prettyTime, rspackMinVersion, } from '../helpers'; -import { registerDevHook } from '../hooks'; +import { registerDevHook } from '../initHooks'; import { logger } from '../logger'; import type { DevMiddlewareAPI } from '../server/devMiddleware'; import type { From f842cf45438a1b55c831f4e859e2d3072d4efc08 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Mon, 5 Aug 2024 18:53:15 +0800 Subject: [PATCH 13/15] chore: rename hooks --- packages/core/src/createContext.ts | 2 +- packages/core/src/{initHooks.ts => hooks.ts} | 0 packages/core/src/internal.ts | 4 ++-- packages/core/src/provider/build.ts | 2 +- packages/core/src/provider/createCompiler.ts | 2 +- packages/core/src/types/context.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename packages/core/src/{initHooks.ts => hooks.ts} (100%) diff --git a/packages/core/src/createContext.ts b/packages/core/src/createContext.ts index bd3cb7c72a..11bdb0c37a 100644 --- a/packages/core/src/createContext.ts +++ b/packages/core/src/createContext.ts @@ -3,7 +3,7 @@ import browserslist from 'browserslist'; import { withDefaultConfig } from './config'; import { DEFAULT_BROWSERSLIST, ROOT_DIST_DIR } from './constants'; import { getCommonParentPath } from './helpers/path'; -import { initHooks } from './initHooks'; +import { initHooks } from './hooks'; import { getHTMLPathByEntry } from './initPlugins'; import { logger } from './logger'; import type { diff --git a/packages/core/src/initHooks.ts b/packages/core/src/hooks.ts similarity index 100% rename from packages/core/src/initHooks.ts rename to packages/core/src/hooks.ts diff --git a/packages/core/src/internal.ts b/packages/core/src/internal.ts index d5c331d88f..954fd4d298 100644 --- a/packages/core/src/internal.ts +++ b/packages/core/src/internal.ts @@ -7,7 +7,7 @@ export { runCli } from './cli/commands'; export { prepareCli } from './cli/prepare'; export { initPlugins, createPluginManager } from './pluginManager'; -export { initHooks, type Hooks } from './initHooks'; +export { initHooks, type Hooks } from './hooks'; export { initRsbuildConfig } from './provider/initConfigs'; export { stringifyConfig, @@ -17,7 +17,7 @@ export { export type { InternalContext } from './types'; export { setHTMLPlugin, getHTMLPlugin } from './pluginHelper'; export { formatStats, getStatsOptions, prettyTime } from './helpers'; -export { registerBuildHook, registerDevHook, onCompileDone } from './initHooks'; +export { registerBuildHook, registerDevHook, onCompileDone } from './hooks'; export { getChainUtils, getConfigUtils } from './provider/rspackConfig'; export { chainToConfig, modifyBundlerChain } from './configChain'; export { applySwcDecoratorConfig } from './plugins/swc'; diff --git a/packages/core/src/provider/build.ts b/packages/core/src/provider/build.ts index a24c8e59cf..dad9cfcf95 100644 --- a/packages/core/src/provider/build.ts +++ b/packages/core/src/provider/build.ts @@ -1,6 +1,6 @@ import { rspack } from '@rspack/core'; import { getNodeEnv, setNodeEnv } from '../helpers'; -import { registerBuildHook } from '../initHooks'; +import { registerBuildHook } from '../hooks'; import { logger } from '../logger'; import type { BuildOptions, diff --git a/packages/core/src/provider/createCompiler.ts b/packages/core/src/provider/createCompiler.ts index 6744bd5344..8e02f6d6e3 100644 --- a/packages/core/src/provider/createCompiler.ts +++ b/packages/core/src/provider/createCompiler.ts @@ -10,7 +10,7 @@ import { prettyTime, rspackMinVersion, } from '../helpers'; -import { registerDevHook } from '../initHooks'; +import { registerDevHook } from '../hooks'; import { logger } from '../logger'; import type { DevMiddlewareAPI } from '../server/devMiddleware'; import type { diff --git a/packages/core/src/types/context.ts b/packages/core/src/types/context.ts index 05752ad3df..8ef8c343b1 100644 --- a/packages/core/src/types/context.ts +++ b/packages/core/src/types/context.ts @@ -1,4 +1,4 @@ -import type { Hooks } from '../initHooks'; +import type { Hooks } from '../hooks'; import type { NormalizedConfig, RsbuildConfig } from './config'; import type { EnvironmentContext } from './hooks'; import type { RsbuildPluginAPI } from './plugin'; From de78953080c832a727f1069e80dcef74bac46cd4 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Mon, 5 Aug 2024 18:53:58 +0800 Subject: [PATCH 14/15] chore: rename hooks --- packages/core/tests/hooks.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/tests/hooks.test.ts b/packages/core/tests/hooks.test.ts index 22e39ac984..9fa771b497 100644 --- a/packages/core/tests/hooks.test.ts +++ b/packages/core/tests/hooks.test.ts @@ -1,5 +1,5 @@ import { createStubRsbuild } from '@scripts/test-helper'; -import { createEnvironmentAsyncHook, initHooks } from '../src/initHooks'; +import { createEnvironmentAsyncHook, initHooks } from '../src/hooks'; describe('initHooks', () => { test('should init hooks correctly', async () => { From 5bd7ea004470266f46bbdd8d07545d2531203d60 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Mon, 5 Aug 2024 18:57:45 +0800 Subject: [PATCH 15/15] fix: CI --- packages/core/tests/createAsyncHook.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/tests/createAsyncHook.test.ts b/packages/core/tests/createAsyncHook.test.ts index 4662790b0b..dc7b01e984 100644 --- a/packages/core/tests/createAsyncHook.test.ts +++ b/packages/core/tests/createAsyncHook.test.ts @@ -1,4 +1,4 @@ -import { createAsyncHook } from '../src/initHooks'; +import { createAsyncHook } from '../src/hooks'; describe('createAsyncHook', () => { test('should execute callback functions in order', async () => {