feat: add beforeModuleIds hook#12809
Conversation
✅ Deploy Preview for rspack canceled.Built without sensitive environment variables
|
|
@hamlim have you checked the performance cost when using this hooks for your case, I'm not sure whether this will slow down build too much? |
ad55a72 to
721ccde
Compare
|
Sorry for the noise on the PR, just re-synced my fork and rebased on top of latest main to clean up some of the misc commits that had briefly ended up in this PR. |
721ccde to
40b7ea9
Compare
|
@hardfist I created a minimal test repo here to compare perf of an rspack app with and without using the new hook: https://github.com/hamlim/rspack-before-module-ids-perf-test It is a bit slower on my machine, see bench-results.json or the readme for more details |
|
📝 Benchmark detail: Open task failure |
6b65752 to
daa512b
Compare
daa512b to
217d89a
Compare
|
📝 Benchmark detail: Open task failure |
217d89a to
dc4de6e
Compare
|
📝 Benchmark detail: Open task failure |
dc4de6e to
c47745e
Compare
Merging this PR will improve performance by 23.87%
Performance Changes
Comparing Footnotes
|
c47745e to
f60d97f
Compare
|
The wasm test seems to report as a timeout, but it seems like the underlying tests actually complete pretty quickly? |
|
Let me check the CI problem. Sadly, it seems like a flaky failure 😅 |
|
📝 Benchmark detail: Open
|
f60d97f to
ce3d716
Compare
|
Any updates on this PR? Anything I can do to get it reviewed sooner? |
ce3d716 to
0bd501e
Compare
|
@hamlim Thanks for your contribution, we're gonna land it |
|
Thanks! |
|
From what I understand this only supports assigning custom string ids. Would it be possible to adjust it to support numbers too? |
Cherry-picked from 5ee65b4 with conflict resolution for v1.x
|
Update, I hadn't noticed that there was a separate v1.x branch - I've backported this PR and a followup PR to that branch here: #13223 |
* feat: add `beforeModuleIds` hook (#12809) Cherry-picked from 5ee65b4 with conflict resolution for v1.x * feat: support number type module ids in beforeModuleIds * fix: validate module id type in beforeModuleIds setter * test: add edge case for module.id = 0 in beforeModuleIds --------- Co-authored-by: Matt Hamlin <mhamlin@hubspot.com>
Summary
This PR implements the
beforeModuleIdshook for rspack, providing webpack API compatibility for plugins that need to assign custom module IDs before rspack's built-in module ID assignment strategy runs.This hook is called during the module IDs phase, after modules are collected but before any ID assignment occurs. Plugins can use it to assign custom IDs to specific modules (e.g., for stable chunk hashing, debugging, or custom naming schemes).
Note: This PR was created with assistance using Claude Code
Motivation
Webpack provides
compilation.hooks.beforeModuleIdswhich allows plugins to intercept the module ID assignment process. Some webpack plugins rely on this hook to:Without this hook, these plugins cannot be ported to rspack.
Related links
Closes: #10764
Implementation
Key Design Decisions
Proxy-based Module Exposure: To provide full webpack API compatibility, the JS implementation uses a Proxy pattern:
Moduleobjects fromcompilation.modulesby identifierlibIdent(),userRequest,type,rootModule, etc.)idsetter to track assignments in a Mapmodule.id = "custom-id"This approach ensures:
libIdent()for context-relative paths,userRequestfor the original import path,rootModulefor concatenated modules)Artifact Passing: The
moduleIdsplugins (deterministic, natural) need to see IDs assigned bybeforeModuleIds. This required adding a new helper functionget_used_module_ids_and_modules_with_artifactthat accepts the artifact as a parameter, since the artifact is temporarily moved out ofcompilationduring hook invocation.Test
Added
tests/rspack-test/configCases/hooks/before-module-ids/with:rspack.config.js- Plugin that assigns custom ID toindex.jsmoduleindex.js- Test entry pointa.js- Helper moduleThe test verifies:
module.id = "..."libIdent(),userRequest,type)Usage
API
Hook Signature
Module Object
Each module in the iterable is a proxied
Moduleobject with full access to:Core Properties:
identifier- The module's unique identifier (string)id- The module's ID (read/write, set this to assign a custom ID)type- The module type (e.g., "javascript/auto")context- The module's context directorylayer- The module's layer (if any)Methods:
libIdent(options: { context: string })- Returns a context-relative identifier suitable for stable IDsNormalModule Properties:
userRequest- The user's original request stringrawRequest- The raw request before resolutionresource- The resolved resource pathresourceResolveData- Full resolution dataloaders- Array of loaders applied to this modulematchResource- The match resource (if using!=!syntax)ConcatenatedModule Properties:
rootModule- The root module of the concatenated modulemodules- Array of all modules in the concatenationTesting
All existing tests pass (563 tests in Config.part2.test.js which includes hooks tests).
Checklist
define_hook!macro)CompilationHooksstructcargo fmtapplied