1- import { buildTranslationFiles } from '../keys-builder' ;
2- import { buildTranslationFile } from '../keys-builder/build-translation-file' ;
3- import { extractTemplateKeys } from '../keys-builder/template' ;
4- import { extractTSKeys } from '../keys-builder/typescript' ;
1+ import { relative , sep } from 'node:path' ;
2+ import { templateExtractor } from '../keys-builder/template' ;
3+ import { TSExtractor } from '../keys-builder/typescript' ;
54import { Config , ScopeMap , FileType } from '../types' ;
5+ import { writeFile } from '../utils/file.utils' ;
66import { initExtraction } from '../utils/init-extraction' ;
77import { mergeDeep } from '../utils/object.utils' ;
8- import { buildScopeFilePaths } from '../utils/path.utils' ;
98import { resolveConfig } from '../utils/resolve-config' ;
10- import { updateScopesMap } from '../utils/update-scopes-map' ;
119
1210import { generateKeys } from './generate-keys' ;
1311
14- let init = true ;
15-
1612export class TranslocoExtractKeysWebpackPlugin {
1713 config : Config ;
1814
@@ -21,82 +17,83 @@ export class TranslocoExtractKeysWebpackPlugin {
2117 }
2218
2319 apply ( compiler : any ) {
24- compiler . hooks . watchRun . tapPromise (
20+ compiler . hooks . thisCompilation . tap (
2521 'TranslocoExtractKeysPlugin' ,
26- async ( comp : any ) => {
27- if ( init ) {
28- init = false ;
29- return buildTranslationFiles ( this . config ) ;
30- }
31-
32- const keysExtractions : Record < FileType , string [ ] > = {
33- html : [ ] ,
34- ts : [ ] ,
35- } ;
36- const files =
37- comp . modifiedFiles ||
38- Object . keys ( comp . watchFileSystem . watcher . mtimes ) ;
39-
40- for ( const file of files ) {
41- const fileType = resolveFileType ( file ) ;
42-
43- if ( fileType ) {
44- keysExtractions [ fileType ] . push ( file ) ;
45- }
46- }
47-
48- if ( keysExtractions . html . length || keysExtractions . ts . length ) {
49- let htmlResult = initExtraction ( ) ;
50- let tsResult = initExtraction ( ) ;
51- if ( keysExtractions . ts . length ) {
52- // Maybe someone added a TRANSLOCO_SCOPE
53- const newScopes = updateScopesMap ( { files : keysExtractions . ts } ) ;
54-
55- const paths = buildScopeFilePaths ( {
56- aliasToScope : newScopes ,
57- langs : this . config . langs ,
58- output : this . config . output ,
59- fileFormat : this . config . fileFormat ,
60- } ) ;
61-
62- paths . forEach ( ( { path } ) =>
63- buildTranslationFile ( {
64- path,
65- fileFormat : this . config . fileFormat ,
66- } ) ,
22+ ( comp : any ) => {
23+ comp . hooks . processAssets . tap (
24+ {
25+ name : 'TranslocoExtractKeysPlugin' ,
26+ stage : compiler . webpack . Compilation . PROCESS_ASSETS_STAGE_ADDITIONAL ,
27+ } ,
28+ ( ) => {
29+ let htmlResult = initExtraction ( ) ;
30+ let tsResult = initExtraction ( ) ;
31+ const files = compiler . modifiedFiles || comp . fileDependencies ;
32+
33+ for ( const file of files ) {
34+ if (
35+ ! this . config . input . some ( ( input ) => file . startsWith ( input + sep ) )
36+ ) {
37+ continue ;
38+ }
39+
40+ const fileType = resolveFileType ( file ) ;
41+
42+ switch ( fileType ) {
43+ case 'html' : {
44+ htmlResult . scopeToKeys = templateExtractor ( {
45+ defaultValue : this . config . defaultValue ,
46+ file,
47+ scopes : this . config . scopes ,
48+ scopeToKeys : htmlResult . scopeToKeys ,
49+ } ) ;
50+ }
51+ case 'ts' : {
52+ tsResult . scopeToKeys = TSExtractor ( {
53+ defaultValue : this . config . defaultValue ,
54+ file,
55+ scopes : this . config . scopes ,
56+ scopeToKeys : tsResult . scopeToKeys ,
57+ } ) ;
58+ }
59+ }
60+ }
61+
62+ const scopeToKeys = mergeDeep (
63+ { } ,
64+ htmlResult . scopeToKeys ,
65+ tsResult . scopeToKeys ,
66+ ) as ScopeMap ;
67+ const hasTranslateKeys = Object . keys ( scopeToKeys ) . some (
68+ ( key ) => Object . keys ( scopeToKeys [ key ] ) . length > 0 ,
6769 ) ;
68- tsResult = extractTSKeys ( {
69- ...this . config ,
70- files : keysExtractions . ts ,
71- } ) ;
72- }
73-
74- if ( keysExtractions . html . length ) {
75- htmlResult = extractTemplateKeys ( {
76- ...this . config ,
77- files : keysExtractions . html ,
78- } ) ;
79- }
80-
81- const scopeToKeys = mergeDeep (
82- { } ,
83- htmlResult . scopeToKeys ,
84- tsResult . scopeToKeys ,
85- ) as ScopeMap ;
86- const hasTranslateKeys = Object . keys ( scopeToKeys ) . some (
87- ( key ) => Object . keys ( scopeToKeys [ key ] ) . length > 0 ,
88- ) ;
89-
90- if ( hasTranslateKeys ) {
91- generateKeys ( {
92- config : this . config ,
93- translationPath : this . config . translationsPath ,
94- scopeToKeys,
95- } ) ;
96- }
97- }
9870
99- return Promise . resolve ( ) ;
71+ if ( hasTranslateKeys ) {
72+ const files = generateKeys ( {
73+ config : this . config ,
74+ translationPath : this . config . translationsPath ,
75+ scopeToKeys,
76+ } ) ;
77+
78+ for ( const { filePath, content } of files ) {
79+ writeFile ( filePath , content , true ) ;
80+
81+ for ( const [ name , info ] of comp . assetsInfo ) {
82+ if (
83+ info . sourceFilename &&
84+ relative ( info . sourceFilename , filePath ) === ''
85+ ) {
86+ comp . updateAsset (
87+ name ,
88+ new compiler . webpack . sources . RawSource ( content ) ,
89+ ) ;
90+ break ;
91+ }
92+ }
93+ }
94+ }
95+ } ,
96+ ) ;
10097 } ,
10198 ) ;
10299 }
0 commit comments