From 5a26ace89162a40fa2a5aff29f7116f21ccbe74a Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 30 May 2024 14:02:03 +0800 Subject: [PATCH 1/5] Revert "fix: should comment-compare-results when print-results wrong (#32)" This reverts commit 3d98f7a4159652bb8cdc363225fad902bb26a2e3. --- .github/workflows/bench_rspack_commit.yml | 9 ++++----- .github/workflows/bench_rspack_pr.yml | 10 ++++------ 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/workflows/bench_rspack_commit.yml b/.github/workflows/bench_rspack_commit.yml index 73e98f76b..730bb5a22 100644 --- a/.github/workflows/bench_rspack_commit.yml +++ b/.github/workflows/bench_rspack_commit.yml @@ -62,6 +62,10 @@ jobs: result=$(node bin/cli.js compare --base latest --current current) echo "$result" echo "diff-result=${result//$'\n'/'@@'}" >> $GITHUB_OUTPUT + if [[ $result =~ "Threshold exceeded" ]]; then + echo "Some benchmark cases exceed the threshold, please visit the previous step for more information" + exit 1 + fi - uses: actions/github-script@v6 with: github-token: ${{ secrets.RSPACK_BOT_ACCESS_TOKEN }} @@ -86,8 +90,3 @@ jobs: repo: 'rspack', body }) - - if (result.includes("Threshold exceeded")) { - console.log("Some benchmark cases exceed the threshold, please visit the previous step for more information"); - process.exit(1); - } diff --git a/.github/workflows/bench_rspack_pr.yml b/.github/workflows/bench_rspack_pr.yml index e58c338b7..8a4f318f9 100644 --- a/.github/workflows/bench_rspack_pr.yml +++ b/.github/workflows/bench_rspack_pr.yml @@ -87,12 +87,15 @@ jobs: result=$(node bin/cli.js compare --base latest --current current) echo "$result" echo "diff-result=${result//$'\n'/'@@'}" >> $GITHUB_OUTPUT + if [[ $result =~ "Threshold exceeded" ]]; then + echo "Some benchmark cases exceed the threshold, please visit the previous step for more information" + exit 1 + fi - uses: actions/github-script@v6 with: github-token: ${{ secrets.RSPACK_BOT_ACCESS_TOKEN }} script: | const diffResult = `${{ steps.print-results.outputs.diff-result }}` - let result = "task ${{ needs.bench.result }}" if (diffResult) { result = diffResult.replace(/@@/g, "\n"); @@ -112,8 +115,3 @@ jobs: comment_id: `${{ needs.create-comment.outputs.comment-id }}`, body }) - - if (result.includes("Threshold exceeded")) { - console.log("Some benchmark cases exceed the threshold, please visit the previous step for more information"); - process.exit(1); - } From ea01261745bd3cc00076e2f549a938d7c23e240e Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 30 May 2024 14:02:04 +0800 Subject: [PATCH 2/5] Revert "Revert "feat: only run 1 time when not in scheduled job (#28)" (#29)" This reverts commit 843fe0e9caf3a11a6ddc683657570216946f1c70. --- .github/workflows/scheduled_bench.yml | 3 ++ bench.config.js | 78 ++++++++++++++++++++++----- bin/cli.js | 26 ++++----- docs/index.html | 2 +- docs/index.js | 4 +- lib/addons/hmr.js | 1 - lib/bench.js | 4 +- lib/compare.js | 17 +++--- lib/display.js | 2 +- lib/utils.js | 2 +- 10 files changed, 102 insertions(+), 37 deletions(-) diff --git a/.github/workflows/scheduled_bench.yml b/.github/workflows/scheduled_bench.yml index b35a5f27c..e2c3b87ed 100644 --- a/.github/workflows/scheduled_bench.yml +++ b/.github/workflows/scheduled_bench.yml @@ -11,6 +11,9 @@ jobs: - uses: actions/checkout@v4 - name: Init env uses: ./.github/actions/env + - name: Set Scheduled env + shell: bash + run: echo "SCHEDULED_JOB=true" >> $GITHUB_ENV - name: Build rspack run: node bin/cli.js build - name: Run benchmark diff --git a/bench.config.js b/bench.config.js index 7fb6c93ee..7fcd434bf 100644 --- a/bench.config.js +++ b/bench.config.js @@ -1,17 +1,71 @@ +const isScheduled = !!process.env.SCHEDULED_JOB; + +// HMR will run 10 times in build plugin, so we should not start multiple instances of Rspack. +// However, we still need to run multiple instances of Rspack when executing scheduled tasks for longer runtimes. +const hmrRuns = isScheduled ? 10 : 1; + export default { jobs: [ - "10000_development-mode", - "10000_development-mode_hmr", - "10000_production-mode", - "arco-pro_development-mode", - "arco-pro_development-mode_intercept-plugin", - "arco-pro_development-mode_hmr", - "arco-pro_development-mode_hmr_intercept-plugin", - "arco-pro_production-mode", - "arco-pro_production-mode_intercept-plugin", - "threejs_development-mode_10x", - "threejs_development-mode_10x_hmr", - "threejs_production-mode_10x" + { + name: "10000_development-mode", + runs: 10, + compareMetrics: ["exec"] + }, + { + name: "10000_development-mode_hmr", + runs: hmrRuns, + compareMetrics: ["stats"] + }, + { + name: "10000_production-mode", + runs: 10, + compareMetrics: ["exec"] + }, + { + name: "arco-pro_development-mode", + runs: 10, + compareMetrics: ["exec"] + }, + { + name: "arco-pro_development-mode_intercept-plugin", + runs: 10, + compareMetrics: ["exec"] + }, + { + name: "arco-pro_development-mode_hmr", + runs: hmrRuns, + compareMetrics: ["stats"] + }, + { + name: "arco-pro_development-mode_hmr_intercept-plugin", + runs: hmrRuns, + compareMetrics: ["stats"] + }, + { + name: "arco-pro_production-mode", + runs: 10, + compareMetrics: ["exec"] + }, + { + name: "arco-pro_production-mode_intercept-plugin", + runs: 10, + compareMetrics: ["exec"] + }, + { + name: "threejs_development-mode_10x", + runs: 10, + compareMetrics: ["exec"] + }, + { + name: "threejs_development-mode_10x_hmr", + runs: hmrRuns, + compareMetrics: ["stats"] + }, + { + name: "threejs_production-mode_10x", + runs: 10, + compareMetrics: ["exec"] + } ], rspackDirectory: process.env.RSPACK_DIR }; diff --git a/bin/cli.js b/bin/cli.js index 78a5effd2..ac75e21fe 100644 --- a/bin/cli.js +++ b/bin/cli.js @@ -68,12 +68,13 @@ const { const cwd = process.cwd(); -const configPath = join(process.cwd(), "bench.config.js"); -const config = (await import(configPath)).default; +const benchConfigPath = join(process.cwd(), "bench.config.js"); +const benchConfig = (await import(benchConfigPath)).default; -const jobs = config.jobs ?? []; -const rspackDirectory = config.rspackDirectory ?? join(cwd, ".rspack"); -const benchmarkDirectory = config.benchmarkDirectory ?? join(cwd, "output"); +const jobs = benchConfig.jobs ?? []; +const rspackDirectory = benchConfig.rspackDirectory ?? join(cwd, ".rspack"); +const benchmarkDirectory = + benchConfig.benchmarkDirectory ?? join(cwd, "output"); if (!command || command === "build") { const fetchUrl = `https://github.com/${repository}`; @@ -125,17 +126,18 @@ if (!command || command === "bench") { console.log( [ `Running jobs for shard ${currentIndex}/${totalShards}:`, - ...shardJobs + ...shardJobs.map(job => job.name) ].join("\n * ") ); for (const job of shardJobs) { const start = Date.now(); - const result = await run(job); + const result = await run(job.name, job.runs); + const message = `${job.name} was run ${job.runs} times, with the following results:`; if (isGitHubActions) { - actionsCore.startGroup(`${job} result is`); + actionsCore.startGroup(message); } else { - console.log(`${job} result is`); + console.log(message); } console.log(formatResultTable(result, { verbose: true })); @@ -143,11 +145,11 @@ if (!command || command === "bench") { if (isGitHubActions) { actionsCore.endGroup(); const cost = Math.ceil((Date.now() - start) / 1000); - console.log(`Cost for \`${job}\`: ${cost} s`); + console.log(`Cost for \`${job.name}\`: ${cost} s`); } await writeFile( - join(benchmarkDirectory, `${job}.json`), + join(benchmarkDirectory, `${job.name}.json`), JSON.stringify(result, null, 2) ); } @@ -157,5 +159,5 @@ if (!command || command === "bench") { } if (!command || command === "compare") { - compare(base, current, benchmarkDirectory); + compare(base, current, benchmarkDirectory, jobs); } diff --git a/docs/index.html b/docs/index.html index 010628b62..9ffb16bd6 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,4 +1,4 @@ - + rspack/benchmark diff --git a/docs/index.js b/docs/index.js index c84504593..220d6c6ce 100644 --- a/docs/index.js +++ b/docs/index.js @@ -329,8 +329,8 @@ class BenchmarkChart { context.dataset.yAxisID === "size" ? formatSize(value, value) : context.dataset.yAxisID === "ratio" - ? formatRatio(value, value) - : formatTime(value, value); + ? formatRatio(value, value) + : formatTime(value, value); return `${context.dataset.label}: ${text}`; } } diff --git a/lib/addons/hmr.js b/lib/addons/hmr.js index 46ea675d8..037f4dec3 100644 --- a/lib/addons/hmr.js +++ b/lib/addons/hmr.js @@ -3,7 +3,6 @@ import { Addon } from "./common.js"; export default class extends Addon { async afterSetup(ctx) { ctx.rspackArgs.push("--watch"); - ctx.runTimes = 5; ctx.config = ctx.config + ` diff --git a/lib/bench.js b/lib/bench.js index 2b96fb2f9..bfa38f70f 100644 --- a/lib/bench.js +++ b/lib/bench.js @@ -5,7 +5,7 @@ import { useAddons, dirExist } from "./utils.js"; const dirname = path.resolve(fileURLToPath(import.meta.url), ".."); -export async function run(benchmarkName) { +export async function run(benchmarkName, runs) { const [caseName, ...addonNames] = benchmarkName.split("_"); const scenario = getScenario(caseName); const addons = await Promise.all( @@ -20,6 +20,8 @@ export async function run(benchmarkName) { await useAddons(addons, "beforeSetup"); const ctx = await scenario.setup(); + ctx.runTimes = runs; + await useAddons(addons, "afterSetup", ctx); try { diff --git a/lib/compare.js b/lib/compare.js index 37aa6a4e7..16949f000 100644 --- a/lib/compare.js +++ b/lib/compare.js @@ -71,9 +71,7 @@ async function getResults(date, index, benchmarkDirectory) { ); } -export async function compare(base, current, benchmarkDirectory) { - const compareMetric = ["exec"]; - +export async function compare(base, current, benchmarkDirectory, jobs) { const index = await fetchIndex(); if (base === "latest") { base = index[index.length - 1].date; @@ -86,13 +84,20 @@ export async function compare(base, current, benchmarkDirectory) { ]); const baseData = {}; const currentData = {}; - for (const metric of compareMetric) { - for (const { name, result } of baseResults) { + + for (const { name, result } of baseResults) { + const job = jobs.find(job => job.name === name); + const compareMetrics = job ? job.compareMetrics : []; + for (const metric of compareMetrics) { const tag = `${name} + ${metric}`; baseData[tag] = result[metric]; } + } - for (const { name, result } of currentResults) { + for (const { name, result } of currentResults) { + const job = jobs.find(job => job.name === name); + const compareMetrics = job ? job.compareMetrics : []; + for (const metric of compareMetrics) { const tag = `${name} + ${metric}`; currentData[tag] = result[metric]; } diff --git a/lib/display.js b/lib/display.js index 5b050b1d6..e37f74fd5 100644 --- a/lib/display.js +++ b/lib/display.js @@ -135,7 +135,7 @@ export function formatResultTable(result, { verbose, limit, threshold }) { con: l => f(l.name, l.confidence), con: l => f(l.name, l.confidence), n: l => `${l.count}` - } + } : undefined) }; return formatTable(entries, columns); diff --git a/lib/utils.js b/lib/utils.js index dec4d9303..12b99cbea 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -21,7 +21,7 @@ export async function runCommand( ? { ...process.env, ...env - } + } : undefined }); if (hasOnData) { From 2ccb14f333fbca879abd508012db77566528bfdc Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 30 May 2024 14:02:09 +0800 Subject: [PATCH 3/5] Revert "feat: only run 1 time when not in scheduled job (#28)" This reverts commit f6d9e69886dfc148e61ecd0a35f08ebcf410a7ba. --- .github/workflows/scheduled_bench.yml | 3 -- bench.config.js | 78 +++++---------------------- bin/cli.js | 26 +++++---- docs/index.html | 2 +- docs/index.js | 4 +- lib/addons/hmr.js | 1 + lib/bench.js | 4 +- lib/compare.js | 17 +++--- lib/display.js | 2 +- lib/utils.js | 2 +- 10 files changed, 37 insertions(+), 102 deletions(-) diff --git a/.github/workflows/scheduled_bench.yml b/.github/workflows/scheduled_bench.yml index e2c3b87ed..b35a5f27c 100644 --- a/.github/workflows/scheduled_bench.yml +++ b/.github/workflows/scheduled_bench.yml @@ -11,9 +11,6 @@ jobs: - uses: actions/checkout@v4 - name: Init env uses: ./.github/actions/env - - name: Set Scheduled env - shell: bash - run: echo "SCHEDULED_JOB=true" >> $GITHUB_ENV - name: Build rspack run: node bin/cli.js build - name: Run benchmark diff --git a/bench.config.js b/bench.config.js index 7fcd434bf..7fb6c93ee 100644 --- a/bench.config.js +++ b/bench.config.js @@ -1,71 +1,17 @@ -const isScheduled = !!process.env.SCHEDULED_JOB; - -// HMR will run 10 times in build plugin, so we should not start multiple instances of Rspack. -// However, we still need to run multiple instances of Rspack when executing scheduled tasks for longer runtimes. -const hmrRuns = isScheduled ? 10 : 1; - export default { jobs: [ - { - name: "10000_development-mode", - runs: 10, - compareMetrics: ["exec"] - }, - { - name: "10000_development-mode_hmr", - runs: hmrRuns, - compareMetrics: ["stats"] - }, - { - name: "10000_production-mode", - runs: 10, - compareMetrics: ["exec"] - }, - { - name: "arco-pro_development-mode", - runs: 10, - compareMetrics: ["exec"] - }, - { - name: "arco-pro_development-mode_intercept-plugin", - runs: 10, - compareMetrics: ["exec"] - }, - { - name: "arco-pro_development-mode_hmr", - runs: hmrRuns, - compareMetrics: ["stats"] - }, - { - name: "arco-pro_development-mode_hmr_intercept-plugin", - runs: hmrRuns, - compareMetrics: ["stats"] - }, - { - name: "arco-pro_production-mode", - runs: 10, - compareMetrics: ["exec"] - }, - { - name: "arco-pro_production-mode_intercept-plugin", - runs: 10, - compareMetrics: ["exec"] - }, - { - name: "threejs_development-mode_10x", - runs: 10, - compareMetrics: ["exec"] - }, - { - name: "threejs_development-mode_10x_hmr", - runs: hmrRuns, - compareMetrics: ["stats"] - }, - { - name: "threejs_production-mode_10x", - runs: 10, - compareMetrics: ["exec"] - } + "10000_development-mode", + "10000_development-mode_hmr", + "10000_production-mode", + "arco-pro_development-mode", + "arco-pro_development-mode_intercept-plugin", + "arco-pro_development-mode_hmr", + "arco-pro_development-mode_hmr_intercept-plugin", + "arco-pro_production-mode", + "arco-pro_production-mode_intercept-plugin", + "threejs_development-mode_10x", + "threejs_development-mode_10x_hmr", + "threejs_production-mode_10x" ], rspackDirectory: process.env.RSPACK_DIR }; diff --git a/bin/cli.js b/bin/cli.js index ac75e21fe..78a5effd2 100644 --- a/bin/cli.js +++ b/bin/cli.js @@ -68,13 +68,12 @@ const { const cwd = process.cwd(); -const benchConfigPath = join(process.cwd(), "bench.config.js"); -const benchConfig = (await import(benchConfigPath)).default; +const configPath = join(process.cwd(), "bench.config.js"); +const config = (await import(configPath)).default; -const jobs = benchConfig.jobs ?? []; -const rspackDirectory = benchConfig.rspackDirectory ?? join(cwd, ".rspack"); -const benchmarkDirectory = - benchConfig.benchmarkDirectory ?? join(cwd, "output"); +const jobs = config.jobs ?? []; +const rspackDirectory = config.rspackDirectory ?? join(cwd, ".rspack"); +const benchmarkDirectory = config.benchmarkDirectory ?? join(cwd, "output"); if (!command || command === "build") { const fetchUrl = `https://github.com/${repository}`; @@ -126,18 +125,17 @@ if (!command || command === "bench") { console.log( [ `Running jobs for shard ${currentIndex}/${totalShards}:`, - ...shardJobs.map(job => job.name) + ...shardJobs ].join("\n * ") ); for (const job of shardJobs) { const start = Date.now(); - const result = await run(job.name, job.runs); - const message = `${job.name} was run ${job.runs} times, with the following results:`; + const result = await run(job); if (isGitHubActions) { - actionsCore.startGroup(message); + actionsCore.startGroup(`${job} result is`); } else { - console.log(message); + console.log(`${job} result is`); } console.log(formatResultTable(result, { verbose: true })); @@ -145,11 +143,11 @@ if (!command || command === "bench") { if (isGitHubActions) { actionsCore.endGroup(); const cost = Math.ceil((Date.now() - start) / 1000); - console.log(`Cost for \`${job.name}\`: ${cost} s`); + console.log(`Cost for \`${job}\`: ${cost} s`); } await writeFile( - join(benchmarkDirectory, `${job.name}.json`), + join(benchmarkDirectory, `${job}.json`), JSON.stringify(result, null, 2) ); } @@ -159,5 +157,5 @@ if (!command || command === "bench") { } if (!command || command === "compare") { - compare(base, current, benchmarkDirectory, jobs); + compare(base, current, benchmarkDirectory); } diff --git a/docs/index.html b/docs/index.html index 9ffb16bd6..010628b62 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,4 +1,4 @@ - + rspack/benchmark diff --git a/docs/index.js b/docs/index.js index 220d6c6ce..c84504593 100644 --- a/docs/index.js +++ b/docs/index.js @@ -329,8 +329,8 @@ class BenchmarkChart { context.dataset.yAxisID === "size" ? formatSize(value, value) : context.dataset.yAxisID === "ratio" - ? formatRatio(value, value) - : formatTime(value, value); + ? formatRatio(value, value) + : formatTime(value, value); return `${context.dataset.label}: ${text}`; } } diff --git a/lib/addons/hmr.js b/lib/addons/hmr.js index 037f4dec3..46ea675d8 100644 --- a/lib/addons/hmr.js +++ b/lib/addons/hmr.js @@ -3,6 +3,7 @@ import { Addon } from "./common.js"; export default class extends Addon { async afterSetup(ctx) { ctx.rspackArgs.push("--watch"); + ctx.runTimes = 5; ctx.config = ctx.config + ` diff --git a/lib/bench.js b/lib/bench.js index bfa38f70f..2b96fb2f9 100644 --- a/lib/bench.js +++ b/lib/bench.js @@ -5,7 +5,7 @@ import { useAddons, dirExist } from "./utils.js"; const dirname = path.resolve(fileURLToPath(import.meta.url), ".."); -export async function run(benchmarkName, runs) { +export async function run(benchmarkName) { const [caseName, ...addonNames] = benchmarkName.split("_"); const scenario = getScenario(caseName); const addons = await Promise.all( @@ -20,8 +20,6 @@ export async function run(benchmarkName, runs) { await useAddons(addons, "beforeSetup"); const ctx = await scenario.setup(); - ctx.runTimes = runs; - await useAddons(addons, "afterSetup", ctx); try { diff --git a/lib/compare.js b/lib/compare.js index 16949f000..37aa6a4e7 100644 --- a/lib/compare.js +++ b/lib/compare.js @@ -71,7 +71,9 @@ async function getResults(date, index, benchmarkDirectory) { ); } -export async function compare(base, current, benchmarkDirectory, jobs) { +export async function compare(base, current, benchmarkDirectory) { + const compareMetric = ["exec"]; + const index = await fetchIndex(); if (base === "latest") { base = index[index.length - 1].date; @@ -84,20 +86,13 @@ export async function compare(base, current, benchmarkDirectory, jobs) { ]); const baseData = {}; const currentData = {}; - - for (const { name, result } of baseResults) { - const job = jobs.find(job => job.name === name); - const compareMetrics = job ? job.compareMetrics : []; - for (const metric of compareMetrics) { + for (const metric of compareMetric) { + for (const { name, result } of baseResults) { const tag = `${name} + ${metric}`; baseData[tag] = result[metric]; } - } - for (const { name, result } of currentResults) { - const job = jobs.find(job => job.name === name); - const compareMetrics = job ? job.compareMetrics : []; - for (const metric of compareMetrics) { + for (const { name, result } of currentResults) { const tag = `${name} + ${metric}`; currentData[tag] = result[metric]; } diff --git a/lib/display.js b/lib/display.js index e37f74fd5..5b050b1d6 100644 --- a/lib/display.js +++ b/lib/display.js @@ -135,7 +135,7 @@ export function formatResultTable(result, { verbose, limit, threshold }) { con: l => f(l.name, l.confidence), con: l => f(l.name, l.confidence), n: l => `${l.count}` - } + } : undefined) }; return formatTable(entries, columns); diff --git a/lib/utils.js b/lib/utils.js index 12b99cbea..dec4d9303 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -21,7 +21,7 @@ export async function runCommand( ? { ...process.env, ...env - } + } : undefined }); if (hasOnData) { From dd516f21767fa304bb9648c0aee5e7e351cc7807 Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 30 May 2024 14:02:11 +0800 Subject: [PATCH 4/5] Revert "fix: commit ci (#27)" This reverts commit a4ab1f2203bda7ddc0a9ad55091cae06278714c9. --- .github/workflows/bench_rspack_commit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/bench_rspack_commit.yml b/.github/workflows/bench_rspack_commit.yml index 730bb5a22..cf5bafc87 100644 --- a/.github/workflows/bench_rspack_commit.yml +++ b/.github/workflows/bench_rspack_commit.yml @@ -37,7 +37,7 @@ jobs: with: path: ${{ env.RSPACK_DIR }} - name: Run benchmark - run: node bin/cli.js bench --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} + run: node bin/cli.js bench --shard ${{ matrix.shardIndex }}/${{ smatrix.shardTotal }} - uses: actions/upload-artifact@v4 with: name: benchmark-artifacts-${{ matrix.shardIndex }}-${{ matrix.shardTotal }} From 3b8e115be846e501ab95ae500fea5ac092c998ac Mon Sep 17 00:00:00 2001 From: Cong-Cong Date: Thu, 30 May 2024 14:02:12 +0800 Subject: [PATCH 5/5] Revert "feat: improve ci perf (#21)" This reverts commit 45ee41f894d28944778eca26faa8f5dbe43cfdcf. --- .github/actions/build-rspack/action.yaml | 52 ------ .github/actions/env/action.yml | 4 +- .../prepare-rspack-binding/action.yaml | 41 ----- .github/workflows/bench_rspack_commit.yml | 65 +++---- .github/workflows/bench_rspack_pr.yml | 62 ++----- .github/workflows/ci.yml | 33 +--- .github/workflows/scheduled_bench.yml | 9 +- .prettierignore | 5 - README.md | 68 ++++---- bench.config.js | 17 -- bin/bench.js | 41 +++++ bin/build-rspack.js | 8 + bin/cli.js | 161 ------------------ bin/compare-bench.js | 103 +++++++++++ docs/index.css | 16 +- docs/index.html | 18 +- docs/index.js | 45 ++--- lib/addons/10x/loader.cjs | 31 ++-- lib/addons/intercept-plugin.js | 1 + lib/compare.js | 97 +---------- lib/display.js | 17 +- lib/index.js | 2 + lib/rspack.js | 48 ++++++ lib/scenarios/build-plugin.cjs | 9 +- lib/scenarios/index.js | 17 +- lib/scenarios/utils.js | 4 +- lib/utils.js | 2 - package.json | 10 +- pnpm-lock.yaml | 91 +--------- 29 files changed, 358 insertions(+), 719 deletions(-) delete mode 100644 .github/actions/build-rspack/action.yaml delete mode 100644 .github/actions/prepare-rspack-binding/action.yaml delete mode 100644 .prettierignore delete mode 100644 bench.config.js create mode 100644 bin/bench.js create mode 100644 bin/build-rspack.js delete mode 100644 bin/cli.js create mode 100644 bin/compare-bench.js create mode 100644 lib/rspack.js diff --git a/.github/actions/build-rspack/action.yaml b/.github/actions/build-rspack/action.yaml deleted file mode 100644 index 551faa0df..000000000 --- a/.github/actions/build-rspack/action.yaml +++ /dev/null @@ -1,52 +0,0 @@ -name: "Build Rspack" -description: "Checkout, download rspack binding, and build rspack js" - -inputs: - repository: - description: "The rspack repository to use" - required: true - default: "web-infra-dev/rspack" - path: - description: "Destination path to the rspack repository" - required: true - default: ".rspack" - ref: - description: "The branch, tag or SHA to checkout" - required: true - default: "main" - node-version: - description: "The version of Node.js to set up" - required: true - default: "18" - -outputs: - artifact-name: - description: "The name of the uploaded artifact" - -runs: - using: composite - steps: - - shell: bash - run: | - npm install -g corepack@0.24.1 - echo "Corepack version: $(corepack --version)" - corepack enable - - shell: bash - run: pnpm --version - - shell: bash - run: pnpm install --prefer-frozen-lockfile --prefer-offline - - name: Build Rspack JS - shell: bash - run: >- - node bin/cli.js build - --repository ${{ inputs.repository }} - --ref ${{ inputs.ref }} - --binding false - --js true - - uses: actions/download-artifact@v4 - with: - name: binding-linux-x64-gnu - path: ${{ inputs.path }}/crates/node_binding - - name: Show restored binding - shell: bash - run: ls -lah ${{ inputs.path }}/crates/node_binding/*.node diff --git a/.github/actions/env/action.yml b/.github/actions/env/action.yml index c5574217f..9a7237f3b 100644 --- a/.github/actions/env/action.yml +++ b/.github/actions/env/action.yml @@ -6,7 +6,7 @@ runs: using: composite steps: - name: Setup node - uses: actions/setup-node@v4 + uses: actions/setup-node@v3 with: node-version: 20 - name: Activate corepack @@ -19,7 +19,7 @@ runs: corepack enable - name: Install dependencies with pnpm shell: bash - run: pnpm install --prefer-frozen-lockfile --prefer-offline + run: pnpm install - name: Set Rspack Dir shell: bash run: | diff --git a/.github/actions/prepare-rspack-binding/action.yaml b/.github/actions/prepare-rspack-binding/action.yaml deleted file mode 100644 index 6eea579aa..000000000 --- a/.github/actions/prepare-rspack-binding/action.yaml +++ /dev/null @@ -1,41 +0,0 @@ -name: "Prepare Rspack Binding" -description: "Checkout, build, and upload rspack native bindings" - -inputs: - repository: - description: "The rspack repository to use" - required: true - default: "web-infra-dev/rspack" - path: - description: "Destination path to clone" - required: true - default: ".rspack" - ref: - description: "The branch, tag or SHA to checkout" - required: true - default: "main" - node-version: - description: "The version of Node.js to set up" - required: true - default: "18" - -outputs: - artifact-name: - description: "The name of the uploaded artifact" - -runs: - using: composite - steps: - - name: Build Rspack - shell: bash - run: >- - node bin/cli.js build - --repository ${{ inputs.repository }} - --ref ${{ inputs.ref }} - --binding true - --js false - - uses: actions/upload-artifact@v4 - with: - name: binding-linux-x64-gnu - path: ${{ inputs.path }}/crates/node_binding/*.node - compression-level: 9 diff --git a/.github/workflows/bench_rspack_commit.yml b/.github/workflows/bench_rspack_commit.yml index cf5bafc87..73b63abf8 100644 --- a/.github/workflows/bench_rspack_commit.yml +++ b/.github/workflows/bench_rspack_commit.yml @@ -9,70 +9,43 @@ on: type: string jobs: - prepare-binding: - name: Prepare Rspack Binding + run-bench: runs-on: [self-hosted, benchmark] + outputs: + diff-result: ${{ steps.print-results.outputs.diff-result }} steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v2 - name: Init env uses: ./.github/actions/env - - uses: ./.github/actions/prepare-rspack-binding - with: - path: ${{ env.RSPACK_DIR }} - - bench: - runs-on: [self-hosted, benchmark] - needs: prepare-binding - timeout-minutes: 30 - strategy: - matrix: - shardIndex: [1, 2, 3] - shardTotal: [3] - fail-fast: false - steps: - - uses: actions/checkout@v4 - - name: Init env - uses: ./.github/actions/env - - uses: ./.github/actions/build-rspack - with: - path: ${{ env.RSPACK_DIR }} + - name: Build rspack + run: node bin/build-rspack.js origin ${{ inputs.commit_sha }} - name: Run benchmark - run: node bin/cli.js bench --shard ${{ matrix.shardIndex }}/${{ smatrix.shardTotal }} - - uses: actions/upload-artifact@v4 - with: - name: benchmark-artifacts-${{ matrix.shardIndex }}-${{ matrix.shardTotal }} - path: output - - comment-compare-results: - runs-on: ubuntu-latest - needs: bench - if: always() - steps: - - uses: actions/checkout@v4 - - name: Init env - uses: ./.github/actions/env - - uses: actions/download-artifact@v4 - with: - pattern: benchmark-artifacts-* - path: output - merge-multiple: true + run: node bin/bench.js - id: print-results name: Print results run: | - result=$(node bin/cli.js compare --base latest --current current) + result=$(node bin/compare-bench.js latest current) echo "$result" echo "diff-result=${result//$'\n'/'@@'}" >> $GITHUB_OUTPUT if [[ $result =~ "Threshold exceeded" ]]; then echo "Some benchmark cases exceed the threshold, please visit the previous step for more information" exit 1 fi - - uses: actions/github-script@v6 + + create-comment: + runs-on: ubuntu-latest + needs: [run-bench] + if: always() + steps: + - id: create-comment + uses: actions/github-script@v6 with: github-token: ${{ secrets.RSPACK_BOT_ACCESS_TOKEN }} result-encoding: string script: | - const diffResult = `${{ steps.print-results.outputs.diff-result }}` - let result = "task ${{ needs.bench.result }}" + const diffResult = `${{ needs.run-bench.outputs.diff-result }}` + let result = "task ${{ needs.run-bench.result }}" if (diffResult) { result = diffResult.replace(/@@/g, "\n"); } diff --git a/.github/workflows/bench_rspack_pr.yml b/.github/workflows/bench_rspack_pr.yml index 8a4f318f9..073353c67 100644 --- a/.github/workflows/bench_rspack_pr.yml +++ b/.github/workflows/bench_rspack_pr.yml @@ -31,72 +31,42 @@ jobs: }) return comment.id - prepare-binding: - name: Prepare Rspack Binding + run-bench: runs-on: [self-hosted, benchmark] - steps: - - uses: actions/checkout@v4 - - name: Init env - uses: ./.github/actions/env - - uses: ./.github/actions/prepare-rspack-binding - with: - path: ${{ env.RSPACK_DIR }} - - bench: - runs-on: [self-hosted, benchmark] - needs: [create-comment, prepare-binding] - timeout-minutes: 30 - strategy: - matrix: - shardIndex: [1, 2, 3] - shardTotal: [3] - fail-fast: false + needs: create-comment outputs: diff-result: ${{ steps.print-results.outputs.diff-result }} steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v2 - name: Init env uses: ./.github/actions/env - - uses: ./.github/actions/build-rspack - with: - path: ${{ env.RSPACK_DIR }} - ref: pull/${{ inputs.prNumber }}/head + - name: Build rspack + run: node bin/build-rspack.js origin pull/${{ inputs.prNumber }}/head - name: Run benchmark - run: node bin/cli.js bench --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} - - uses: actions/upload-artifact@v4 - with: - name: benchmark-artifacts-${{ matrix.shardIndex }}-${{ matrix.shardTotal }} - path: output - - comment-compare-results: - runs-on: ubuntu-latest - needs: [create-comment, bench] - if: always() - steps: - - uses: actions/checkout@v4 - - name: Init env - uses: ./.github/actions/env - - uses: actions/download-artifact@v4 - with: - pattern: benchmark-artifacts-* - path: output - merge-multiple: true + run: node bin/bench.js - id: print-results name: Print results run: | - result=$(node bin/cli.js compare --base latest --current current) + result=$(node bin/compare-bench.js latest current) echo "$result" echo "diff-result=${result//$'\n'/'@@'}" >> $GITHUB_OUTPUT if [[ $result =~ "Threshold exceeded" ]]; then echo "Some benchmark cases exceed the threshold, please visit the previous step for more information" exit 1 fi + + update-comment: + runs-on: ubuntu-latest + needs: [create-comment, run-bench] + if: always() + steps: - uses: actions/github-script@v6 with: github-token: ${{ secrets.RSPACK_BOT_ACCESS_TOKEN }} script: | - const diffResult = `${{ steps.print-results.outputs.diff-result }}` - let result = "task ${{ needs.bench.result }}" + const diffResult = `${{ needs.run-bench.outputs.diff-result }}` + let result = "task ${{ needs.run-bench.result }}" if (diffResult) { result = diffResult.replace(/@@/g, "\n"); } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index faadd36b6..2746da2cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: - "**/*.md" pull_request: types: [opened, synchronize] - branches: [main] + branches: [ main ] paths-ignore: - "**/*.md" @@ -17,40 +17,21 @@ concurrency: cancel-in-progress: ${{ github.ref_name != 'main' }} jobs: - prepare-binding: - name: Prepare Rspack Binding + ci: runs-on: [self-hosted, benchmark] - steps: - - uses: actions/checkout@v4 - - name: Init env - uses: ./.github/actions/env - - uses: ./.github/actions/prepare-rspack-binding - with: - path: ${{ env.RSPACK_DIR }} - - bench: - needs: prepare-binding - runs-on: [self-hosted, benchmark] - timeout-minutes: 30 - strategy: - matrix: - shardIndex: [1, 2, 3] - shardTotal: [3] - fail-fast: false steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v2 - name: Init env uses: ./.github/actions/env - - uses: ./.github/actions/build-rspack - with: - path: ${{ env.RSPACK_DIR }} + - name: Build rspack + run: node bin/build-rspack.js - name: Run benchmark - run: node bin/cli.js bench --shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }} + run: node bin/bench.js - id: print-compare-results name: Print compare results run: | - result=$(node bin/cli.js compare --base latest --current current) + result=$(node bin/compare-bench.js latest current) echo "$result" echo "diff-result=${result//$'\n'/'@@'}" >> $GITHUB_OUTPUT - name: Check Threshold diff --git a/.github/workflows/scheduled_bench.yml b/.github/workflows/scheduled_bench.yml index b35a5f27c..9d4b2e649 100644 --- a/.github/workflows/scheduled_bench.yml +++ b/.github/workflows/scheduled_bench.yml @@ -8,17 +8,18 @@ jobs: bench: runs-on: [self-hosted, benchmark] steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v2 - name: Init env uses: ./.github/actions/env - name: Build rspack - run: node bin/cli.js build + run: node bin/build-rspack.js - name: Run benchmark - run: node bin/cli.js bench + run: node bin/bench.js - id: print-compare-results name: Print compare results run: | - result=$(node bin/cli.js compare --base latest --current current) + result=$(node bin/compare-bench.js latest current) echo "$result" echo "diff-result=${result//$'\n'/'@@'}" >> $GITHUB_OUTPUT - name: Setup git user diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 93da55ad6..000000000 --- a/.prettierignore +++ /dev/null @@ -1,5 +0,0 @@ -.rspack/** -output/** -cases/** -pnpm-lock.yaml -pnpm-workspace.yaml diff --git a/README.md b/README.md index d5fb0d9e1..b342a7008 100644 --- a/README.md +++ b/README.md @@ -6,36 +6,36 @@ This repository is used to monitor rspack performance. You can use the scripts in the `bin` directory to prepare and run benchmark. -- `node bin/build-rspack.js [remote] [branch]` +* `node bin/build-rspack.js [remote] [branch]` Clone and build [rspack](https://github.com/web-infra-dev/rspack) in the folder which defined by the environment variable of `RSPACK_DIR` or `/.rspack`. You can set target branch with the parameter. eg. -```bash +``` bash node bin/build-rspack.js # use the main branch to build node bin/build-rspack.js origin main # use the main branch to build node bin/build-rspack.js origin pull/1000/head # use the pull request with index 1000 to build ``` -- `node bin/bench.js [benchmarkNames...]` +* `node bin/bench.js [benchmarkNames...]` Run benchmark with rspack and write the output to `output` folder. You can configure the environment variable of `RSPACK_DIR` to set the rspack project path, and it will use the rspack from the `.rspack` folder by default. eg. -```bash +``` bash node bin/bench.js # run all benchmarks node bin/bench.js 10000_development-mode 10000_production-mode # run benchmarks named 10000_development-mode and 10000_production-mode RSPACK_DIR= node bin/bench.js 10000_development-mode_hmr # set the rspack command path, and run 10000_development-mode_hmr ``` -- `node bin/compare-bench.js ` +* `node bin/compare-bench.js ` Compare and print the difference between `` and ``. The parameter has three types, `current` will use the data from `output` folder. `latest` will use the latest data from `data` branch. A date string like `YYYY-MM-DD` will use the data of that day from `data` branch. eg. -```bash +``` bash node bin/compare-bench.js current latest # use output data as base, and latest data as current node bin/compare-bench.js latest 2023-08-17 # use latest data as base, and the data of 2023-08-17 as current ``` -- `node bin/upload.js` +* `node bin/upload.js` Clone the data branch to `.data` folder, copy `output` folder into it and push it to the remote. @@ -43,23 +43,23 @@ Clone the data branch to `.data` folder, copy `output` folder into it and push i #### Benchmark Name -Benchmark name is a string containing the case name and the addon names. A benchmark name is separated by "\_", the first part is the case name, amd the other parts are the addon names. +Benchmark name is a string containing the case name and the addon names. A benchmark name is separated by "_", the first part is the case name, amd the other parts are the addon names. #### Case The benchmark case is the rspack project in `cases` folder. It must contain `rspack.config.js` and `hmr.js`, the first one is the default config for rspack, the next one is used to tell benchmark how to change file when hmr. -- `10000` is a project with 10000 modules -- `threejs` is a copy of three js +* `10000` is a project with 10000 modules +* `threejs` is a copy of three js #### Addon The addon is used to change rspack configuration and benchmark parameters. All addons are registered in `lib/addons`. -- `development-mode` is used to set the development mode -- `production-mode` is used to set the production mode -- `10x` is used to make the project module 10 times larger -- `hmr` is used to change the phase of collected metrics to hmr instead of build +* `development-mode` is used to set the development mode +* `production-mode` is used to set the production mode +* `10x` is used to make the project module 10 times larger +* `hmr` is used to change the phase of collected metrics to hmr instead of build #### Metric @@ -73,7 +73,7 @@ The tag is `benchmarkName` + `metric`, it is used to display information on webs Rspack benchmark consists of the following steps. -```mermaid +``` mermaid flowchart LR A("Setup") --> B("Generate") B --> C("Warmup") @@ -82,16 +82,16 @@ flowchart LR E --> F("Teardown") ``` -- `Setup` is used to prepare the benchmark case environment and global context. -- `Generate` will generate the benchmark case. -- `Warmup` will attempt to run the benchmark case. -- `Run` will run the benchmark case multiple times and collect metric data. -- `Statistic` will calculate the final result through multiple benchmarks. -- `Teardown` is used to clean up. +* `Setup` is used to prepare the benchmark case environment and global context. +* `Generate` will generate the benchmark case. +* `Warmup` will attempt to run the benchmark case. +* `Run` will run the benchmark case multiple times and collect metric data. +* `Statistic` will calculate the final result through multiple benchmarks. +* `Teardown` is used to clean up. The main process is controlled by `scenario`, and its structure is: -```typescript +``` typescript interface Context { caseDir: string originalFiles: Record @@ -141,19 +141,19 @@ interface Scenario { The addons can change context in most steps, and its structure is: -```typescript +``` typescript interface Addon { - beforeSetup(): void; - afterSetup(ctx: Context): void; - - beforeGenerate(ctx: Context): void; - afterGenerate(ctx: Context): void; - - beforeStatistic(ctx: Context): void; - afterStatistic(ctx: Context): void; - - beforeTeardown(ctx: Context): void; - afterTeardown(ctx: Context): void; + async beforeSetup(): void + async afterSetup(ctx: Context): void + + async beforeGenerate(ctx: Context): void + async afterGenerate(ctx: Context): void + + async beforeStatistic(ctx: Context): void + async afterStatistic(ctx: Context): void + + async beforeTeardown(ctx: Context): void + async afterTeardown(ctx: Context): void } ``` diff --git a/bench.config.js b/bench.config.js deleted file mode 100644 index 7fb6c93ee..000000000 --- a/bench.config.js +++ /dev/null @@ -1,17 +0,0 @@ -export default { - jobs: [ - "10000_development-mode", - "10000_development-mode_hmr", - "10000_production-mode", - "arco-pro_development-mode", - "arco-pro_development-mode_intercept-plugin", - "arco-pro_development-mode_hmr", - "arco-pro_development-mode_hmr_intercept-plugin", - "arco-pro_production-mode", - "arco-pro_production-mode_intercept-plugin", - "threejs_development-mode_10x", - "threejs_development-mode_10x_hmr", - "threejs_production-mode_10x" - ], - rspackDirectory: process.env.RSPACK_DIR -}; diff --git a/bin/bench.js b/bin/bench.js new file mode 100644 index 000000000..1a572603b --- /dev/null +++ b/bin/bench.js @@ -0,0 +1,41 @@ +import { resolve } from "path"; +import { fileURLToPath } from "url"; +import { mkdir, writeFile } from "fs/promises"; +import { run, formatResultTable } from "../lib/index.js"; + +const [, , ...benchmarkNames] = process.argv; + +const rootDir = resolve(fileURLToPath(import.meta.url), "../.."); +const defaultBenchmarkNames = [ + "10000_development-mode", + "10000_development-mode_hmr", + "10000_production-mode", + "arco-pro_development-mode", + "arco-pro_development-mode_intercept-plugin", + "arco-pro_development-mode_hmr", + "arco-pro_development-mode_hmr_intercept-plugin", + "arco-pro_production-mode", + "arco-pro_production-mode_intercept-plugin", + "threejs_development-mode_10x", + "threejs_development-mode_10x_hmr", + "threejs_production-mode_10x" +]; + +(async () => { + await mkdir(resolve(rootDir, "output"), { recursive: true }); + const benchmarks = benchmarkNames.length + ? benchmarkNames + : defaultBenchmarkNames; + for (const item of benchmarks) { + const result = await run(item); + console.log(`${item} result is:`); + console.log(formatResultTable(result, { verbose: true })); + await writeFile( + resolve(rootDir, `output/${item}.json`), + JSON.stringify(result, null, 2) + ); + } +})().catch(err => { + process.exitCode = 1; + console.error(err.stack); +}); diff --git a/bin/build-rspack.js b/bin/build-rspack.js new file mode 100644 index 000000000..9ed192ee4 --- /dev/null +++ b/bin/build-rspack.js @@ -0,0 +1,8 @@ +import { buildRspack } from "../lib/index.js"; + +const [, , remote = "origin", branch = "main"] = process.argv; + +buildRspack(remote, branch).catch(err => { + process.exitCode = 1; + console.error(err.stack); +}); diff --git a/bin/cli.js b/bin/cli.js deleted file mode 100644 index 78a5effd2..000000000 --- a/bin/cli.js +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/env node -import { mkdir, writeFile } from "node:fs/promises"; -import { join } from "node:path"; -import meow from "meow"; -import { $, cd } from "zx"; -import actionsCore from "@actions/core"; -import { run, formatResultTable } from "../lib/index.js"; -import { isGitHubActions, dirExist } from "../lib/utils.js"; -import { compare } from "../lib/compare.js"; - -$.verbose = true; - -const cli = meow({ - importMeta: import.meta, - flags: { - // Rspack repository name. - repository: { - type: "string", - default: "web-infra-dev/rspack" - }, - // The branch, tag or SHA to checkout. When checking out the repository that - // triggered a workflow, this defaults to the reference or SHA for that event. - // Otherwise, uses the default branch. - ref: { - type: "string", - default: "main" - }, - - binding: { - type: "boolean", - default: true - }, - js: { - type: "boolean", - default: true - }, - - shard: { - type: "string", - default: "1/1" - }, - - base: { - type: "string", - default: "latest" - }, - current: { - type: "string", - default: "current" - } - } -}); - -const command = cli.input.at(0); - -const { - repository, - ref, - - binding, - js, - - shard, - - base, - current -} = cli.flags; - -const cwd = process.cwd(); - -const configPath = join(process.cwd(), "bench.config.js"); -const config = (await import(configPath)).default; - -const jobs = config.jobs ?? []; -const rspackDirectory = config.rspackDirectory ?? join(cwd, ".rspack"); -const benchmarkDirectory = config.benchmarkDirectory ?? join(cwd, "output"); - -if (!command || command === "build") { - const fetchUrl = `https://github.com/${repository}`; - if (!(await dirExist(rspackDirectory))) { - await $`git clone ${fetchUrl} ${rspackDirectory}`; - } - - cd(rspackDirectory); - - await $`git reset --hard`; - const currentBranch = (await $`git rev-parse --abbrev-ref HEAD`) - .toString() - .trim(); - await $`git fetch ${fetchUrl} ${ref} --prune`; - await $`git checkout -b ${Date.now()} FETCH_HEAD`; - if (currentBranch) { - await $`git branch -D ${currentBranch}`; - } - - await $`git log -1`; - - await $`pnpm --version`; - await $`pnpm install --prefer-frozen-lockfile --prefer-offline`; - - if (binding) { - await $`pnpm run build:binding:release`; - } - - if (js) { - await $`pnpm run build:js`; - } - - cd(cwd); -} - -if (!command || command === "bench") { - const shardPair = shard.split("/").map(t => parseInt(t, 10)); - const [currentIndex, totalShards] = shardPair; - - const shardSize = Math.ceil(jobs.length / totalShards); - const shardJobs = jobs.slice( - shardSize * (currentIndex - 1), - shardSize * currentIndex - ); - - await mkdir(benchmarkDirectory, { recursive: true }); - - if (shardJobs.length) { - console.log( - [ - `Running jobs for shard ${currentIndex}/${totalShards}:`, - ...shardJobs - ].join("\n * ") - ); - - for (const job of shardJobs) { - const start = Date.now(); - const result = await run(job); - if (isGitHubActions) { - actionsCore.startGroup(`${job} result is`); - } else { - console.log(`${job} result is`); - } - - console.log(formatResultTable(result, { verbose: true })); - - if (isGitHubActions) { - actionsCore.endGroup(); - const cost = Math.ceil((Date.now() - start) / 1000); - console.log(`Cost for \`${job}\`: ${cost} s`); - } - - await writeFile( - join(benchmarkDirectory, `${job}.json`), - JSON.stringify(result, null, 2) - ); - } - } else { - console.log(`No jobs to run for shard ${currentIndex}/${totalShards}.`); - } -} - -if (!command || command === "compare") { - compare(base, current, benchmarkDirectory); -} diff --git a/bin/compare-bench.js b/bin/compare-bench.js new file mode 100644 index 000000000..81b0f8a58 --- /dev/null +++ b/bin/compare-bench.js @@ -0,0 +1,103 @@ +import { resolve, basename } from "path"; +import { fileURLToPath } from "url"; +import { readFile, readdir } from "fs/promises"; +import { compare, formatDiffTable } from "../lib/index.js"; +import { fetchBuildInfo, fetchIndex, fetchBenchmarkResult } from "../lib/services.js"; + +let [ + , + , + baseDate = "latest", + currentDate = "current" +] = process.argv; + +const compareMetric = ["exec"]; +const rootDir = resolve(fileURLToPath(import.meta.url), "../.."); +const outputDir = resolve(rootDir, "output"); + +const index = await fetchIndex(); +if (baseDate === "latest") { + baseDate = index[index.length - 1].date; +} + +function getOverThresholdTags(diff) { + return Object.entries(diff) + .map(([tag, data]) => { + if (!tag.endsWith(" memory") && !tag.endsWith(" size")) { + // time type + if (data.currentMean < 300) { + return null; + } + } + if (data.currentMean / data.baseMean < 1.05) { + return null; + } + return tag; + }) + .filter(item => !!item); +} + +// get the result by date +// `current` will get ../output data +// `latest` will get the latest data on the data branch +// `2023-08-08` will get the data from `2023-08-08` on the data branch +async function getResults(date) { + if (date === "current") { + const outputFiles = await readdir(outputDir); + return await Promise.all( + outputFiles.map(async item => { + return { + name: basename(item, '.json'), + result: JSON.parse(await readFile(resolve(outputDir, item))) + }; + }) + ); + } + + return Promise.all( + index + .find(i => i.date === date) + .files + .map(async file => ({ + name: basename(file, '.json'), + result: await fetchBenchmarkResult(date, file) + })) + ); +} + +(async () => { + const [baseResults, currentResults, buildInfo] = await Promise.all([ + getResults(baseDate), + getResults(currentDate), + fetchBuildInfo() + ]); + const baseData = {}; + const currentData = {}; + for (const metric of compareMetric) { + for (const { name, result } of baseResults) { + const tag = `${name} + ${metric}`; + baseData[tag] = result[metric]; + } + + for (const { name, result } of currentResults) { + const tag = `${name} + ${metric}`; + currentData[tag] = result[metric]; + } + } + + const diff = compare(baseData, currentData); + const formatedTable = formatDiffTable({ + diff, + baseDate, + baseCommitSHA: buildInfo[baseDate]?.commitSHA, + }); + const overThresholdTags = getOverThresholdTags(diff); + console.log(formatedTable); + if (overThresholdTags.length > 0) { + console.log(""); + console.log("Threshold exceeded: ", JSON.stringify(overThresholdTags)); + } +})().catch(err => { + process.exitCode = 1; + console.error(err.stack); +}); diff --git a/docs/index.css b/docs/index.css index 0ed9b91af..d38f1b8ea 100644 --- a/docs/index.css +++ b/docs/index.css @@ -4,9 +4,9 @@ body { padding: 0; } body { - max-width: 1200px; - margin: auto; - padding: 0 24px; + max-width: 1200px; + margin: auto; + padding: 0 24px; } .action-container, @@ -90,12 +90,12 @@ body { } .chart-container { - min-height: 600px; + min-height: 600px; } .slider-container { - padding: 0 32px; - margin-bottom: 32px; + padding: 0 32px; + margin-bottom: 32px; } .slider { position: relative; @@ -109,8 +109,8 @@ body { top: 0; bottom: 0; background: #1677ff; - transition: 0.2s; - cursor: pointer; + transition: 0.2s; + cursor: pointer; } .slider .mark { position: absolute; diff --git a/docs/index.html b/docs/index.html index 010628b62..0375ae24d 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,4 +1,4 @@ - + rspack/benchmark @@ -16,18 +16,18 @@

rspack/benchmark

Add -
Display benchmark tags:
+
Display benchmark tags:
-
-
- - - -
-
+
+
+ + + +
+
diff --git a/docs/index.js b/docs/index.js index c84504593..4bb015030 100644 --- a/docs/index.js +++ b/docs/index.js @@ -27,7 +27,7 @@ const debounce = (fn, t) => { timer = setTimeout(() => fn(...args), t); }; }; -const getAxisType = tag => { +const getAxisType = (tag) => { if (tag.endsWith(" size") || tag.endsWith(" memory")) { return "size"; } else if (tag.endsWith(" cache")) { @@ -73,9 +73,7 @@ class DataCenter { this.index = index; // generate metrics struct - const latestData = await fetch(`${fetchPrefix}/${lines.pop()}`).then(res => - res.json() - ); + const latestData = await fetch(`${fetchPrefix}/${lines.pop()}`).then(res => res.json()); this.metrics = Object.keys(latestData); // set date range @@ -84,19 +82,14 @@ class DataCenter { async fetchBuildInfo() { try { - this.buildInfo = await fetch(`${fetchPrefix}/build-info.json`).then( - res => { - if (!res.ok) { - throw new Error(`Request failed with status code ${res.status}`); - } - return res.json(); + this.buildInfo = await fetch(`${fetchPrefix}/build-info.json`).then(res => { + if (!res.ok) { + throw new Error(`Request failed with status code ${res.status}`); } - ); + return res.json() + }); } catch (err) { - console.log( - "Error occurred while fetching build-info.json: ", - err.message - ); + console.log("Error occurred while fetching build-info.json: ", err.message); } } @@ -108,9 +101,7 @@ class DataCenter { if (!this.cache[benchmarkName]) { this.cache[benchmarkName] = await Promise.all( this.index[benchmarkName].map(async date => { - const file = await fetch( - `${fetchPrefix}/${date}/${benchmarkName}.json` - ).then(res => res.json()); + const file = await fetch(`${fetchPrefix}/${date}/${benchmarkName}.json`).then(res => res.json()); return { date, file }; }) ); @@ -250,14 +241,11 @@ class BenchmarkChart { if (activeElements.length === 0) { return; } - const { datasetIndex, index } = activeElements[0]; + const {datasetIndex, index} = activeElements[0]; const { x } = this.data.datasets[datasetIndex].data[index]; const commitSHA = buildInfo[x] ? buildInfo[x].commitSHA : null; if (commitSHA) { - window.open( - `https://github.com/web-infra-dev/rspack/commit/${commitSHA}`, - "_blank" - ); + window.open(`https://github.com/web-infra-dev/rspack/commit/${commitSHA}`, '_blank'); } }, scales: { @@ -316,10 +304,7 @@ class BenchmarkChart { title(context) { const date = context[0].raw.x; if (buildInfo[date] && buildInfo[date].commitSHA) { - return [ - date, - `commit sha: ${buildInfo[date].commitSHA.slice(0, 7)}` - ]; + return [date, `commit sha: ${buildInfo[date].commitSHA.slice(0, 7)}`]; } return date; }, @@ -329,8 +314,8 @@ class BenchmarkChart { context.dataset.yAxisID === "size" ? formatSize(value, value) : context.dataset.yAxisID === "ratio" - ? formatRatio(value, value) - : formatTime(value, value); + ? formatRatio(value, value) + : formatTime(value, value); return `${context.dataset.label}: ${text}`; } } @@ -381,7 +366,7 @@ class BenchmarkChart { const pc = (end - begin) / 100; this.chart.options.scales.x.min = begin + pc * min; - this.chart.options.scales.x.max = begin + pc * max; + this.chart.options.scales.x.max = begin + pc * max; this.chart.update(); } } diff --git a/lib/addons/10x/loader.cjs b/lib/addons/10x/loader.cjs index d27036cce..e6d9fcd09 100644 --- a/lib/addons/10x/loader.cjs +++ b/lib/addons/10x/loader.cjs @@ -1,18 +1,15 @@ -module.exports = function (source) { - const { times } = this.getOptions(); - if (!this.resourceQuery) { - // entry - const resourcePath = this.resourcePath; - return new Array(times) - .fill(1) - .map((_, index) => { - return `export * as t${index} from "${resourcePath}?time=${index}";`; - }) - .join("\n"); - } +module.exports = function(source) { + const { times } = this.getOptions(); + if (!this.resourceQuery) { + // entry + const resourcePath = this.resourcePath; + return new Array(times).fill(1).map((_, index) => { + return `export * as t${index} from "${resourcePath}?time=${index}";` + }).join("\n"); + } - // add resource query to all import and export - return source.replace(/(import|export).+?from +['"`]\..+?['"`]/g, str => { - return str.slice(0, -1) + this.resourceQuery + str.slice(-1); - }); -}; + // add resource query to all import and export + return source.replace(/(import|export).+?from +['"`]\..+?['"`]/g, (str) => { + return str.slice(0, -1) + this.resourceQuery + str.slice(-1) + }) +} \ No newline at end of file diff --git a/lib/addons/intercept-plugin.js b/lib/addons/intercept-plugin.js index 0940fdffe..41c1b4985 100644 --- a/lib/addons/intercept-plugin.js +++ b/lib/addons/intercept-plugin.js @@ -27,5 +27,6 @@ function interceptPlugin(compiler) { module.exports.plugins = module.exports.plugins || []; module.exports.plugins.push(interceptPlugin) `; + } } diff --git a/lib/compare.js b/lib/compare.js index 37aa6a4e7..5f80b9f68 100644 --- a/lib/compare.js +++ b/lib/compare.js @@ -1,31 +1,4 @@ -import { resolve, basename } from "path"; -import { fileURLToPath } from "url"; -import { readFile, readdir } from "fs/promises"; -import { formatDiffTable } from "../lib/index.js"; -import { - fetchBuildInfo, - fetchIndex, - fetchBenchmarkResult -} from "../lib/services.js"; - -function getOverThresholdTags(diff) { - return Object.entries(diff) - .map(([tag, data]) => { - if (!tag.endsWith(" memory") && !tag.endsWith(" size")) { - // time type - if (data.currentMean < 300) { - return null; - } - } - if (data.currentMean / data.baseMean < 1.05) { - return null; - } - return tag; - }) - .filter(item => !!item); -} - -function compareData(base, current) { +export function compare(base, current) { const diff = {}; for (const key of new Set([...Object.keys(base), ...Object.keys(current)])) { const baseValue = base[key]; @@ -43,71 +16,3 @@ function compareData(base, current) { } return diff; } - -// get the result by date -// `current` will get ../output data -// `latest` will get the latest data on the data branch -// `2023-08-08` will get the data from `2023-08-08` on the data branch -async function getResults(date, index, benchmarkDirectory) { - if (date === "current") { - const outputFiles = await readdir(benchmarkDirectory); - return await Promise.all( - outputFiles.map(async item => { - return { - name: basename(item, ".json"), - result: JSON.parse(await readFile(resolve(benchmarkDirectory, item))) - }; - }) - ); - } - - return Promise.all( - index - .find(i => i.date === date) - .files.map(async file => ({ - name: basename(file, ".json"), - result: await fetchBenchmarkResult(date, file) - })) - ); -} - -export async function compare(base, current, benchmarkDirectory) { - const compareMetric = ["exec"]; - - const index = await fetchIndex(); - if (base === "latest") { - base = index[index.length - 1].date; - } - - const [baseResults, currentResults, buildInfo] = await Promise.all([ - getResults(base, index, benchmarkDirectory), - getResults(current, index, benchmarkDirectory), - fetchBuildInfo() - ]); - const baseData = {}; - const currentData = {}; - for (const metric of compareMetric) { - for (const { name, result } of baseResults) { - const tag = `${name} + ${metric}`; - baseData[tag] = result[metric]; - } - - for (const { name, result } of currentResults) { - const tag = `${name} + ${metric}`; - currentData[tag] = result[metric]; - } - } - - const diff = compareData(baseData, currentData); - const formatedTable = formatDiffTable({ - diff, - base, - baseCommitSHA: buildInfo[base]?.commitSHA - }); - const overThresholdTags = getOverThresholdTags(diff); - console.log(formatedTable); - if (overThresholdTags.length > 0) { - console.log(""); - console.log("Threshold exceeded: ", JSON.stringify(overThresholdTags)); - } -} diff --git a/lib/display.js b/lib/display.js index 5b050b1d6..0c85d9070 100644 --- a/lib/display.js +++ b/lib/display.js @@ -63,7 +63,12 @@ function formatTable(entries, columns) { ].join("\n"); } -export function formatDiffTable({ diff, baseDate, baseCommitSHA, limit }) { +export function formatDiffTable({ + diff, + baseDate, + baseCommitSHA, + limit +}) { let entries = Object.keys(diff).map(key => ({ name: key, ...diff[key] })); if (limit) { entries = entries.slice(0, limit); @@ -72,20 +77,16 @@ export function formatDiffTable({ diff, baseDate, baseCommitSHA, limit }) { let baseTitle = `Base (${baseDate}`; if (baseCommitSHA) { - baseTitle += ` [${baseCommitSHA.slice( - 0, - 7 - )}](https://github.com/web-infra-dev/rspack/commit/${baseCommitSHA})`; + baseTitle += ` [${baseCommitSHA.slice(0, 7)}](https://github.com/web-infra-dev/rspack/commit/${baseCommitSHA})`; } baseTitle += ")"; const columns = { Name: l => l.name, - [baseTitle]: l => - `${f(l.name, l.baseMean)} ± ${f(l.name, l.baseConfidence)}`, + [baseTitle]: l => `${f(l.name, l.baseMean)} ± ${f(l.name, l.baseConfidence)}`, Current: l => `${f(l.name, l.currentMean)} ± ${f(l.name, l.currentConfidence)}`, - Change: l => { + "Change": l => { const percent = ( ((l.currentMean - l.baseMean) * 100) / l.baseMean diff --git a/lib/index.js b/lib/index.js index ec99907ab..7cf9ad436 100644 --- a/lib/index.js +++ b/lib/index.js @@ -4,6 +4,8 @@ export { compare } from "./compare.js"; export { formatDiffTable, formatResultTable } from "./display.js"; +export { buildRspack } from "./rspack.js"; + export async function sendMessage(_info) { // TODO send alert message } diff --git a/lib/rspack.js b/lib/rspack.js new file mode 100644 index 000000000..408dc6730 --- /dev/null +++ b/lib/rspack.js @@ -0,0 +1,48 @@ +import { resolve } from "path"; +import { fileURLToPath } from "url"; +import { runCommand, dirExist } from "./utils.js"; + +const rootDir = resolve(fileURLToPath(import.meta.url), "../.."); +const rspackDir = process.env.RSPACK_DIR || resolve(rootDir, ".rspack"); +const repoUrl = `https://github.com/web-infra-dev/rspack.git`; + +async function switchToBranch(remote, branch) { + await runCommand("git", ["reset", "--hard"]); + + let currentBranch = ""; + await runCommand("git", ["rev-parse", "--abbrev-ref", "HEAD"], { + onData: function (name) { + currentBranch = name; + } + }); + + await runCommand("git", ["fetch", remote, branch, "--prune"]); + await runCommand("git", [ + "checkout", + "-b", + String(new Date().valueOf()), + "FETCH_HEAD" + ]); + if (currentBranch) { + await runCommand("git", ["branch", "-D", currentBranch]); + } +} + +export async function buildRspack(remote, branch) { + if (!(await dirExist(rspackDir))) { + console.log(`git clone ${repoUrl} ${rspackDir}`); + await runCommand("git", ["clone", repoUrl, rspackDir]); + } + process.chdir(rspackDir); + + console.log("== switch branch =="); + console.log("use branch: ", remote, branch); + await switchToBranch(remote, branch); + + console.log("== install deps =="); + await runCommand("pnpm", ["--version"]); + await runCommand("pnpm", ["install", "--no-frozen-lockfile"]); + + console.log("== build rspack =="); + await runCommand("npm", ["run", "build:cli:release"]); +} diff --git a/lib/scenarios/build-plugin.cjs b/lib/scenarios/build-plugin.cjs index c2d08c535..973a97954 100644 --- a/lib/scenarios/build-plugin.cjs +++ b/lib/scenarios/build-plugin.cjs @@ -14,7 +14,7 @@ module.exports = class BuildPlugin { if (isWatching && counter <= TOTAL_BUILDS) console.log("#!# next"); }, 10); }); - compiler.hooks.done.tap("BuildPlugin", stats => { + compiler.hooks.done.tap("BuildPlugin", (stats) => { if (isWatching) { counter++; if (counter <= WARMUP_BUILDS) return; @@ -29,7 +29,7 @@ module.exports = class BuildPlugin { const { logging, time } = stats.toJson({ all: false, timings: true, - logging: "verbose" + logging: "verbose", }); console.log(`#!# stats = ${time}`); const memoryUsage = process.memoryUsage(); @@ -51,11 +51,10 @@ module.exports = class BuildPlugin { } } else if (type === "cache") { if (args) { - const ratio = (args[1] / args[2]) * 100; + const ratio = args[1] / args[2] * 100; console.log(`#!# ${name}.${args[0]} = ${ratio}`); } else { - const [, label, ratio] = - /^(.+): ([\d.]+)% \(([\d.\/]+)\/([\d.\/]+)\)$/.exec(message); + const [, label, ratio] = /^(.+): ([\d.]+)% \(([\d.\/]+)\/([\d.\/]+)\)$/.exec(message); console.log(`#!# ${name}.${label} = ${ratio}`); } } diff --git a/lib/scenarios/index.js b/lib/scenarios/index.js index e95b88096..dc81cb208 100644 --- a/lib/scenarios/index.js +++ b/lib/scenarios/index.js @@ -1,8 +1,7 @@ import path from "path"; import { readFile, unlink, writeFile } from "fs/promises"; import { fileURLToPath } from "url"; -import actionsCore from "@actions/core"; -import { isGitHubActions, runCommand } from "../utils.js"; +import { runCommand } from "../utils.js"; import { getDirSizes, calcStatistics, @@ -92,19 +91,17 @@ module.exports.plugins.push(new (require("../../lib/scenarios/build-plugin.cjs") }; }, async generate(ctx) { - if (isGitHubActions) { - actionsCore.startGroup("Generating rspack configuration:"); - console.log(ctx.config); - actionsCore.endGroup(); - } - + console.log("generate rspack config:"); + console.log("```"); + console.log(ctx.config); + console.log("```"); await writeFile( path.resolve(ctx.caseDir, "rspack.config.js"), ctx.config ); const rspackDir = process.env.RSPACK_DIR || path.resolve(rootDir, ".rspack"); - console.log("Create Rspack package link"); + console.log("create rspack package link"); await runCommand("mkdir", [ "-p", path.resolve(rootDir, "node_modules/@rspack") @@ -126,7 +123,7 @@ module.exports.plugins.push(new (require("../../lib/scenarios/build-plugin.cjs") ]); }, async warmup(ctx) { - console.log("Run Rspack with args:", ctx.rspackArgs); + console.log("run rspack with args:", ctx.rspackArgs); await runRspack({ ...ctx, rspackArgs: ctx.rspackArgs.filter(a => a !== "--watch") diff --git a/lib/scenarios/utils.js b/lib/scenarios/utils.js index 6fcae0861..e451340b5 100644 --- a/lib/scenarios/utils.js +++ b/lib/scenarios/utils.js @@ -21,7 +21,7 @@ export async function clearCaches(directory) { } export async function getDirSizes(dir) { - let totalSize = 0; + let totalSize = 0; const dirContents = await fs.readdir(dir, { withFileTypes: true }); for (const dirent of dirContents) { if (dirent.isDirectory()) { @@ -31,7 +31,7 @@ export async function getDirSizes(dir) { totalSize += fileStats.size; } } - return totalSize; + return totalSize; } export async function getHmrConfig(filePath) { diff --git a/lib/utils.js b/lib/utils.js index dec4d9303..17609931d 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -57,5 +57,3 @@ export function formatDate(timestamp) { day < 10 ? "0" + day : day }`; } - -export const isGitHubActions = !!process.env.GITHUB_ACTIONS; diff --git a/package.json b/package.json index 62e778b08..61173ad53 100644 --- a/package.json +++ b/package.json @@ -2,17 +2,11 @@ "name": "rspack-ecosystem-benchmark", "type": "module", "dependencies": { - "@actions/core": "^1.10.1", "@icon-park/react": "^1.4.2", - "meow": "^13.2.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-refresh": "^0.14.0", - "undici": "^6.11.0", - "zx": "^8.1.1" + "undici": "^6.11.0" }, - "packageManager": "pnpm@8.14.3", - "devDependencies": { - "prettier": "^2.6.2" - } + "packageManager": "pnpm@8.14.3" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed37658d8..36ebd4d4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,15 +8,9 @@ importers: .: dependencies: - '@actions/core': - specifier: ^1.10.1 - version: 1.10.1 '@icon-park/react': specifier: ^1.4.2 version: 1.4.2(react-dom@18.2.0)(react@18.2.0) - meow: - specifier: ^13.2.0 - version: 13.2.0 react: specifier: ^18.2.0 version: 18.2.0 @@ -29,9 +23,6 @@ importers: undici: specifier: ^6.11.0 version: 6.11.0 - zx: - specifier: ^8.1.1 - version: 8.1.1 cases/10000: {} @@ -160,20 +151,6 @@ importers: packages: - /@actions/core@1.10.1: - resolution: {integrity: sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==} - dependencies: - '@actions/http-client': 2.2.1 - uuid: 8.3.2 - dev: false - - /@actions/http-client@2.2.1: - resolution: {integrity: sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw==} - dependencies: - tunnel: 0.0.6 - undici: 5.28.4 - dev: false - /@ampproject/remapping@2.2.1: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} engines: {node: '>=6.0.0'} @@ -1694,11 +1671,6 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - /@fastify/busboy@2.1.1: - resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} - engines: {node: '>=14'} - dev: false - /@icon-park/react@1.4.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-+MtQLjNiRuia3fC/NfpSCTIy5KH5b+NkMB9zYd7p3R4aAIK61AjK0OSraaICJdkKooU9jpzk8m0fY4g9A3JqhQ==} engines: {node: '>= 8.0.0', npm: '>= 5.0.0'} @@ -3000,15 +2972,6 @@ packages: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} dev: true - /@types/fs-extra@11.0.4: - resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} - requiresBuild: true - dependencies: - '@types/jsonfile': 6.1.4 - '@types/node': 14.18.63 - dev: false - optional: true - /@types/geojson@7946.0.8: resolution: {integrity: sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==} dev: false @@ -3024,24 +2987,9 @@ packages: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true - /@types/jsonfile@6.1.4: - resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - requiresBuild: true - dependencies: - '@types/node': 14.18.63 - dev: false - optional: true - /@types/node@14.18.63: resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} - - /@types/node@20.12.12: - resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==} - requiresBuild: true - dependencies: - undici-types: 5.26.5 - dev: false - optional: true + dev: true /@types/parse-json@4.0.2: resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -4916,11 +4864,6 @@ packages: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} dev: true - /meow@13.2.0: - resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} - engines: {node: '>=18'} - dev: false - /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} dev: true @@ -6095,11 +6038,6 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - /tunnel@0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - dev: false - /turf-jsts@1.2.3: resolution: {integrity: sha512-Ja03QIJlPuHt4IQ2FfGex4F4JAr8m3jpaHbFbQrgwr7s7L6U8ocrHiF3J1+wf9jzhGKxvDeaCAnGDot8OjGFyA==} dev: false @@ -6179,19 +6117,6 @@ packages: which-boxed-primitive: 1.0.2 dev: false - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - requiresBuild: true - dev: false - optional: true - - /undici@5.28.4: - resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} - engines: {node: '>=14.0'} - dependencies: - '@fastify/busboy': 2.1.1 - dev: false - /undici@6.11.0: resolution: {integrity: sha512-y4AOKcD36FXz+MY19yw8Emtbsdp8wBWTLln508+EJwqWezUheU5PSRbvIb+pQld7ZoOY8ruNwqSejSVGZUS/aA==} engines: {node: '>=18.0'} @@ -6289,11 +6214,6 @@ packages: tslib: 2.6.2 dev: false - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false - /value-equal@1.0.1: resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==} dev: false @@ -6451,12 +6371,3 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true - - /zx@8.1.1: - resolution: {integrity: sha512-JYAyM06wK+KLy07MkipBTghtd3zsYBxTH44Fh3p932ntDKdT5jxziEK51siPG+rqT+MWV1yK9mCM1/CB92PV7Q==} - engines: {node: '>= 12.17.0'} - hasBin: true - optionalDependencies: - '@types/fs-extra': 11.0.4 - '@types/node': 20.12.12 - dev: false