11import { extname } from 'path' ;
22
33const requiredCode = `import * as React from 'react';` ;
4- const mockBaseUrl = new URL ( 'mocks/' , import . meta. url ) ;
4+ const css = new URL ( 'mocks/css.mjs ' , import . meta. url ) . href ;
55
66/**
7+ *
8+ * This hook intercepts module resolution, allowing us to handle
9+ * CSS/SCSS files in a custom way. Instead of actually loading the CSS,
10+ * we short-circuit the resolution and return a mock module.
11+ *
712 * @type {import('node:module').ResolveHook }
813 */
914export async function resolve ( specifier , ctx , nextResolve ) {
10- if ( specifier . endsWith ( '.css' ) ) {
15+ const ext = extname ( specifier ) ;
16+ if ( ext === '.css' || ext === '.scss' ) {
17+ // For CSS/SCSS, return the mock CSS module and skip default resolution.
1118 return {
1219 format : 'module' ,
13- url : new URL ( ' css.mjs' , mockBaseUrl ) . href ,
20+ url : css ,
1421 shortCircuit : true ,
1522 } ;
1623 }
@@ -19,12 +26,21 @@ export async function resolve(specifier, ctx, nextResolve) {
1926}
2027
2128/**
29+ *
30+ * This hook is used to modify the source of JSX/TSX files on the fly.
31+ * We prepend the necessary React import to ensure React is available,
32+ * which is required for JSX to work without explicitly importing React.
33+ *
2234 * @type {import('node:module').LoadHook }
2335 */
2436export async function load ( url , ctx , nextLoad ) {
2537 const ext = extname ( url ) ;
26- if ( ext [ ext . length - 1 ] !== 'x' ) return nextLoad ( url ) ;
2738 const result = await nextLoad ( url , ctx ) ;
28- result . source = requiredCode + result . source ;
39+
40+ if ( ext === '.jsx' || ext === '.tsx' ) {
41+ // Ensure React is in scope for JSX transforms.
42+ result . source = requiredCode + result . source ;
43+ }
44+
2945 return result ;
3046}
0 commit comments