1
1
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
2
// See LICENSE in the project root for license information.
3
3
<
EF56
/td>
4
- import { JsonFile } from '@rushstack/node-core-library' ;
4
+ import {
5
+ JsonFile ,
6
+ FileSystem ,
7
+ ITerminalProvider ,
8
+ TerminalProviderSeverity ,
9
+ Terminal
10
+ } from '@rushstack/node-core-library' ;
5
11
import * as Webpack from 'webpack' ;
6
12
import * as path from 'path' ;
7
13
import * as Tapable from 'tapable' ;
@@ -27,6 +33,7 @@ import { LocFileTypingsGenerator } from './LocFileTypingsGenerator';
27
33
import { Pseudolocalization } from './Pseudolocalization' ;
28
34
import { EntityMarker } from './utilities/EntityMarker' ;
29
35
import { IAsset , IProcessAssetResult , AssetProcessor } from './AssetProcessor' ;
36
+ import { LocFileParser } from './utilities/LocFileParser' ;
30
37
31
38
/**
32
39
* @internal
@@ -135,7 +142,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
135
142
// https://github.com/webpack/webpack-dev-server/pull/1929/files#diff-15fb51940da53816af13330d8ce69b4eR66
136
143
const isWebpackDevServer : boolean = process . env . WEBPACK_DEV_SERVER === 'true' ;
137
144
138
- const errors : Error [ ] = this . _initializeAndValidateOptions ( compiler . options , isWebpackDevServer ) ;
145
+ const { errors, warnings } = this . _initializeAndValidateOptions ( compiler . options , isWebpackDevServer ) ;
139
146
140
147
let typingsPreprocessor : LocFileTypingsGenerator | undefined ;
141
148
if ( this . _options . typingsOptions ) {
@@ -156,14 +163,18 @@ export class LocalizationPlugin implements Webpack.Plugin {
156
163
localeNameOrPlaceholder : Constants . LOCALE_NAME_PLACEHOLDER
157
164
} ;
158
165
159
- if ( errors . length > 0 ) {
166
+ if ( errors . length > 0 || warnings . length > 0 ) {
160
167
compiler . hooks . compilation . tap ( PLUGIN_NAME , ( compilation : Webpack . compilation . Compilation ) => {
161
168
compilation . errors . push ( ...errors ) ;
169
+ compilation . warnings . push ( ...warnings ) ;
162
170
} ) ;
163
171
164
- WebpackConfigurationUpdater . amendWebpackConfigurationForInPlaceLocFiles ( webpackConfigurationUpdaterOptions ) ;
165
-
166
- return ;
172
+ if ( errors . length > 0 ) {
173
+ // If there are any errors, just pass through the resources in source and don't do any
174
+ // additional configuration
175
+ WebpackConfigurationUpdater . amendWebpackConfigurationForInPlaceLocFiles ( webpackConfigurationUpdaterOptions ) ;
176
+ return ;
177
+ }
167
178
}
168
179
169
180
if ( isWebpackDevServer ) {
@@ -390,11 +401,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
390
401
* @internal
391
402
*/
392
403
public addDefaultLocFile ( locFilePath : string , locFile : ILocalizationFile ) : void {
393
- const locFileData : ILocaleFileData = { } ;
394
- for ( const stringName in locFile ) { // eslint-disable-line guard-for-in
395
- locFileData [ stringName ] = locFile [ stringName ] . value ;
396
- }
397
-
404
+ const locFileData : ILocaleFileData = this . _convertLocalizationFileToLocData ( locFile ) ;
398
405
this . _addLocFile ( this . _defaultLocale , locFilePath , locFileData ) ;
399
406
400
407
this . _pseudolocalizers . forEach ( ( pseudolocalizer : ( str : string ) => string , pseudolocaleName : string ) => {
@@ -454,8 +461,12 @@ export class LocalizationPlugin implements Webpack.Plugin {
454
461
}
455
462
}
456
463
457
- private _initializeAndValidateOptions ( configuration : Webpack . Configuration , isWebpackDevServer : boolean ) : Error [ ] {
464
+ private _initializeAndValidateOptions (
465
+ configuration : Webpack . Configuration ,
466
+ isWebpackDevServer : boolean
467
+ ) : { errors : Error [ ] , warnings : Error [ ] } {
458
468
const errors : Error [ ] = [ ] ;
469
+ const warnings : Error [ ] = [ ] ;
459
470
460
471
function ensureValidLocaleName ( localeName : string ) : boolean {
461
472
const LOCALE_NAME_REGEX : RegExp = / [ a - z - ] / i;
@@ -510,18 +521,37 @@ export class LocalizationPlugin implements Webpack.Plugin {
510
521
// START options.localizedData.translatedStrings
511
522
const { translatedStrings } = this . _options . localizedData ;
512
523
if ( translatedStrings ) {
524
+ const terminalProvider : ITerminalProvider = {
525
+ supportsColor : false ,
526
+ eolCharacter : '\n' ,
527
+ write : ( data : string , severity : TerminalProviderSeverity ) => {
528
+ switch ( severity ) {
529
+ case TerminalProviderSeverity . error : {
530
+ errors . push ( new Error ( data ) ) ;
531
+ break ;
532
+ }
533
+
534
+ case TerminalProviderSeverity . warning : {
535
+ warnings . push ( new Error ( data ) ) ;
536
+ break ;
537
+ }
538
+ }
539
+ }
540
+ } ;
541
+ const terminal : Terminal = new Terminal ( terminalProvider ) ;
542
+
513
543
for ( const localeName in translatedStrings ) {
514
544
if ( translatedStrings . hasOwnProperty ( localeName ) ) {
515
545
if ( this . _locales . has ( localeName ) ) {
516
546
errors . push ( Error (
517
547
`The locale "${ localeName } " appears multiple times. ` +
518
548
'There may be multiple instances with different casing.'
519
549
) ) ;
520
- return errors ;
550
+ return { errors, warnings } ;
521
551
}
522
552
523
553
if ( ! ensureValidLocaleName ( localeName ) ) {
524
- return errors ;
554
+ return { errors, warnings } ;
525
555
}
526
556
527
557
this . _locales . add ( localeName ) ;
@@ -540,12 +570,25 @@ export class LocalizationPlugin implements Webpack.Plugin {
540
570
`The localization file path "${ locFilePath } " appears multiple times in locale ${ localeName } . ` +
541
571
'There may be multiple instances with different casing.'
542
572
) ) ;
543
- return errors ;
573
+ return { errors, warnings } ;
544
574
}
545
575
546
576
locFilePathsInLocale . add ( normalizedLocFilePath ) ;
547
577
548
- const locFileData : ILocaleFileData = locale [ locFilePath ] ;
578
+ let locFileData : ILocaleFileData ;
579
+ const locFileDataFromOptions : ILocaleFileData | string = locale [ locFilePath ] ;
580
+ if ( typeof locFileDataFromOptions === 'string' ) {
581
+ const normalizedTranslatedFilePath : string = path . resolve ( configuration . context ! , locFileDataFromOptions ) ;
582
+ const localizationFile : ILocalizationFile = LocFileParser . parseLocFile ( {
583
+ filePath : normalizedTranslatedFilePath ,
584
+ content : FileSystem . readFile ( normalizedTranslatedFilePath ) ,
585
+ terminal : terminal
586
+ } ) ;
587
+
588
+ locFileData = this . _convertLocalizationFileToLocData ( localizationFile ) ;
589
+ } else {
590
+ locFileData = locFileDataFromOptions ;
591
+ }
549
592
this . _addLocFile ( localeName , normalizedLocFilePath , locFileData ) ;
550
593
}
551
594
}
@@ -560,9 +603,9 @@ export class LocalizationPlugin implements Webpack.Plugin {
560
603
if ( this . _options . localizedData . defaultLocale . localeName ) {
561
604
if ( this . _locales . has ( localeName ) ) {
562
605
errors . push ( new Error ( 'The default locale is also specified in the translated strings.' ) ) ;
563
- return errors ;
606
+ return { errors, warnings } ;
564
607
} else if ( ! ensureValidLocaleName ( localeName ) ) {
565
- return errors ;
608
+ return { errors, warnings } ;
566
609
}
567
610
568
611
this . _locales . add ( localeName ) ;
@@ -571,11 +614,11 @@ export class LocalizationPlugin implements Webpack.Plugin {
571
614
this . _fillMissingTranslationStrings = ! ! fillMissingTranslationStrings ;
572
615
} else {
573
616
errors . push ( new Error ( 'Missing default locale name' ) ) ;
574
- return errors ;
617
+ return { errors, warnings } ;
575
618
}
576
619
} else {
577
620
errors . push ( new Error ( 'Missing default locale options.' ) ) ;
578
- return errors ;
621
+ return { errors, warnings } ;
579
622
}
580
623
// END options.localizedData.defaultLocale
581
624
@@ -585,14 +628,14 @@ export class LocalizationPlugin implements Webpack.Plugin {
585
628
if ( this . _options . localizedData . pseudolocales . hasOwnProperty ( pseudolocaleName ) ) {
586
629
if ( this . _defaultLocale === pseudolocaleName ) {
587
630
errors . push ( new Error ( `A pseudolocale (${ pseudolocaleName } ) name is also the default locale name.` ) ) ;
588
- return errors ;
631
+ return { errors, warnings } ;
589
632
}
590
633
591
634
if ( this . _locales . has ( pseudolocaleName ) ) {
592
635
errors . push ( new Error (
593
636
`A pseudolocale (${ pseudolocaleName } ) name is also specified in the translated strings.`
594
637
) ) ;
595
- return errors ;
638
+ return { errors, warnings } ;
596
639
}
597
640
598
641
const pseudoLocaleOpts : IPseudolocaleOptions = this . _options . localizedData . pseudolocales [ pseudolocaleName ] ;
@@ -620,7 +663,7 @@ export class LocalizationPlugin implements Webpack.Plugin {
620
663
}
621
664
// END options.noStringsLocaleName
622
665
623
- return errors ;
666
+ return { errors, warnings } ;
624
667
}
625
668
626
669
/**
@@ -661,4 +704,13 @@ export class LocalizationPlugin implements Webpack.Plugin {
661
704
662
705
return EntityMarker . getMark ( chunk ) ! ;
663
706
}
707
+
708
+ private _convertLocalizationFileToLocData ( locFile : ILocalizationFile ) : ILocaleFileData {
709
+ const locFileData : ILocaleFileData = { } ;
710
+ for ( const stringName in locFile ) { // eslint-disable-line guard-for-in
711
+ locFileData [ stringName ] = locFile [ stringName ] . value ;
712
+ }
713
+
714
+ return locFileData ;
715
+ }
664
716
}
0 commit comments