File tree Expand file tree Collapse file tree 6 files changed +175
-0
lines changed
tests/rspack-test/hookCases
compilation#unsupportedHookError/basic
compiler#unsupportedHookError/basic Expand file tree Collapse file tree 6 files changed +175
-0
lines changed Original file line number Diff line number Diff line change @@ -389,6 +389,26 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
389389 afterSeal : new liteTapable . AsyncSeriesHook ( [ ] ) ,
390390 needAdditionalPass : new liteTapable . SyncBailHook ( [ ] ) ,
391391 } ;
392+
393+ // Wrap hooks with a Proxy to provide helpful error messages when
394+ // webpack plugins try to access hooks that don't exist in rspack
395+ const availableHooks = Object . keys ( this . hooks ) ;
396+ this . hooks = new Proxy ( this . hooks , {
397+ get ( target , prop , receiver ) {
398+ const value = Reflect . get ( target , prop , receiver ) ;
399+ if ( value === undefined && typeof prop === 'string' ) {
400+ const hooksList = availableHooks . join ( ', ' ) ;
401+ throw new Error (
402+ `Compilation.hooks.${ prop } is not supported in rspack. ` +
403+ `This typically happens when using webpack plugins that rely on webpack-specific hooks. ` +
404+ `Consider using an rspack-compatible alternative or removing the incompatible plugin.\n\n` +
405+ `Available compilation hooks: ${ hooksList } ` ,
406+ ) ;
407+ }
408+ return value ;
409+ } ,
410+ } ) ;
411+
392412 this . compiler = compiler ;
393413 this . resolverFactory = compiler . resolverFactory ;
394414 this . inputFileSystem = compiler . inputFileSystem ;
Original file line number Diff line number Diff line change @@ -260,6 +260,25 @@ class Compiler {
260260 additionalPass : new liteTapable . AsyncSeriesHook ( [ ] ) ,
261261 } ;
262262
263+ // Wrap hooks with a Proxy to provide helpful error messages when
264+ // webpack plugins try to access hooks that don't exist in rspack
265+ const availableCompilerHooks = Object . keys ( this . hooks ) ;
266+ this . hooks = new Proxy ( this . hooks , {
267+ get ( target , prop , receiver ) {
268+ const value = Reflect . get ( target , prop , receiver ) ;
269+ if ( value === undefined && typeof prop === 'string' ) {
270+ const hooksList = availableCompilerHooks . join ( ', ' ) ;
271+ throw new Error (
272+ `Compiler.hooks.${ prop } is not supported in rspack. ` +
273+ `This typically happens when using webpack plugins that rely on webpack-specific hooks. ` +
274+ `Consider using an rspack-compatible alternative or removing the incompatible plugin.\n\n` +
275+ `Available compiler hooks: ${ hooksList } ` ,
276+ ) ;
277+ }
278+ return value ;
279+ } ,
280+ } ) ;
281+
263282 const compilerRuntimeGlobals = createCompilerRuntimeGlobals ( options ) ;
264283 const compilerFn = function ( ...params : Parameters < typeof rspackFn > ) {
265284 return rspackFn ( ...params ) ;
Original file line number Diff line number Diff line change 1+ ```js title=main.js
2+ (() => {
3+ var __webpack_modules__ = ({
4+ 402(module) {
5+ module.exports = "This is hook"
6+
7+
8+ },
9+
10+ });
11+ // The module cache
12+ var __webpack_module_cache__ = {};
13+
14+ // The require function
15+ function __webpack_require__(moduleId) {
16+
17+ // Check if module is in cache
18+ var cachedModule = __webpack_module_cache__[moduleId];
19+ if (cachedModule !== undefined) {
20+ return cachedModule.exports;
21+ }
22+ // Create a new module (and put it into the cache)
23+ var module = (__webpack_module_cache__[moduleId] = {
24+ exports: {}
25+ });
26+ // Execute the module function
27+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
28+
29+ // Return the exports of the module
30+ return module.exports;
31+
32+ }
33+
34+ // startup
35+ // Load entry module and return exports
36+ // This entry module is referenced by other modules so it can't be inlined
37+ var __webpack_exports__ = __webpack_require__(402);
38+ })()
39+ ;
40+ ```
Original file line number Diff line number Diff line change 1+ /** @type {import("@rspack/test-tools").THookCaseConfig } */
2+ module . exports = {
3+ description : "should throw helpful error for unsupported compilation hooks" ,
4+ options ( ) {
5+ return {
6+ plugins : [
7+ {
8+ apply ( compiler ) {
9+ compiler . hooks . compilation . tap ( "test" , compilation => {
10+ // Test accessing an unsupported hook that exists in webpack but not rspack
11+ expect ( ( ) => {
12+ compilation . hooks . nonExistentWebpackHook . tap ( "test" , ( ) => { } ) ;
13+ } ) . toThrow ( / C o m p i l a t i o n \. h o o k s \. n o n E x i s t e n t W e b p a c k H o o k i s n o t s u p p o r t e d i n r s p a c k / ) ;
14+
15+ // Verify the error message includes the available hooks list
16+ try {
17+ compilation . hooks . nonExistentWebpackHook ;
18+ } catch ( e ) {
19+ expect ( e . message ) . toContain ( "Available compilation hooks:" ) ;
20+ expect ( e . message ) . toContain ( "processAssets" ) ;
21+ expect ( e . message ) . toContain ( "seal" ) ;
22+ }
23+ } ) ;
24+ }
25+ }
26+ ]
27+ } ;
28+ }
29+ } ;
Original file line number Diff line number Diff line change 1+ ```js title=main.js
2+ (() => {
3+ var __webpack_modules__ = ({
4+ 402(module) {
5+ module.exports = "This is hook"
6+
7+
8+ },
9+
10+ });
11+ // The module cache
12+ var __webpack_module_cache__ = {};
13+
14+ // The require function
15+ function __webpack_require__(moduleId) {
16+
17+ // Check if module is in cache
18+ var cachedModule = __webpack_module_cache__[moduleId];
19+ if (cachedModule !== undefined) {
20+ return cachedModule.exports;
21+ }
22+ // Create a new module (and put it into the cache)
23+ var module = (__webpack_module_cache__[moduleId] = {
24+ exports: {}
25+ });
26+ // Execute the module function
27+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
28+
29+ // Return the exports of the module
30+ return module.exports;
31+
32+ }
33+
34+ // startup
35+ // Load entry module and return exports
36+ // This entry module is referenced by other modules so it can't be inlined
37+ var __webpack_exports__ = __webpack_require__(402);
38+ })()
39+ ;
40+ ```
Original file line number Diff line number Diff line change 1+ /** @type {import("@rspack/test-tools").THookCaseConfig } */
2+ module . exports = {
3+ description : "should throw helpful error for unsupported compiler hooks" ,
4+ options ( ) {
5+ return {
6+ plugins : [
7+ {
8+ apply ( compiler ) {
9+ // Test accessing an unsupported hook that exists in webpack but not rspack
10+ expect ( ( ) => {
11+ compiler . hooks . nonExistentWebpackHook . tap ( "test" , ( ) => { } ) ;
12+ } ) . toThrow ( / C o m p i l e r \. h o o k s \. n o n E x i s t e n t W e b p a c k H o o k i s n o t s u p p o r t e d i n r s p a c k / ) ;
13+
14+ // Verify the error message includes the available hooks list
15+ try {
16+ compiler . hooks . nonExistentWebpackHook ;
17+ } catch ( e ) {
18+ expect ( e . message ) . toContain ( "Available compiler hooks:" ) ;
19+ expect ( e . message ) . toContain ( "compilation" ) ;
20+ expect ( e . message ) . toContain ( "emit" ) ;
21+ }
22+ }
23+ }
24+ ]
25+ } ;
26+ }
27+ } ;
You can’t perform that action at this time.
0 commit comments