1+ import path from 'node:path' ;
12import type { Compiler , RspackPluginInstance } from '@rspack/core' ;
23import { ConfigurationError } from './utils/ConfigurationError.js' ;
34
@@ -14,6 +15,10 @@ export class SourceMapPlugin implements RspackPluginInstance {
1415 return ;
1516 }
1617
18+ const host = compiler . options . devServer ! . host ;
19+ const port = compiler . options . devServer ! . port ;
20+ const namespace = `http://${ host } :${ port } ` ;
21+
1722 const format = compiler . options . devtool ;
1823 // disable builtin sourcemap generation
1924 compiler . options . devtool = false ;
@@ -24,8 +29,8 @@ export class SourceMapPlugin implements RspackPluginInstance {
2429 const devtoolNamespace =
2530 compiler . options . output . devtoolNamespace ??
2631 compiler . options . output . uniqueName ;
27- const devtoolModuleFilenameTemplate =
28- compiler . options . output . devtoolModuleFilenameTemplate ;
32+ // const devtoolModuleFilenameTemplate =
33+ // compiler.options.output.devtoolModuleFilenameTemplate;
2934 const devtoolFallbackModuleFilenameTemplate =
3035 compiler . options . output . devtoolFallbackModuleFilenameTemplate ;
3136
@@ -48,14 +53,41 @@ export class SourceMapPlugin implements RspackPluginInstance {
4853 const moduleMaps = format . includes ( 'module' ) ;
4954 const noSources = format . includes ( 'nosources' ) ;
5055
51- // TODO Fix sourcemap directory structure
52- // Right now its very messy and not every node module is inside of the node module
53- // like React Devtools backend etc or some symilinked module appear with relative path
54- // We should normalize this through a custom handler and provide an output similar to Metro
5556 new compiler . webpack . SourceMapDevToolPlugin ( {
5657 test : / \. ( [ c m ] ? j s x ? | b u n d l e ) $ / ,
5758 filename : '[file].map' ,
58- moduleFilenameTemplate : devtoolModuleFilenameTemplate ,
59+ moduleFilenameTemplate : ( info ) => {
60+ // inlined modules
61+ if ( ! info . identifier ) {
62+ return `${ namespace } ` ;
63+ }
64+
65+ const [ prefix , ...parts ] = info . resourcePath . split ( '/' ) ;
66+
67+ // prefixed modules like React DevTools Backend
68+ if ( prefix !== '.' && prefix !== '..' ) {
69+ const resourcePath = parts . filter ( ( part ) => part !== '..' ) . join ( '/' ) ;
70+ return `webpack://${ prefix } /${ resourcePath } ` ;
71+ }
72+
73+ const hasValidAbsolutePath = path . isAbsolute ( info . absoluteResourcePath ) ;
74+
75+ // project root
76+ if ( hasValidAbsolutePath && info . resourcePath . startsWith ( './' ) ) {
77+ return `[projectRoot]${ info . resourcePath . slice ( 1 ) } ` ;
78+ }
79+
80+ // outside of project root
81+ if ( hasValidAbsolutePath && info . resourcePath . startsWith ( '../' ) ) {
82+ const parts = info . resourcePath . split ( '/' ) ;
83+ const upLevel = parts . filter ( ( part ) => part === '..' ) . length ;
84+ const restPath = parts . slice ( parts . lastIndexOf ( '..' ) + 1 ) . join ( '/' ) ;
85+ const rootRef = `[projectRoot^${ upLevel } ]` ;
86+ return `${ rootRef } ${ restPath ? '/' + restPath : '' } ` ;
87+ }
88+
89+ return `[unknownOrigin]/${ path . basename ( info . identifier ) } ` ;
90+ } ,
5991 fallbackModuleFilenameTemplate : devtoolFallbackModuleFilenameTemplate ,
6092 append : hidden
6193 ? false
0 commit comments