Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions packages/compat/webpack/src/createCompiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { type InitConfigsOptions, initConfigs } from './initConfigs.js';

export async function createCompiler(options: InitConfigsOptions) {
logger.debug('creating compiler');

const HOOK_NAME = 'rsbuild:compiler';
const { helpers, context } = options;
const { webpackConfigs } = await initConfigs(options);

Expand All @@ -20,7 +22,24 @@ export async function createCompiler(options: InitConfigsOptions) {
| Rspack.Compiler
| Rspack.MultiCompiler;

const done = (stats: Rspack.Stats) => {
compiler.hooks.run.tap(HOOK_NAME, () => {
context.buildState.status = 'building';
});

compiler.hooks.watchRun.tap(HOOK_NAME, () => {
context.buildState.status = 'building';
});

compiler.hooks.invalid.tap(HOOK_NAME, () => {
context.buildState.status = 'idle';
context.buildState.hasErrors = false;
});

compiler.hooks.done.tap(HOOK_NAME, (stats) => {
const hasErrors = stats.hasErrors();
context.buildState.hasErrors = hasErrors;
context.buildState.status = 'done';

const statsOptions = helpers.getStatsOptions(compiler);
const statsJson = stats.toJson({
moduleTrace: true,
Expand All @@ -29,20 +48,13 @@ export async function createCompiler(options: InitConfigsOptions) {
...statsOptions,
});

const { message, level } = helpers.formatStats(
statsJson,
stats.hasErrors(),
);
const { message, level } = helpers.formatStats(statsJson, hasErrors);

if (level === 'error') {
logger.error(message);
} else if (level === 'warning') {
logger.warn(message);
}
};

compiler.hooks.done.tap('rsbuild:done', (stats: unknown) => {
done(stats as Rspack.Stats);
});

if (context.action === 'dev') {
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/createContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,5 +212,9 @@ export async function createContext(
config: { ...rsbuildConfig },
originalConfig: userConfig,
specifiedEnvironments,
buildState: {
status: 'idle',
hasErrors: false,
},
};
}
109 changes: 60 additions & 49 deletions packages/core/src/provider/createCompiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ export async function createCompiler(options: InitConfigsOptions): Promise<{
rspackConfigs: Rspack.Configuration[];
}> {
logger.debug('creating compiler');

const HOOK_NAME = 'rsbuild:compiler';
const { context } = options;
const { rspackConfigs } = await initConfigs(options);

Expand Down Expand Up @@ -122,7 +124,7 @@ export async function createCompiler(options: InitConfigsOptions): Promise<{
const lazyModules: Set<string> = new Set();

// Collect lazy compiled modules from the infrastructure logs
compiler.hooks.infrastructureLog.tap('rsbuild:compiling', (name, _, args) => {
compiler.hooks.infrastructureLog.tap(HOOK_NAME, (name, _, args) => {
const log = args[0];
if (
name === 'LazyCompilation' &&
Expand All @@ -144,7 +146,12 @@ export async function createCompiler(options: InitConfigsOptions): Promise<{
}
});

compiler.hooks.watchRun.tap('rsbuild:compiling', (compiler) => {
compiler.hooks.run.tap(HOOK_NAME, () => {
context.buildState.status = 'building';
});

compiler.hooks.watchRun.tap(HOOK_NAME, (compiler) => {
context.buildState.status = 'building';
logRspackVersion();

if (!isCompiling) {
Expand All @@ -158,68 +165,72 @@ export async function createCompiler(options: InitConfigsOptions): Promise<{
isCompiling = true;
});

compiler.hooks.invalid.tap(HOOK_NAME, () => {
context.buildState.status = 'idle';
context.buildState.hasErrors = false;
});

if (context.action === 'build') {
// When there are multiple compilers, we only need to print the start log once
const firstCompiler = isMultiCompiler
? (compiler as Rspack.MultiCompiler).compilers[0]
: compiler;
firstCompiler.hooks.run.tap('rsbuild:run', () => {

firstCompiler.hooks.run.tap(HOOK_NAME, () => {
logger.info('build started...');
logRspackVersion();
});
}

const done = (stats: Rspack.Stats | Rspack.MultiStats) => {
const statsOptions = getStatsOptions(compiler);
const statsJson = stats.toJson({
children: true,
moduleTrace: true,
// get the compilation time
timings: true,
preset: 'errors-warnings',
...statsOptions,
});
compiler.hooks.done.tap(
HOOK_NAME,
(stats: Rspack.Stats | Rspack.MultiStats) => {
const hasErrors = stats.hasErrors();
context.buildState.hasErrors = hasErrors;
context.buildState.status = 'done';

const statsOptions = getStatsOptions(compiler);
const statsJson = stats.toJson({
children: true,
moduleTrace: true,
// get the compilation time
timings: true,
preset: 'errors-warnings',
...statsOptions,
});

const printTime = (c: StatsCompilation, index: number) => {
if (c.time) {
const time = prettyTime(c.time / 1000);
const { name } = rspackConfigs[index];

// When using multi compiler, print name to distinguish different compilers
const suffix = name && isMultiCompiler ? color.dim(` (${name})`) : '';
logger.ready(`built in ${time}${suffix}`);
}
};

if (!hasErrors) {
// only print children compiler time when multi compiler
if (isMultiCompiler && statsJson.children?.length) {
statsJson.children.forEach((c, index) => {
printTime(c, index);
});
} else {
printTime(statsJson, 0);
}
}

const printTime = (c: StatsCompilation, index: number) => {
if (c.time) {
const time = prettyTime(c.time / 1000);
const { name } = rspackConfigs[index];
const { message, level } = formatStats(statsJson, hasErrors);

// When using multi compiler, print name to distinguish different compilers
const suffix = name && isMultiCompiler ? color.dim(` (${name})`) : '';
logger.ready(`built in ${time}${suffix}`);
if (level === 'error') {
logger.error(message);
}
};

const hasErrors = stats.hasErrors();

if (!hasErrors) {
// only print children compiler time when multi compiler
if (isMultiCompiler && statsJson.children?.length) {
statsJson.children.forEach((c, index) => {
printTime(c, index);
});
} else {
printTime(statsJson, 0);
if (level === 'warning') {
logger.warn(message);
}
}

const { message, level } = formatStats(statsJson, hasErrors);

if (level === 'error') {
logger.error(message);
}
if (level === 'warning') {
logger.warn(message);
}

isCompiling = false;
};

compiler.hooks.done.tap(
'rsbuild:done',
(stats: Rspack.Stats | Rspack.MultiStats) => {
done(stats);
isCompiling = false;
},
);

Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1357,14 +1357,14 @@ export type OutputStructure = 'flat' | 'nested';
/**
* custom properties
* e.g. { name: 'viewport' content: 'width=500, initial-scale=1' }
* */
*/
export type MetaAttrs = { [attrName: string]: string | boolean };

export type MetaOptions = {
/**
* name content pair
* e.g. { viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no' }`
* */
*/
[name: string]: string | false | MetaAttrs;
};

Expand Down Expand Up @@ -1886,7 +1886,7 @@ export type AllowedEnvironmentDevKeys =

/**
* The Rsbuild config to run in the specified environment.
* */
*/
export interface EnvironmentConfig {
/**
* Options for local development.
Expand Down Expand Up @@ -1934,7 +1934,7 @@ export type LogLevel = 'info' | 'warn' | 'error' | 'silent';

/**
* The Rsbuild config.
* */
*/
export interface RsbuildConfig extends EnvironmentConfig {
/**
* Specify the build mode for Rsbuild, as each mode has different default behavior and optimizations.
Expand Down
20 changes: 16 additions & 4 deletions packages/core/src/types/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ export type RsbuildContext = {
* // ...
* });
* await rsbuild.startDevServer();
* console.log(rsbuild.context.devServer); // { hostname: 'localhost', port: 3000, https: false }
* console.log(rsbuild.context.devServer);
* // { hostname: 'localhost', port: 3000, https: false }
* }
* ```
*/
Expand Down Expand Up @@ -61,6 +62,15 @@ export type RsbuildContext = {
callerName: string;
};

export type BuildStatus = 'idle' | 'building' | 'done';

export type BuildState = {
/** Current build status */
status: BuildStatus;
/** Whether there are build errors */
hasErrors: boolean;
};

/** The inner context. */
export type InternalContext = RsbuildContext & {
/** All hooks. */
Expand All @@ -73,12 +83,14 @@ export type InternalContext = RsbuildContext & {
normalizedConfig?: NormalizedConfig;
/**
* Get the plugin API.
*
* When environment is undefined, the global plugin API is returned, which can be used in all environments.
* */
* When environment is undefined, the global plugin API is returned, which
* can be used in all environments.
*/
getPluginAPI?: (environment?: string) => RsbuildPluginAPI;
/** The environment context. */
environments: Record<string, EnvironmentContext>;
/** Only build specified environment. */
specifiedEnvironments?: string[];
/** Build state information */
buildState: BuildState;
};
2 changes: 1 addition & 1 deletion packages/core/src/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export type ModifyWebpackChainUtils = ModifyChainUtils & {
CHAIN_ID: ChainIdentifier;
/**
* @deprecated Use target instead.
* */
*/
name: string;
/**
* @deprecated Use HtmlPlugin instead.
Expand Down
Loading