@@ -22,7 +22,13 @@ import * as path from 'path';
22
22
import { RawSourceMap , SourceMapConsumer , SourceMapGenerator } from 'source-map' ;
23
23
import { minify } from 'terser' ;
24
24
import * as v8 from 'v8' ;
25
- import { SourceMapSource } from 'webpack-sources' ;
25
+ import {
26
+ ConcatSource ,
27
+ OriginalSource ,
28
+ ReplaceSource ,
29
+ Source ,
30
+ SourceMapSource ,
31
+ } from 'webpack-sources' ;
26
32
import { allowMangle , allowMinify , shouldBeautify } from './environment-options' ;
27
33
import { I18nOptions } from './i18n-options' ;
28
34
@@ -48,7 +54,7 @@ export interface ProcessBundleOptions {
48
54
integrityAlgorithm ?: 'sha256' | 'sha384' | 'sha512' ;
49
55
runtimeData ?: ProcessBundleResult [ ] ;
50
56
replacements ?: [ string , string ] [ ] ;
51
- supportedBrowsers ?: string [ ] | Record < string , string > ;
57
+ supportedBrowsers ?: string [ ] | Record < string , string > ;
52
58
}
53
59
54
60
export interface ProcessBundleResult {
@@ -665,7 +671,7 @@ export async function inlineLocales(options: InlineOptions) {
665
671
fs . writeFileSync ( outputPath , transformResult . code ) ;
666
672
667
673
if ( inputMap && transformResult . map ) {
668
- const outputMap = mergeSourceMaps (
674
+ const outputMap = await mergeSourceMaps (
669
675
options . code ,
670
676
inputMap ,
671
677
transformResult . code ,
@@ -686,7 +692,6 @@ async function inlineLocalesDirect(ast: ParseResult, options: InlineOptions) {
686
692
return { file : options . filename , diagnostics : [ ] , count : 0 } ;
687
693
}
688
694
689
- const { default : MagicString } = await import ( 'magic-string' ) ;
690
695
const { default : generate } = await import ( '@babel/generator' ) ;
691
696
const utils = await import (
692
697
// tslint:disable-next-line: trailing-comma no-implicit-dependencies
@@ -702,11 +707,21 @@ async function inlineLocalesDirect(ast: ParseResult, options: InlineOptions) {
702
707
return inlineCopyOnly ( options ) ;
703
708
}
704
709
705
- // tslint:disable-next-line: no-any
706
- let content = new MagicString ( options . code , { filename : options . filename } as any ) ;
707
710
const inputMap = options . map && ( JSON . parse ( options . map ) as RawSourceMap ) ;
708
- let contentClone ;
711
+ // Cleanup source root otherwise it will be added to each source entry
712
+ const mapSourceRoot = inputMap && inputMap . sourceRoot ;
713
+ if ( inputMap ) {
714
+ delete inputMap . sourceRoot ;
715
+ }
716
+
709
717
for ( const locale of i18n . inlineLocales ) {
718
+ const content = new ReplaceSource (
719
+ inputMap
720
+ ? // tslint:disable-next-line: no-any
721
+ new SourceMapSource ( options . code , options . filename , inputMap as any )
722
+ : new OriginalSource ( options . code , options . filename ) ,
723
+ ) ;
724
+
710
725
const isSourceLocale = locale === i18n . sourceLocale ;
711
726
// tslint:disable-next-line: no-any
712
727
const translations : any = isSourceLocale ? { } : i18n . locales [ locale ] . translation || { } ;
@@ -722,49 +737,42 @@ async function inlineLocalesDirect(ast: ParseResult, options: InlineOptions) {
722
737
const expression = utils . buildLocalizeReplacement ( translated [ 0 ] , translated [ 1 ] ) ;
723
738
const { code } = generate ( expression ) ;
724
739
725
- content . overwrite ( position . start , position . end , code ) ;
740
+ content . replace ( position . start , position . end - 1 , code ) ;
726
741
}
727
742
743
+ let outputSource : Source = content ;
728
744
if ( options . setLocale ) {
729
- const setLocaleText = `var $localize=Object.assign(void 0===$localize?{}:$localize,{locale:"${ locale } "});` ;
730
- contentClone = content . clone ( ) ;
731
- content . prepend ( setLocaleText ) ;
745
+ const setLocaleText = `var $localize=Object.assign(void 0===$localize?{}:$localize,{locale:"${ locale } "});\n` ;
732
746
733
747
// If locale data is provided, load it and prepend to file
748
+ let localeDataSource : Source | null = null ;
734
749
const localeDataPath = i18n . locales [ locale ] && i18n . locales [ locale ] . dataPath ;
735
750
if ( localeDataPath ) {
736
- const localDataContent = await loadLocaleData ( localeDataPath , true ) ;
737
- // The semicolon ensures that there is no syntax error between statements
738
- content . prepend ( localDataContent + ';' ) ;
751
+ const localeDataContent = await loadLocaleData ( localeDataPath , true ) ;
752
+ localeDataSource = new OriginalSource ( localeDataContent , path . basename ( localeDataPath ) ) ;
739
753
}
754
+
755
+ outputSource = localeDataSource
756
+ // The semicolon ensures that there is no syntax error between statements
757
+ ? new ConcatSource ( setLocaleText , localeDataSource , ';\n' , content )
758
+ : new ConcatSource ( setLocaleText , content ) ;
740
759
}
741
760
742
- const output = content . toString ( ) ;
761
+ const { source : outputCode , map : outputMap } = outputSource . sourceAndMap ( ) ;
743
762
const outputPath = path . join (
744
763
options . outputPath ,
745
764
i18n . flatOutput ? '' : locale ,
746
765
options . filename ,
747
766
) ;
748
- fs . writeFileSync ( outputPath , output ) ;
749
-
750
- if ( inputMap ) {
751
- const contentMap = content . generateMap ( ) ;
752
- const outputMap = mergeSourceMaps (
753
- options . code ,
754
- inputMap ,
755
- output ,
756
- contentMap ,
757
- options . filename ,
758
- options . code . length > FAST_SOURCEMAP_THRESHOLD ,
759
- ) ;
767
+ fs . writeFileSync ( outputPath , outputCode ) ;
760
768
769
+ if ( inputMap && outputMap ) {
770
+ outputMap . file = options . filename ;
771
+ if ( mapSourceRoot ) {
772
+ outputMap . sourceRoot = mapSourceRoot ;
773
+ }
761
774
fs . writeFileSync ( outputPath + '.map' , JSON . stringify ( outputMap ) ) ;
762
775
}
763
-
764
- if ( contentClone ) {
765
- content = contentClone ;
766
- contentClone = undefined ;
767
- }
768
776
}
769
777
770
778
return { file : options . filename , diagnostics : diagnostics . messages , count : positions . length } ;
0 commit comments