@@ -17,7 +17,7 @@ import {
1717import { createHash } from 'crypto' ;
1818import * as fs from 'fs' ;
1919import * as path from 'path' ;
20- import { RawSourceMap , SourceMapConsumer , SourceMapGenerator } from 'source-map' ;
20+ import { RawSourceMap } from 'source-map' ;
2121import { minify } from 'terser' ;
2222import * as v8 from 'v8' ;
2323import { SourceMapSource } from 'webpack-sources' ;
@@ -108,23 +108,19 @@ export async function process(options: ProcessBundleOptions): Promise<ProcessBun
108108 const filename = path . basename ( options . filename ) ;
109109 const downlevelFilename = filename . replace ( / \- e s 2 0 \d { 2 } / , '-es5' ) ;
110110 const downlevel = ! options . optimizeOnly ;
111-
112- // if code size is larger than 500kB, manually handle sourcemaps with newer source-map package.
113- // babel currently uses an older version that still supports sync calls
114- const codeSize = Buffer . byteLength ( options . code ) ;
115- const mapSize = options . map ? Buffer . byteLength ( options . map ) : 0 ;
116- const manualSourceMaps = codeSize >= 500 * 1024 || mapSize >= 500 * 1024 ;
117111 const sourceCode = options . code ;
118- const sourceMap = options . map ? JSON . parse ( options . map ) : false ;
112+ const sourceMap = options . map ? JSON . parse ( options . map ) : undefined ;
119113
120114 let downlevelCode ;
121115 let downlevelMap ;
122116 if ( downlevel ) {
123117 // Downlevel the bundle
124118 const transformResult = await transformAsync ( sourceCode , {
125- filename : options . filename ,
119+ filename,
126120 // using false ensures that babel will NOT search and process sourcemap comments (large memory usage)
127- inputSourceMap : manualSourceMaps ? false : sourceMap ,
121+ // The types do not include the false option even though it is valid
122+ // tslint:disable-next-line: no-any
123+ inputSourceMap : false as any ,
128124 babelrc : false ,
129125 presets : [ [
130126 require . resolve ( '@babel/preset-env' ) ,
@@ -147,11 +143,14 @@ export async function process(options: ProcessBundleOptions): Promise<ProcessBun
147143 }
148144 downlevelCode = transformResult . code ;
149145
150- if ( manualSourceMaps && sourceMap && transformResult . map ) {
151- downlevelMap = await mergeSourceMapsFast ( sourceMap , transformResult . map ) ;
152- } else {
153- // undefined is needed here to normalize the property type
154- downlevelMap = transformResult . map || undefined ;
146+ if ( sourceMap && transformResult . map ) {
147+ downlevelMap = mergeSourceMaps (
148+ sourceCode ,
149+ sourceMap ,
150+ downlevelCode ,
151+ transformResult . map ,
152+ filename ,
153+ ) ;
155154 }
156155 }
157156
@@ -175,15 +174,14 @@ export async function process(options: ProcessBundleOptions): Promise<ProcessBun
175174 return result ;
176175}
177176
177+ // SourceMapSource produces high-quality sourcemaps
178178function mergeSourceMaps (
179179 inputCode : string ,
180180 inputSourceMap : RawSourceMap ,
181181 resultCode : string ,
182182 resultSourceMap : RawSourceMap ,
183183 filename : string ,
184184) : RawSourceMap {
185- // More accurate but significantly more costly
186-
187185 // The last argument is not yet in the typings
188186 // tslint:disable-next-line: no-any
189187 return new ( SourceMapSource as any ) (
@@ -196,58 +194,6 @@ function mergeSourceMaps(
196194 ) . map ( ) ;
197195}
198196
199- async function mergeSourceMapsFast ( first : RawSourceMap , second : RawSourceMap ) {
200- const sourceRoot = first . sourceRoot ;
201- const generator = new SourceMapGenerator ( ) ;
202-
203- // sourcemap package adds the sourceRoot to all position source paths if not removed
204- delete first . sourceRoot ;
205-
206- await SourceMapConsumer . with ( first , null , originalConsumer => {
207- return SourceMapConsumer . with ( second , null , newConsumer => {
208- newConsumer . eachMapping ( mapping => {
209- if ( mapping . originalLine === null ) {
210- return ;
211- }
212- const originalPosition = originalConsumer . originalPositionFor ( {
213- line : mapping . originalLine ,
214- column : mapping . originalColumn ,
215- } ) ;
216- if (
217- originalPosition . line === null ||
218- originalPosition . column === null ||
219- originalPosition . source === null
220- ) {
221- return ;
222- }
223- generator . addMapping ( {
224- generated : {
225- line : mapping . generatedLine ,
226- column : mapping . generatedColumn ,
227- } ,
228- name : originalPosition . name || undefined ,
229- original : {
230- line : originalPosition . line ,
231- column : originalPosition . column ,
232- } ,
233- source : originalPosition . source ,
234- } ) ;
235- } ) ;
236- } ) ;
237- } ) ;
238-
239- const map = generator . toJSON ( ) ;
240- map . file = second . file ;
241- map . sourceRoot = sourceRoot ;
242-
243- // Put the sourceRoot back
244- if ( sourceRoot ) {
245- first . sourceRoot = sourceRoot ;
246- }
247-
248- return map ;
249- }
250-
251197async function processBundle (
252198 options : Omit < ProcessBundleOptions , 'map' > & { isOriginal : boolean ; map ?: string | RawSourceMap } ,
253199) : Promise < ProcessBundleFile > {
@@ -270,6 +216,10 @@ async function processBundle(
270216 map : RawSourceMap | undefined ,
271217 } ;
272218
219+ if ( rawMap ) {
220+ rawMap . file = filename ;
221+ }
222+
273223 if ( optimize ) {
274224 result = terserMangle ( code , {
275225 filename,
@@ -278,10 +228,6 @@ async function processBundle(
278228 ecma : isOriginal ? 6 : 5 ,
279229 } ) ;
280230 } else {
281- if ( rawMap ) {
282- rawMap . file = filename ;
283- }
284-
285231 result = {
286232 map : rawMap ,
287233 code,
@@ -328,7 +274,7 @@ function terserMangle(
328274 // estree -> terser is already supported; need babel -> estree/terser
329275
330276 // Mangle downlevel code
331- const minifyOutput = minify ( code , {
277+ const minifyOutput = minify ( options . filename ? { [ options . filename ] : code } : code , {
332278 compress : options . compress || false ,
333279 ecma : options . ecma || 5 ,
334280 mangle : ! manglingDisabled ,
@@ -340,10 +286,6 @@ function terserMangle(
340286 sourceMap :
341287 ! ! options . map &&
342288 ( {
343- filename : options . filename ,
344- // terser uses an old version of the sourcemap typings
345- // tslint:disable-next-line: no-any
346- content : options . map as any ,
347289 asObject : true ,
348290 // typings don't include asObject option
349291 // tslint:disable-next-line: no-any
@@ -355,7 +297,20 @@ function terserMangle(
355297 }
356298
357299 // tslint:disable-next-line: no-non-null-assertion
358- return { code : minifyOutput . code ! , map : minifyOutput . map as RawSourceMap | undefined } ;
300+ const outputCode = minifyOutput . code ! ;
301+
302+ let outputMap ;
303+ if ( options . map && minifyOutput . map ) {
304+ outputMap = mergeSourceMaps (
305+ code ,
306+ options . map ,
307+ outputCode ,
308+ minifyOutput . map as unknown as RawSourceMap ,
309+ options . filename || '0' ,
310+ ) ;
311+ }
312+
313+ return { code : outputCode , map : outputMap } ;
359314}
360315
361316function createFileEntry (
@@ -493,7 +448,8 @@ export async function inlineLocales(options: InlineOptions) {
493448 return inlineCopyOnly ( options ) ;
494449 }
495450
496- let content = new MagicString ( options . code ) ;
451+ // tslint:disable-next-line: no-any
452+ let content = new MagicString ( options . code , { filename : options . filename } as any ) ;
497453 const inputMap = options . map && ( JSON . parse ( options . map ) as RawSourceMap ) ;
498454 let contentClone ;
499455 for ( const locale of i18n . inlineLocales ) {
0 commit comments