Skip to content

Commit ad55a72

Browse files
committed
Merge branch 'main' of https://github.com/web-infra-dev/rspack into hamlim/before-module-ids-hook
2 parents ba47962 + e31ee70 commit ad55a72

File tree

133 files changed

+2400
-498
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

133 files changed

+2400
-498
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
name: 'CodSpeed Performance Analysis'
2+
description: 'Continuous benchmarking and performance checks'
3+
branding:
4+
color: orange
5+
icon: activity
6+
7+
author: 'Arthur Pastel'
8+
inputs:
9+
run:
10+
description: 'The command to run the benchmarks'
11+
required: true
12+
13+
mode:
14+
description: |
15+
The mode to run the benchmarks in. The following modes are available:
16+
- `simulation`: Run the benchmarks with CPU simulation measurements.
17+
- `walltime`: Run the benchmarks with walltime measurement.
18+
- `memory`: Run the benchmarks with allocation measurements.
19+
- `instrumentation`: (Deprecated) Legacy name for `simulation`. Please use `simulation` instead.
20+
21+
We strongly recommend starting with the `simulation` mode.
22+
23+
Using the `walltime` mode on traditional VMs/Hosted Runners might lead to inconsistent data. For the best results, we recommend using CodSpeed Hosted Macro Runners, which are fine-tuned for performance measurement consistency.
24+
Check out the [Walltime Instrument Documentation](https://docs.codspeed.io/instruments/walltime/) for more details.
25+
required: true
26+
27+
token:
28+
description: |
29+
CodSpeed upload token. Only required for private repositories.
30+
required: false
31+
32+
working-directory:
33+
description: |
34+
The directory where the `run` command will be executed.
35+
Warning: if you use defaults.working-directory, you must still set this parameter.
36+
required: false
37+
38+
upload-url:
39+
description: 'The upload endpoint (for on-premise deployments)'
40+
required: false
41+
42+
runner-version:
43+
description: "The version of the runner to use. Use 'latest' to automatically fetch the latest release version from GitHub, or specify a version like '3.5.0' or 'v3.5.0'."
44+
required: false
45+
46+
instruments:
47+
description: |
48+
Comma separated list of instruments to enable. The following instruments are available:
49+
- `mongodb`: MongoDB instrumentation, requires the MongoDB instrument to be enabled for the organization in CodSpeed
50+
required: false
51+
52+
mongo-uri-env-name:
53+
description: |
54+
The name of the environment variable containing the MongoDB URI. Requires the `mongodb` instrument to be activated in `instruments`.
55+
If the instrumentation is enabled and this value is not set, the user will need to dynamically provide the MongoDB URI to the CodSpeed runner.
56+
required: false
57+
58+
cache-instruments:
59+
description: |
60+
Enable caching of instrument installations (like valgrind or perf) to speed up subsequent workflow runs. Set to 'false' to disable caching.
61+
required: false
62+
default: 'true'
63+
64+
instruments-cache-dir:
65+
description: |
66+
The directory to use for caching installations of instruments (like valgrind or perf). Defaults to `$HOME/.cache/codspeed-action`.
67+
required: false
68+
default: '~/.cache/codspeed-action'
69+
70+
allow-empty:
71+
description: |
72+
Allow the action to complete successfully even if no benchmarks were found or run. Set to 'true' to enable this behavior.
73+
required: false
74+
default: 'false'
75+
76+
runs:
77+
using: 'composite'
78+
steps:
79+
- shell: bash
80+
run: |
81+
# Validate required inputs
82+
# (custom message for smoother v4 migration)
83+
if [ -z "${{ inputs.mode }}" ]; then
84+
echo "::error title=Missing required input 'mode'::The 'mode' input is required as of CodSpeed Action v4. Please explicitly set 'mode' to 'simulation' or 'walltime'. Before, this variable was automatically set to instrumentation on every runner except for CodSpeed macro runners where it was set to walltime by default. See https://codspeed.io/docs/instruments for details."
85+
exit 1
86+
fi
87+
88+
# We can use official runner if it supports config valgrind flags in the future: https://github.com/CodSpeedHQ/runner/pull/92
89+
cargo install --git https://github.com/CPunisher/runner.git --rev 9c1ca5aa4742b8524843c0ac3e417c6ecb91b1bd codspeed-runner
90+
91+
# Get the runner arguments
92+
RUNNER_ARGS=""
93+
if [ -n "${{ inputs.token }}" ]; then
94+
RUNNER_ARGS="$RUNNER_ARGS --token ${{ inputs.token }}"
95+
fi
96+
if [ -n "${{ inputs.working-directory }}" ]; then
97+
RUNNER_ARGS="$RUNNER_ARGS --working-directory=${{ inputs.working-directory }}"
98+
fi
99+
if [ -n "${{ inputs.upload-url }}" ]; then
100+
RUNNER_ARGS="$RUNNER_ARGS --upload-url=${{ inputs.upload-url }}"
101+
fi
102+
if [ -n "${{ inputs.mode }}" ]; then
103+
RUNNER_ARGS="$RUNNER_ARGS --mode=${{ inputs.mode }}"
104+
fi
105+
if [ -n "${{ inputs.instruments }}" ]; then
106+
RUNNER_ARGS="$RUNNER_ARGS --instruments=${{ inputs.instruments }}"
107+
fi
108+
if [ -n "${{ inputs.mongo-uri-env-name }}" ]; then
109+
RUNNER_ARGS="$RUNNER_ARGS --mongo-uri-env-name=${{ inputs.mongo-uri-env-name }}"
110+
fi
111+
if [ "${{ inputs.cache-instruments }}" = "true" ] && [ -n "${{ inputs.instruments-cache-dir }}" ]; then
112+
RUNNER_ARGS="$RUNNER_ARGS --setup-cache-dir=${{ inputs.instruments-cache-dir }}"
113+
fi
114+
if [ "${{ inputs.allow-empty }}" = "true" ]; then
115+
RUNNER_ARGS="$RUNNER_ARGS --allow-empty"
116+
fi
117+
118+
# Run the benchmarks
119+
# Enable fair sched to make benchmark more stable, see: https://github.com/CodSpeedHQ/runner/pull/91
120+
env VALGRIND_FLAGS='--fair-sched=yes' codspeed run $RUNNER_ARGS -- '${{ inputs.run }}'

.github/workflows/reusable-build-bench.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
run: pnpm run build:js
7878

7979
- name: Run benchmark
80-
uses: CodSpeedHQ/action@0700edb451d0e9f2426f99bd6977027e550fb2a6 # https://github.com/CodSpeedHQ/action/releases/tag/v4.7.0
80+
uses: ./.github/actions/codspeed
8181
timeout-minutes: 30
8282
env:
8383
RAYON_NUM_THREADS: 1

.github/workflows/reusable-build-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,5 +175,5 @@ jobs:
175175
env:
176176
NODE_NO_WARNINGS: 1
177177
WASM: 1
178-
RSPACK_LOADER_WORKER_THREADS: 4
178+
RSPACK_LOADER_WORKER_THREADS: 1
179179
run: pnpm run test:ci

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
lts/jod
1+
22

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

agents/ARTIFACTS.md

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
# Artifacts
2+
3+
Design and usage of the artifact system in Rspack's incremental compilation.
4+
5+
## Overview
6+
7+
Artifacts are data structures that hold intermediate compilation results. They are designed to be recovered across rebuilds during incremental compilation, avoiding redundant recomputation when their associated compilation pass hasn't changed.
8+
9+
## Core Concepts
10+
11+
### ArtifactExt Trait
12+
13+
The `ArtifactExt` trait is the foundation of the artifact system. It associates each artifact with its corresponding incremental pass and provides recovery logic.
14+
15+
```rust
16+
pub trait ArtifactExt: Sized {
17+
/// The incremental pass associated with this artifact.
18+
const PASS: IncrementalPasses;
19+
20+
/// Determines whether this artifact should be recovered from the previous compilation.
21+
fn should_recover(incremental: &Incremental) -> bool {
22+
incremental.mutations_readable(Self::PASS)
23+
}
24+
25+
/// Recovers the artifact from the old compilation to the new compilation.
26+
fn recover(incremental: &Incremental, new: &mut Self, old: &mut Self) {
27+
if Self::should_recover(incremental) {
28+
mem::swap(new, old);
29+
}
30+
}
31+
}
32+
```
33+
34+
### recover_artifact Function
35+
36+
A helper function that invokes the trait's recovery method:
37+
38+
```rust
39+
pub fn recover_artifact<T: ArtifactExt>(incremental: &Incremental, new: &mut T, old: &mut T) {
40+
T::recover(incremental, new, old);
41+
}
42+
```
43+
44+
## Artifact Types
45+
46+
### Direct Artifacts
47+
48+
Artifacts that directly implement `ArtifactExt`:
49+
50+
| Artifact | PASS | Description |
51+
| --------------------------------- | ------------------------------ | ------------------------------- |
52+
| `ModuleIdsArtifact` | `MODULES_IDS` | Module ID mappings |
53+
| `ChunkNamedIdArtifact` | `CHUNKS_IDS` | Named chunk ID mappings |
54+
| `CgmHashArtifact` | `MODULES_HASHES` | Module hash data |
55+
| `CgmRuntimeRequirementsArtifact` | `MODULES_RUNTIME_REQUIREMENTS` | Module runtime requirements |
56+
| `CgcRuntimeRequirementsArtifact` | `CHUNKS_RUNTIME_REQUIREMENTS` | Chunk runtime requirements |
57+
| `ChunkHashesArtifact` | `CHUNKS_HASHES` | Chunk hash data |
58+
| `ChunkRenderArtifact` | `CHUNKS_RENDER` | Chunk render results |
59+
| `CodeGenerationResults` | `MODULES_CODEGEN` | Code generation results |
60+
| `SideEffectsOptimizeArtifact` | `SIDE_EFFECTS_OPTIMIZATION` | Side effects optimization data |
61+
| `AsyncModulesArtifact` | `INFER_ASYNC_MODULES` | Async modules information |
62+
| `DependenciesDiagnosticsArtifact` | `DEPENDENCIES_DIAGNOSTICS` | Dependencies diagnostics |
63+
| `ImportedByDeferModulesArtifact` | empty | Deferred module import tracking |
64+
65+
### Cache Artifacts
66+
67+
Artifacts with custom `recover` implementations that call `start_next_generation()`:
68+
69+
| Artifact | PASS | Description |
70+
| ----------------------------------------- | ------------------------------ | -------------------------- |
71+
| `ChunkRenderCacheArtifact` | `CHUNKS_RENDER` | Chunk render cache |
72+
| `CodeGenerateCacheArtifact` | `MODULES_CODEGEN` | Code generation cache |
73+
| `ProcessRuntimeRequirementsCacheArtifact` | `MODULES_RUNTIME_REQUIREMENTS` | Runtime requirements cache |
74+
75+
### Wrapper Types
76+
77+
Wrapper types that delegate to the inner type's `PASS`:
78+
79+
| Wrapper | Description |
80+
| ----------------------- | --------------------------------------------- |
81+
| `DerefOption<T>` | Optional artifact wrapper with deref support |
82+
| `Arc<AtomicRefCell<T>>` | Shared artifact wrapper for concurrent access |
83+
| `BindingCell<T>` | JS binding-aware wrapper (napi feature) |
84+
| `Box<T>` | Simple box wrapper (sys binding) |
85+
86+
## Usage in Rebuild
87+
88+
During rebuild, artifacts are recovered from the old compilation to the new compilation:
89+
90+
```rust
91+
// In Compiler::rebuild_inner
92+
93+
// Wrapped artifacts
94+
recover_artifact(
95+
incremental,
96+
&mut new_compilation.async_modules_artifact,
97+
&mut self.compilation.async_modules_artifact,
98+
);
99+
recover_artifact(
100+
incremental,
101+
&mut new_compilation.code_generation_results,
102+
&mut self.compilation.code_generation_results,
103+
);
104+
105+
// Direct type artifacts
106+
recover_artifact(
107+
incremental,
108+
&mut new_compilation.module_ids_artifact,
109+
&mut self.compilation.module_ids_artifact,
110+
);
111+
```
112+
113+
## Implementing a New Artifact
114+
115+
### Basic Artifact
116+
117+
```rust
118+
use crate::{ArtifactExt, incremental::IncrementalPasses};
119+
120+
#[derive(Debug, Default)]
121+
pub struct MyArtifact {
122+
// artifact data
123+
}
124+
125+
impl ArtifactExt for MyArtifact {
126+
const PASS: IncrementalPasses = IncrementalPasses::MY_PASS;
127+
}
128+
```
129+
130+
### Cache Artifact with Custom Recovery
131+
132+
```rust
133+
impl ArtifactExt for MyCacheArtifact {
134+
const PASS: IncrementalPasses = IncrementalPasses::MY_PASS;
135+
136+
fn recover(_incremental: &Incremental, new: &mut Self, old: &mut Self) {
137+
*new = std::mem::take(old);
138+
new.start_next_generation();
139+
}
140+
}
141+
```
142+
143+
### Wrapped Artifact
144+
145+
For artifacts wrapped in `Arc<AtomicRefCell<T>>`, `DerefOption<T>`, or `BindingCell<T>`, the wrapper automatically delegates to the inner type's `PASS`.
146+
147+
```rust
148+
// In Compilation struct
149+
pub my_artifact: Arc<AtomicRefCell<MyArtifact>>,
150+
151+
// Recovery is automatic through the wrapper's ArtifactExt impl
152+
recover_artifact(
153+
incremental,
154+
&mut new_compilation.my_artifact,
155+
&mut self.compilation.my_artifact,
156+
);
157+
```
158+
159+
## Incremental Passes
160+
161+
Incremental passes are bitflags that control which compilation phases are enabled:
162+
163+
```rust
164+
bitflags! {
165+
pub struct IncrementalPasses: u32 {
166+
const MAKE = 0b0000_0001;
167+
const MODULES_IDS = 0b0000_0010;
168+
const CHUNKS_IDS = 0b0000_0100;
169+
const MODULES_HASHES = 0b0000_1000;
170+
const MODULES_CODEGEN = 0b0001_0000;
171+
const MODULES_RUNTIME_REQUIREMENTS = 0b0010_0000;
172+
const CHUNKS_RUNTIME_REQUIREMENTS = 0b0100_0000;
173+
const CHUNKS_HASHES = 0b1000_0000;
174+
const CHUNKS_RENDER = 0b0001_0000_0000;
175+
// ... additional passes
176+
}
177+
}
178+
```
179+
180+
## Design Principles
181+
182+
1. **Separation of Concerns**: Each artifact is associated with related incremental pass
183+
2. **Automatic Recovery**: Wrapper types delegate recovery to inner types
184+
3. **Custom Recovery**: Cache artifacts can override `recover` for generation management
185+
4. **Type Safety**: The trait system ensures compile-time correctness
186+
5. **Performance**: `mem::swap` provides zero-copy artifact transfer
187+
188+
## File Locations
189+
190+
- Rebuild logic: `crates/rspack_core/src/compiler/rebuild.rs`
191+
- Individual artifacts: `crates/rspack_core/src/artifacts/*.rs`

crates/node_binding/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ Private node binding crate for rspack.
1212

1313
See [https://rspack.rs](https://rspack.rs) for details.
1414

15+
## Update Wasm binding
16+
17+
The generation of `rspack.wasi-browser.js` and `rspack.wasi.js` is disabled by default because `@napi/cli` produces unstable output for these files. To update the Wasm bindings, add `wasm32-wasip1-threads` to the `napi.targets` field in `package.json` before building the project.
18+
1519
## License
1620

1721
Rspack is [MIT licensed](https://github.com/web-infra-dev/rspack/blob/main/LICENSE).

crates/node_binding/napi-binding.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,8 +2489,13 @@ export interface RawModuleFederationManifestPluginOptions {
24892489
buildInfo?: RawStatsBuildInfo
24902490
}
24912491

2492+
export interface RawModuleFederationRuntimeExperimentsOptions {
2493+
asyncStartup?: boolean
2494+
}
2495+
24922496
export interface RawModuleFederationRuntimePluginOptions {
24932497
entryRuntime?: string | undefined
2498+
experiments?: RawModuleFederationRuntimeExperimentsOptions
24942499
}
24952500

24962501
export interface RawModuleFilenameTemplateFnCtx {

crates/node_binding/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@
5151
"aarch64-unknown-linux-gnu",
5252
"aarch64-apple-darwin",
5353
"aarch64-unknown-linux-musl",
54-
"aarch64-pc-windows-msvc",
55-
"wasm32-wasip1-threads"
54+
"aarch64-pc-windows-msvc"
5655
],
5756
"wasm": {
5857
"initialMemory": 16384,

crates/rspack_binding_api/src/plugins/interceptor.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,9 +1347,10 @@ impl CompilationAdditionalTreeRuntimeRequirements
13471347
{
13481348
async fn run(
13491349
&self,
1350-
compilation: &mut Compilation,
1350+
compilation: &Compilation,
13511351
chunk_ukey: &ChunkUkey,
13521352
runtime_requirements: &mut RuntimeGlobals,
1353+
_runtime_modules: &mut Vec<Box<dyn RuntimeModule>>,
13531354
) -> rspack_error::Result<()> {
13541355
let arg = JsAdditionalTreeRuntimeRequirementsArg {
13551356
chunk: ChunkWrapper::new(*chunk_ukey, compilation),

0 commit comments

Comments
 (0)