diff --git a/e2e/cases/doctor-rspack/brief.test.ts b/e2e/cases/doctor-rspack/brief.test.ts
new file mode 100644
index 00000000..77dfcd87
--- /dev/null
+++ b/e2e/cases/doctor-rspack/brief.test.ts
@@ -0,0 +1,167 @@
+import { expect, test, webkit } from '@playwright/test';
+import { getSDK, setSDK } from '@rsdoctor/core/plugins';
+import { compileByRspack } from '@scripts/test-helper';
+import { Compiler } from '@rspack/core';
+import path from 'path';
+import fs from 'fs';
+import { createRsdoctorPlugin } from './test-utils';
+
+let reportLoaderStartOrEndTimes = 0;
+
+async function rspackCompile(
+ _tapName: string,
+ compile: typeof compileByRspack,
+) {
+ const file = path.resolve(__dirname, './fixtures/a.js');
+ const loader = path.resolve(__dirname, './fixtures/loaders/comment.js');
+
+ const esmLoader = path.resolve(
+ __dirname,
+ './fixtures/loaders/esm-serialize-query-to-comment.mjs',
+ );
+
+ const res = await compile(file, {
+ resolve: {
+ extensions: ['.ts', '.js'],
+ },
+ output: {
+ path: path.join(__dirname, '../doctor-rspack/dist'),
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js/,
+ use: loader,
+ },
+ {
+ test: /\.js/,
+ use: esmLoader,
+ },
+ {
+ test: /\.[jt]s$/,
+ use: {
+ loader: 'builtin:swc-loader',
+ options: {
+ sourceMap: true,
+ jsc: {
+ parser: {
+ syntax: 'typescript',
+ },
+ externalHelpers: true,
+ preserveAllComments: false,
+ },
+ },
+ },
+ type: 'javascript/auto',
+ },
+ ],
+ },
+ plugins: [
+ // @ts-ignore
+ createRsdoctorPlugin({
+ mode: 'brief',
+ }),
+ {
+ name: 'XXX',
+ apply(compiler: Compiler) {
+ compiler.hooks.beforeRun.tapPromise(
+ { name: 'XXX', stage: 99999 },
+ async () => {
+ const sdk = getSDK();
+ setSDK(
+ new Proxy(sdk, {
+ get(target, key, receiver) {
+ switch (key) {
+ case 'reportLoader':
+ return null;
+ case 'reportLoaderStartOrEnd':
+ return (_data: any) => {
+ reportLoaderStartOrEndTimes += 1;
+ };
+ default:
+ return Reflect.get(target, key, receiver);
+ }
+ },
+ set(target, key, value, receiver) {
+ return Reflect.set(target, key, value, receiver);
+ },
+ defineProperty(target, p, attrs) {
+ return Reflect.defineProperty(target, p, attrs);
+ },
+ }),
+ );
+ },
+ );
+ },
+ },
+ ],
+ });
+
+ return res;
+}
+
+test('rspack banner plugin', async () => {
+ const tapName = 'XXX';
+ await rspackCompile(tapName, compileByRspack);
+
+ const reportPath = path.join(
+ __dirname,
+ './dist/.rsdoctor/rsdoctor-report.html',
+ );
+
+ fileExists(reportPath);
+
+ const browser = await webkit.launch();
+
+ // Create a new browser context
+ const context = await browser.newContext();
+
+ // Open a new page
+ const page = await context.newPage();
+
+ // Navigate to a URL
+ await page.goto(`file:///${reportPath}`);
+
+ // Perform actions on the page
+ const title = await page.title();
+ expect(title).toBe('Rsdoctor');
+
+ const titleContent = 'Bundle Overall';
+
+ const bundleTitleExists = await page
+ .locator(`text=${titleContent}`)
+ .first()
+ .isVisible();
+
+ const compileTabExists = await page
+ .locator(`text='Compile Analysis'`)
+ .first()
+ .isVisible();
+
+ const bundleTabExists = await page
+ .locator(`text='Bundle Size'`)
+ .first()
+ .isVisible();
+
+ expect(bundleTitleExists).toBe(true);
+ expect(compileTabExists).toBe(true);
+ expect(bundleTabExists).toBe(true);
+
+ // Close the page
+ await page.close();
+
+ // Close the browser context
+ await context.close();
+
+ // Close the browser
+ await browser.close();
+});
+
+async function fileExists(filePath: string) {
+ try {
+ await fs.existsSync(filePath);
+ return true;
+ } catch {
+ return false;
+ }
+}
diff --git a/packages/components/src/components/BundleDiff/DiffServerAPIProvider/index.tsx b/packages/components/src/components/BundleDiff/DiffServerAPIProvider/index.tsx
index 10e5617d..cbfa6646 100644
--- a/packages/components/src/components/BundleDiff/DiffServerAPIProvider/index.tsx
+++ b/packages/components/src/components/BundleDiff/DiffServerAPIProvider/index.tsx
@@ -37,7 +37,6 @@ export const DiffServerAPIProvider = <
}
>
{(current) => {
- // TODO:: need check
return current ? children(baseline, current) : ;
}}
diff --git a/packages/core/src/inner-plugins/utils/config.ts b/packages/core/src/inner-plugins/utils/config.ts
index 00c98b51..db7ecdb9 100644
--- a/packages/core/src/inner-plugins/utils/config.ts
+++ b/packages/core/src/inner-plugins/utils/config.ts
@@ -38,6 +38,12 @@ export function normalizeUserConfig(
port,
printLog = { serverUrls: true },
mode = 'normal',
+ brief = {
+ reportHtmlDir: undefined,
+ reportHtmlName: undefined,
+ writeDataJson: false,
+ },
+ reportDir = '',
} = config;
assert(linter && typeof linter === 'object');
@@ -100,6 +106,8 @@ export function normalizeUserConfig(
port,
printLog,
mode,
+ brief,
+ reportDir,
};
return res;
diff --git a/packages/core/src/types/plugin.ts b/packages/core/src/types/plugin.ts
index 09563465..c898aa5f 100644
--- a/packages/core/src/types/plugin.ts
+++ b/packages/core/src/types/plugin.ts
@@ -16,6 +16,8 @@ export type IReportCodeType = {
noCode?: boolean;
};
+export type IOutput = {};
+
export interface RsdoctorWebpackPluginOptions<
Rules extends LinterType.ExtendRuleData[],
> {
@@ -57,26 +59,21 @@ export interface RsdoctorWebpackPluginOptions<
* sdk instance of outside
*/
sdkInstance?: RsdoctorWebpackSDK;
- /**
- * control the Rsdoctor reporter codes records.
- */
- reportCodeType?: IReportCodeType | undefined;
/**
* Whether to turn on some characteristic analysis capabilities, such as: the support for the BannerPlugin.
*/
supports?: ISupport;
+
/**
- * control the Rsdoctor upload data to TOS, used by inner-rsdoctor.
- * @default false
+ * The directory where the report files will be output.
*/
- disableTOSUpload?: boolean;
+ reportDir?: string;
/**
- * The name of inner rsdoctor's client package, used by inner-rsdoctor.
- * @default false
+ * Control the Rsdoctor reporter codes records.
*/
- innerClientPath?: string;
+ reportCodeType?: IReportCodeType | undefined;
/**
* The port of the Rsdoctor server.
@@ -87,6 +84,23 @@ export interface RsdoctorWebpackPluginOptions<
* Options to control the log printing.
*/
printLog?: SDK.IPrintLog;
+
+ /**
+ * Options to control brief mode reports.
+ */
+ brief?: SDK.BriefConfig;
+
+ /**
+ * control the Rsdoctor upload data to TOS, used by inner-rsdoctor.
+ * @default false
+ */
+ disableTOSUpload?: boolean;
+
+ /**
+ * The name of inner rsdoctor's client package, used by inner-rsdoctor.
+ * @default false
+ */
+ innerClientPath?: string;
}
export interface RsdoctorMultiplePluginOptions<
@@ -110,7 +124,12 @@ export interface RsdoctorPluginOptionsNormalized<
> extends Common.DeepRequired<
Omit<
RsdoctorWebpackPluginOptions,
- 'sdkInstance' | 'linter' | 'reportCodeType' | 'supports' | 'port'
+ | 'sdkInstance'
+ | 'linter'
+ | 'reportCodeType'
+ | 'supports'
+ | 'port'
+ | 'brief'
>
> {
features: Common.DeepRequired;
@@ -119,6 +138,7 @@ export interface RsdoctorPluginOptionsNormalized<
port?: number;
reportCodeType: SDK.ToDataType;
supports: ISupport;
+ brief: SDK.BriefConfig;
}
export interface BasePluginInstance {
diff --git a/packages/rspack-plugin/src/plugin.ts b/packages/rspack-plugin/src/plugin.ts
index e7b75b2a..ad294e83 100644
--- a/packages/rspack-plugin/src/plugin.ts
+++ b/packages/rspack-plugin/src/plugin.ts
@@ -80,6 +80,7 @@ export class RsdoctorRspackPlugin
innerClientPath: this.options.innerClientPath,
printLog: this.options.printLog,
mode: this.options.mode ? this.options.mode : undefined,
+ brief: this.options.brief,
},
});
this.outsideInstance = Boolean(this.options.sdkInstance);
@@ -171,21 +172,24 @@ export class RsdoctorRspackPlugin
if (this.outsideInstance && 'parent' in this.sdk) {
this.sdk.parent.master.setOutputDir(
path.resolve(
- compiler.outputPath,
+ this.options.reportDir || compiler.outputPath,
`./${Constants.RsdoctorOutputFolder}`,
),
);
}
this.sdk.setOutputDir(
- path.resolve(compiler.outputPath, `./${Constants.RsdoctorOutputFolder}`),
+ path.resolve(
+ this.options.reportDir || compiler.outputPath,
+ `./${Constants.RsdoctorOutputFolder}`,
+ ),
);
await this.sdk.writeStore();
if (!this.options.disableClientServer) {
if (this.options.mode === SDK.IMode[SDK.IMode.brief]) {
const outputFilePath = path.resolve(
this.sdk.outputDir,
- 'rsdoctor-report.html',
+ this.options.brief.reportHtmlName || 'rsdoctor-report.html',
);
console.log(
@@ -227,7 +231,10 @@ export class RsdoctorRspackPlugin
});
this.sdk.setOutputDir(
- path.resolve(compiler.outputPath, `./${Constants.RsdoctorOutputFolder}`),
+ path.resolve(
+ this.options.reportDir || compiler.outputPath,
+ `./${Constants.RsdoctorOutputFolder}`,
+ ),
);
}
}
diff --git a/packages/sdk/src/sdk/sdk/core.ts b/packages/sdk/src/sdk/sdk/core.ts
index 01af4888..3d59a458 100644
--- a/packages/sdk/src/sdk/sdk/core.ts
+++ b/packages/sdk/src/sdk/sdk/core.ts
@@ -42,7 +42,10 @@ export abstract class SDKCore
this._name = name;
this.root = root;
this.pid = process.pid;
- this._outputDir = path.join(this.root, Constants.RsdoctorOutputFolder);
+ this._outputDir = path.join(
+ this.outputDir || this.root,
+ Constants.RsdoctorOutputFolder,
+ );
}
get outputDir() {
diff --git a/packages/sdk/src/sdk/sdk/webpack.ts b/packages/sdk/src/sdk/sdk/webpack.ts
index 747fa98d..1dff59aa 100644
--- a/packages/sdk/src/sdk/sdk/webpack.ts
+++ b/packages/sdk/src/sdk/sdk/webpack.ts
@@ -380,6 +380,9 @@ export class RsdoctorWebpackSDK<
? this.extraConfig.innerClientPath
: require.resolve('@rsdoctor/client');
+ if (this.extraConfig.brief?.writeDataJson) {
+ this.saveManifest(this.getStoreData(), options || {});
+ }
return this.inlineScriptsAndStyles(clientHtmlPath);
}
return this.saveManifest(this.getStoreData(), options || {});
@@ -593,7 +596,10 @@ export class RsdoctorWebpackSDK<
htmlContent = this.addRsdoctorDataToHTML(this.getStoreData(), htmlContent);
// Output the processed HTML content
- const outputFilePath = path.resolve(this.outputDir, 'rsdoctor-report.html');
+ const outputFilePath = path.resolve(
+ this.outputDir,
+ this.extraConfig?.brief?.reportHtmlName || 'rsdoctor-report.html',
+ );
fse.outputFileSync(outputFilePath, htmlContent, {
encoding: 'utf-8',
diff --git a/packages/types/src/sdk/instance.ts b/packages/types/src/sdk/instance.ts
index 9c6b6a17..39d7d9d1 100644
--- a/packages/types/src/sdk/instance.ts
+++ b/packages/types/src/sdk/instance.ts
@@ -115,6 +115,11 @@ export interface IPrintLog {
serverUrls: boolean;
}
+export interface BriefConfig {
+ reportHtmlName?: string | undefined;
+ writeDataJson: boolean;
+}
+
export type SDKOptionsType = {
disableTOSUpload: boolean;
innerClientPath?: string;
@@ -122,6 +127,7 @@ export type SDKOptionsType = {
noServer?: boolean;
printLog?: IPrintLog;
mode?: keyof typeof IMode;
+ brief?: BriefConfig;
};
/**
diff --git a/packages/webpack-plugin/src/plugin.ts b/packages/webpack-plugin/src/plugin.ts
index 83e22a26..87ff2fbf 100644
--- a/packages/webpack-plugin/src/plugin.ts
+++ b/packages/webpack-plugin/src/plugin.ts
@@ -65,6 +65,7 @@ export class RsdoctorWebpackPlugin
innerClientPath: this.options.innerClientPath,
printLog: this.options.printLog,
mode: this.options.mode ? this.options.mode : undefined,
+ brief: this.options.brief,
},
});
this.outsideInstance = Boolean(this.options.sdkInstance);
@@ -156,7 +157,10 @@ export class RsdoctorWebpackPlugin
});
this.sdk.setOutputDir(
- path.resolve(compiler.outputPath, `./${Constants.RsdoctorOutputFolder}`),
+ path.resolve(
+ this.options.reportDir || compiler.outputPath,
+ `./${Constants.RsdoctorOutputFolder}`,
+ ),
);
if (configuration.name) {
@@ -203,7 +207,7 @@ export class RsdoctorWebpackPlugin
) {
const outputFilePath = path.resolve(
this.sdk.outputDir,
- 'rsdoctor-report.html',
+ this.options.brief.reportHtmlName || 'rsdoctor-report.html',
);
console.log(
`${chalk.green('[RSDOCTOR] generated brief report')}: ${outputFilePath}`,