Skip to content

Commit a5aefa1

Browse files
clydinmgechev
authored andcommitted
refactor(@angular-devkit/build-angular): temporarily disable plugin based localization
1 parent 523a20d commit a5aefa1

File tree

3 files changed

+162
-1
lines changed

3 files changed

+162
-1
lines changed

packages/angular_devkit/build_angular/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"@angular-devkit/build-webpack": "0.0.0",
1313
"@angular-devkit/core": "0.0.0",
1414
"@babel/core": "7.8.6",
15+
"@babel/generator": "7.8.6",
1516
"@babel/preset-env": "7.8.6",
1617
"@babel/template": "7.8.6",
1718
"@jsdevtools/coverage-istanbul-loader": "3.0.0",
@@ -35,6 +36,7 @@
3536
"less-loader": "5.0.0",
3637
"license-webpack-plugin": "2.1.3",
3738
"loader-utils": "1.4.0",
39+
"magic-string": "0.25.7",
3840
"mini-css-extract-plugin": "0.9.0",
3941
"minimatch": "3.0.4",
4042
"parse5": "4.0.0",

packages/angular_devkit/build_angular/src/utils/process-bundle.ts

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
parseSync,
1313
transformAsync,
1414
transformFromAstSync,
15+
traverse,
1516
types,
1617
} from '@babel/core';
1718
import templateBuilder from '@babel/template';
@@ -502,6 +503,8 @@ function createReplacePlugin(replacements: [string, string][]): PluginObj {
502503
};
503504
}
504505

506+
const USE_LOCALIZE_PLUGINS = false;
507+
505508
async function createI18nPlugins(
506509
locale: string,
507510
translation: unknown | undefined,
@@ -565,6 +568,13 @@ export interface InlineOptions {
565568
setLocale?: boolean;
566569
}
567570

571+
interface LocalizePosition {
572+
start: number;
573+
end: number;
574+
messageParts: TemplateStringsArray;
575+
expressions: types.Expression[];
576+
}
577+
568578
const localizeName = '$localize';
569579

570580
export async function inlineLocales(options: InlineOptions) {
@@ -603,6 +613,10 @@ export async function inlineLocales(options: InlineOptions) {
603613
throw new Error(`Unknown error occurred inlining file "${options.filename}"`);
604614
}
605615

616+
if (!USE_LOCALIZE_PLUGINS) {
617+
return inlineLocalesDirect(ast, options);
618+
}
619+
606620
const diagnostics = [];
607621
const inputMap = options.map && (JSON.parse(options.map) as RawSourceMap);
608622
for (const locale of i18n.inlineLocales) {
@@ -667,6 +681,95 @@ export async function inlineLocales(options: InlineOptions) {
667681
return { file: options.filename, diagnostics };
668682
}
669683

684+
async function inlineLocalesDirect(ast: ParseResult, options: InlineOptions) {
685+
if (!i18n || i18n.inlineLocales.size === 0) {
686+
return { file: options.filename, diagnostics: [], count: 0 };
687+
}
688+
689+
const { default: MagicString } = await import('magic-string');
690+
const { default: generate } = await import('@babel/generator');
691+
const utils = await import(
692+
// tslint:disable-next-line: trailing-comma no-implicit-dependencies
693+
'@angular/localize/src/tools/src/translate/source_files/source_file_utils'
694+
);
695+
// tslint:disable-next-line: no-implicit-dependencies
696+
const localizeDiag = await import('@angular/localize/src/tools/src/diagnostics');
697+
698+
const diagnostics = new localizeDiag.Diagnostics();
699+
700+
const positions = findLocalizePositions(ast, options, utils);
701+
if (positions.length === 0 && !options.setLocale) {
702+
return inlineCopyOnly(options);
703+
}
704+
705+
// tslint:disable-next-line: no-any
706+
let content = new MagicString(options.code, { filename: options.filename } as any);
707+
const inputMap = options.map && (JSON.parse(options.map) as RawSourceMap);
708+
let contentClone;
709+
for (const locale of i18n.inlineLocales) {
710+
const isSourceLocale = locale === i18n.sourceLocale;
711+
// tslint:disable-next-line: no-any
712+
const translations: any = isSourceLocale ? {} : i18n.locales[locale].translation || {};
713+
for (const position of positions) {
714+
const translated = utils.translate(
715+
diagnostics,
716+
translations,
717+
position.messageParts,
718+
position.expressions,
719+
isSourceLocale ? 'ignore' : options.missingTranslation || 'warning',
720+
);
721+
722+
const expression = utils.buildLocalizeReplacement(translated[0], translated[1]);
723+
const { code } = generate(expression);
724+
725+
content.overwrite(position.start, position.end, code);
726+
}
727+
728+
if (options.setLocale) {
729+
const setLocaleText = `var $localize=Object.assign(void 0===$localize?{}:$localize,{locale:"${locale}"});`;
730+
contentClone = content.clone();
731+
content.prepend(setLocaleText);
732+
733+
// If locale data is provided, load it and prepend to file
734+
const localeDataPath = i18n.locales[locale] && i18n.locales[locale].dataPath;
735+
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 + ';');
739+
}
740+
}
741+
742+
const output = content.toString();
743+
const outputPath = path.join(
744+
options.outputPath,
745+
i18n.flatOutput ? '' : locale,
746+
options.filename,
747+
);
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+
);
760+
761+
fs.writeFileSync(outputPath + '.map', JSON.stringify(outputMap));
762+
}
763+
764+
if (contentClone) {
765+
content = contentClone;
766+
contentClone = undefined;
767+
}
768+
}
769+
770+
return { file: options.filename, diagnostics: diagnostics.messages, count: positions.length };
771+
}
772+
670773
function inlineCopyOnly(options: InlineOptions) {
671774
if (!i18n) {
672775
throw new Error('i18n options are missing');
@@ -687,6 +790,62 @@ function inlineCopyOnly(options: InlineOptions) {
687790
return { file: options.filename, diagnostics: [], count: 0 };
688791
}
689792

793+
function findLocalizePositions(
794+
ast: ParseResult,
795+
options: InlineOptions,
796+
// tslint:disable-next-line: no-implicit-dependencies
797+
utils: typeof import('@angular/localize/src/tools/src/translate/source_files/source_file_utils'),
798+
): LocalizePosition[] {
799+
const positions: LocalizePosition[] = [];
800+
if (options.es5) {
801+
traverse(ast, {
802+
CallExpression(path: NodePath<types.CallExpression>) {
803+
const callee = path.get('callee');
804+
if (
805+
callee.isIdentifier() &&
806+
callee.node.name === localizeName &&
807+
utils.isGlobalIdentifier(callee)
808+
) {
809+
const messageParts = utils.unwrapMessagePartsFromLocalizeCall(path);
810+
const expressions = utils.unwrapSubstitutionsFromLocalizeCall(path.node);
811+
positions.push({
812+
// tslint:disable-next-line: no-non-null-assertion
813+
start: path.node.start!,
814+
// tslint:disable-next-line: no-non-null-assertion
815+
end: path.node.end!,
816+
messageParts,
817+
expressions,
818+
});
819+
}
820+
},
821+
});
822+
} else {
823+
const traverseFast = ((types as unknown) as {
824+
traverseFast: (node: types.Node, enter: (node: types.Node) => void) => void;
825+
}).traverseFast;
826+
827+
traverseFast(ast, node => {
828+
if (
829+
node.type === 'TaggedTemplateExpression' &&
830+
types.isIdentifier(node.tag) &&
831+
node.tag.name === localizeName
832+
) {
833+
const messageParts = utils.unwrapMessagePartsFromTemplateLiteral(node.quasi.quasis);
834+
positions.push({
835+
// tslint:disable-next-line: no-non-null-assertion
836+
start: node.start!,
837+
// tslint:disable-next-line: no-non-null-assertion
838+
end: node.end!,
839+
messageParts,
840+
expressions: node.quasi.expressions,
841+
});
842+
}
843+
});
844+
}
845+
846+
return positions;
847+
}
848+
690849
async function loadLocaleData(path: string, optimize: boolean): Promise<string> {
691850
// The path is validated during option processing before the build starts
692851
const content = fs.readFileSync(path, 'utf8');

yarn.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@
152152
semver "^5.4.1"
153153
source-map "^0.5.0"
154154

155-
"@babel/generator@^7.4.0", "@babel/generator@^7.8.3", "@babel/generator@^7.8.6":
155+
"@babel/generator@7.8.6", "@babel/generator@^7.4.0", "@babel/generator@^7.8.3", "@babel/generator@^7.8.6":
156156
version "7.8.6"
157157
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.6.tgz#57adf96d370c9a63c241cd719f9111468578537a"
158158
integrity sha512-4bpOR5ZBz+wWcMeVtcf7FbjcFzCp+817z2/gHNncIRcM9MmKzUhtWCYAq27RAfUrAFwb+OCG1s9WEaVxfi6cjg==

0 commit comments

Comments
 (0)