Skip to content

Commit

Permalink
feat: support apply environment bundleAnalyze config (#2682)
Browse files Browse the repository at this point in the history
Co-authored-by: neverland <[email protected]>
  • Loading branch information
9aoy and chenjiahan authored Jun 24, 2024
1 parent d72dd09 commit c260257
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 36 deletions.
2 changes: 1 addition & 1 deletion packages/core/src/createRsbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ async function applyDefaultPlugins(
pluginSplitChunks(),
pluginOpen(),
pluginInlineChunk(),
pluginBundleAnalyzer(),
pluginRsdoctor(),
pluginResourceHints(),
pluginPerformance(),
pluginBundleAnalyzer(),
pluginServer(),
pluginManifest(),
pluginModuleFederation(),
Expand Down
39 changes: 28 additions & 11 deletions packages/core/src/plugins/bundleAnalyzer.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
import { isProd } from '../helpers';
import type { NormalizedConfig, RsbuildConfig, RsbuildPlugin } from '../types';
import type {
NormalizedEnvironmentConfig,
RsbuildConfig,
RsbuildPlugin,
} from '../types';

// There are two ways to enable the bundle analyzer:
// 1. Set environment variable `BUNDLE_ANALYZE`
// 2. Set performance.bundleAnalyze config
const isUseAnalyzer = (config: RsbuildConfig | NormalizedConfig) =>
const isUseAnalyzer = (config: RsbuildConfig | NormalizedEnvironmentConfig) =>
process.env.BUNDLE_ANALYZE || config.performance?.bundleAnalyze;

export function pluginBundleAnalyzer(): RsbuildPlugin {
return {
name: 'rsbuild:bundle-analyzer',

setup(api) {
api.modifyRsbuildConfig((config) => {
if (isProd() || !isUseAnalyzer(config)) {
return;
}
api.modifyRsbuildConfig({
order: 'post',
handler: (config) => {
if (isProd()) {
return;
}

const useAnalyzer =
isUseAnalyzer(config) ||
Object.values(config.environments || []).some((config) =>
isUseAnalyzer(config),
);

if (!useAnalyzer) {
return;
}

// webpack-bundle-analyze needs to read assets from disk
config.dev ||= {};
config.dev.writeToDisk = true;
// webpack-bundle-analyze needs to read assets from disk
config.dev ||= {};
config.dev.writeToDisk = true;

return config;
return config;
},
});

api.modifyBundlerChain(async (chain, { CHAIN_ID, environment }) => {
const config = api.getNormalizedConfig();
const config = api.getNormalizedConfig({ environment });

if (!isUseAnalyzer(config)) {
return;
Expand Down
30 changes: 25 additions & 5 deletions packages/core/src/plugins/cleanOutput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ export const pluginCleanOutput = (): RsbuildPlugin => ({
name: 'rsbuild:clean-output',

setup(api) {
const clean = async () => {
const { distPath, rootPath } = api.context;
const config = api.getNormalizedConfig();
const clean = async (environment: string) => {
const { rootPath } = api.context;
const config = api.getNormalizedConfig({ environment });
const { distPath } = api.context.environments[environment];

let { cleanDistPath } = config.output;

Expand All @@ -43,7 +44,26 @@ export const pluginCleanOutput = (): RsbuildPlugin => ({
}
};

api.onBeforeBuild(clean);
api.onBeforeStartDevServer(clean);
const cleanAll = async () => {
const distPaths = Object.entries(api.context.environments).reduce<
Array<{
environmentName: string;
distPath: string;
}>
>((total, [environmentName, curr]) => {
if (!total.find((t) => t.distPath === curr.distPath)) {
total.push({
environmentName,
distPath: curr.distPath,
});
}
return total;
}, []);

await Promise.all(distPaths.map((d) => clean(d.environmentName)));
};

api.onBeforeBuild(cleanAll);
api.onBeforeStartDevServer(cleanAll);
},
});
53 changes: 35 additions & 18 deletions packages/core/src/plugins/performance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { RsbuildPlugin } from '../types';
import type { EnvironmentConfig } from '@rsbuild/shared';
import type { RsbuildConfig, RsbuildPlugin } from '../types';

/**
* Apply some configs of Rsbuild performance
Expand All @@ -7,26 +8,42 @@ export const pluginPerformance = (): RsbuildPlugin => ({
name: 'rsbuild:performance',

setup(api) {
api.modifyRsbuildConfig((rsbuildConfig) => {
if (rsbuildConfig.performance?.profile) {
// generate stats.json
if (!rsbuildConfig.performance?.bundleAnalyze) {
rsbuildConfig.performance ??= {};
rsbuildConfig.performance.bundleAnalyze = {
analyzerMode: 'disabled',
generateStatsFile: true,
};
} else {
rsbuildConfig.performance.bundleAnalyze = {
generateStatsFile: true,
...(rsbuildConfig.performance.bundleAnalyze || {}),
};
api.modifyRsbuildConfig({
order: 'post',
handler: (rsbuildConfig) => {
// profile needs to be output to stats.json
const applyBundleAnalyzeConfig = (
config: RsbuildConfig | EnvironmentConfig,
) => {
if (!config.performance?.bundleAnalyze) {
config.performance ??= {};
config.performance.bundleAnalyze = {
analyzerMode: 'disabled',
generateStatsFile: true,
};
} else {
config.performance.bundleAnalyze = {
generateStatsFile: true,
...(config.performance.bundleAnalyze || {}),
};
}
};
if (rsbuildConfig.performance?.profile) {
applyBundleAnalyzeConfig(rsbuildConfig);
} else if (rsbuildConfig.environments) {
for (const config of Object.values(
rsbuildConfig.environments,
)) {
if (config.performance?.profile) {
applyBundleAnalyzeConfig(config);
}
}
}
}
},
});

api.modifyBundlerChain((chain) => {
const config = api.getNormalizedConfig();
api.modifyBundlerChain((chain, { environment }) => {
const config = api.getNormalizedConfig({ environment });
const { profile } = config.performance;
if (!profile) {
return;
Expand Down
69 changes: 69 additions & 0 deletions packages/core/tests/__snapshots__/bundleAnalyzer.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,72 @@ exports[`plugin-bundle-analyze > should add bundle analyze plugin 1`] = `
],
}
`;

exports[`plugin-bundle-analyze > should add bundle analyze plugin when bundle analyze is enabled in environments 1`] = `
{
"plugins": [
BundleAnalyzerPlugin {
"logger": Logger {
"activeLevels": Set {
"info",
"warn",
"error",
"silent",
},
},
"opts": {
"analyzerHost": "127.0.0.1",
"analyzerMode": "static",
"analyzerPort": 8888,
"analyzerUrl": [Function],
"defaultSizes": "parsed",
"excludeAssets": null,
"generateStatsFile": false,
"logLevel": "info",
"openAnalyzer": false,
"reportFilename": "index$$.html",
"reportTitle": [Function],
"startAnalyzer": true,
"statsFilename": "stats.json",
"statsOptions": null,
},
"server": null,
},
],
}
`;

exports[`plugin-bundle-analyze > should enable bundle analyze plugin when performance.profile is enable 1`] = `
{
"plugins": [
BundleAnalyzerPlugin {
"logger": Logger {
"activeLevels": Set {
"info",
"warn",
"error",
"silent",
},
},
"opts": {
"analyzerHost": "127.0.0.1",
"analyzerMode": "disabled",
"analyzerPort": 8888,
"analyzerUrl": [Function],
"defaultSizes": "parsed",
"excludeAssets": null,
"generateStatsFile": true,
"logLevel": "info",
"openAnalyzer": false,
"reportFilename": "report-web.html",
"reportTitle": [Function],
"startAnalyzer": true,
"statsFilename": "stats.json",
"statsOptions": null,
},
"server": null,
},
],
"profile": true,
}
`;
2 changes: 1 addition & 1 deletion packages/core/tests/__snapshots__/inspect.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ exports[`inspectConfig > should print plugin names when inspect config 1`] = `
"rsbuild:split-chunks",
"rsbuild:open",
"rsbuild:inline-chunk",
"rsbuild:bundle-analyzer",
"rsbuild:rsdoctor",
"rsbuild:resource-hints",
"rsbuild:performance",
"rsbuild:bundle-analyzer",
"rsbuild:server",
"rsbuild:manifest",
"rsbuild:module-federation",
Expand Down
41 changes: 41 additions & 0 deletions packages/core/tests/bundleAnalyzer.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createStubRsbuild } from '@scripts/test-helper';
import { pluginBundleAnalyzer } from '../src/plugins/bundleAnalyzer';
import { pluginPerformance } from '../src/plugins/performance';

describe('plugin-bundle-analyze', () => {
it('should add bundle analyze plugin', async () => {
Expand All @@ -18,4 +19,44 @@ describe('plugin-bundle-analyze', () => {

expect(config).toMatchSnapshot();
});

it('should add bundle analyze plugin when bundle analyze is enabled in environments', async () => {
const rsbuild = await createStubRsbuild({
plugins: [pluginBundleAnalyzer()],
rsbuildConfig: {
environments: {
web: {
performance: {
bundleAnalyze: {
reportFilename: 'index$$.html',
},
},
},
},
},
});

const config = await rsbuild.unwrapConfig();

expect(config).toMatchSnapshot();
});

it('should enable bundle analyze plugin when performance.profile is enable', async () => {
const rsbuild = await createStubRsbuild({
plugins: [pluginPerformance(), pluginBundleAnalyzer()],
rsbuildConfig: {
environments: {
web: {
performance: {
profile: true,
},
},
},
},
});

const config = await rsbuild.unwrapConfig();

expect(config).toMatchSnapshot();
});
});

0 comments on commit c260257

Please sign in to comment.