88 getThreadPoolSize ,
99 getValidBundleList ,
1010 Log ,
11+ composeSourcemaps ,
1112 isEnabledFeature ,
1213 isEnableThreadPool ,
1314 isEnableAutoExcludesNodeModules ,
@@ -19,6 +20,8 @@ import {
1920import { BundleList , Config } from "../type" ;
2021import { isArray , isFunction , isFileNameExcluded } from '../utils/is' ;
2122import { Worker } from 'node:worker_threads' ;
23+ import { encode } from '@jridgewell/sourcemap-codec' ;
24+ import { TraceMap , originalPositionFor , sourceContentFor } from '@jridgewell/trace-mapping' ;
2225
2326// Mock WORKER_FILE_PATH
2427vi . stubGlobal ( 'WORKER_FILE_PATH' , './worker.js' ) ;
@@ -237,6 +240,58 @@ describe('getChunkName', () => {
237240 } ) ;
238241} ) ;
239242
243+ describe ( 'composeSourcemaps' , ( ) => {
244+ it ( 'should compose maps and preserve the original source content' , ( ) => {
245+ const originalSource = 'const message = "hi";\nconsole.log(message);\n' ;
246+ const intermediateSource = 'const message="hi";\nconsole.log(message);\n' ;
247+
248+ const bundlerMap : Rollup . SourceMapInput = {
249+ version : 3 ,
250+ file : 'bundle.js' ,
251+ sources : [ 'original.ts' ] ,
252+ sourcesContent : [ originalSource ] ,
253+ names : [ ] ,
254+ mappings : encode ( [
255+ [ [ 0 , 0 , 0 , 0 ] ] ,
256+ [ [ 0 , 0 , 1 , 0 ] ] ,
257+ ] ) ,
258+ } ;
259+
260+ const obfuscatorMap : Rollup . SourceMapInput = {
261+ version : 3 ,
262+ file : 'bundle-obf.js' ,
263+ sources : [ 'bundle.js' ] ,
264+ sourcesContent : [ intermediateSource ] ,
265+ names : [ ] ,
266+ mappings : encode ( [
267+ [ [ 0 , 0 , 0 , 0 ] ] ,
268+ [ [ 0 , 0 , 1 , 0 ] ] ,
269+ ] ) ,
270+ } ;
271+
272+ const logSpy = vi . fn ( ) ;
273+
274+ const composed = composeSourcemaps ( bundlerMap , obfuscatorMap , logSpy ) ;
275+
276+ expect ( logSpy ) . toHaveBeenCalledWith ( 'composing source maps...' ) ;
277+ expect ( composed ) . not . toBeNull ( ) ;
278+
279+ const trace = new TraceMap ( composed as any ) ;
280+
281+ const firstLine = originalPositionFor ( trace , { line : 1 , column : 0 } ) ;
282+ expect ( firstLine . source ) . toBe ( 'original.ts' ) ;
283+ expect ( firstLine . line ) . toBe ( 1 ) ;
284+ expect ( firstLine . column ) . toBe ( 0 ) ;
285+
286+ const secondLine = originalPositionFor ( trace , { line : 2 , column : 0 } ) ;
287+ expect ( secondLine . source ) . toBe ( 'original.ts' ) ;
288+ expect ( secondLine . line ) . toBe ( 2 ) ;
289+
290+ const recoveredSource = sourceContentFor ( trace , firstLine . source as string ) ;
291+ expect ( recoveredSource ) . toBe ( originalSource ) ;
292+ } ) ;
293+ } ) ;
294+
240295describe ( 'CodeSizeAnalyzer' , ( ) => {
241296 let analyzer : CodeSizeAnalyzer ;
242297 const mockLog = new Log ( true ) ;
0 commit comments