@angular-devkit/build-angular
Version:
Angular Webpack Build Facade
178 lines (177 loc) • 8.56 kB
JavaScript
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.execute = execute;
const private_1 = require("@angular/build/private");
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const load_esm_1 = require("../../utils/load-esm");
const options_1 = require("./options");
const schema_1 = require("./schema");
/**
* @experimental Direct usage of this function is considered experimental.
*/
async function execute(options, context, transforms) {
// Determine project name from builder context target
const projectName = context.target?.project;
if (!projectName) {
context.logger.error(`The 'extract-i18n' builder requires a target to be specified.`);
return { success: false };
}
const { projectType } = (await context.getProjectMetadata(projectName));
if (projectType !== 'application') {
context.logger.error(`Tried to extract from ${projectName} with 'projectType' ${projectType}, which is not supported.` +
` The 'extract-i18n' builder can only extract from applications.`);
return { success: false };
}
// Check Angular version.
(0, private_1.assertCompatibleAngularVersion)(context.workspaceRoot);
// Load the Angular localize package.
// The package is a peer dependency and might not be present
let localizeToolsModule;
try {
localizeToolsModule =
await (0, load_esm_1.loadEsmModule)('@angular/localize/tools');
}
catch {
return {
success: false,
error: `i18n extraction requires the '@angular/localize' package.` +
` You can add it by using 'ng add @angular/localize'.`,
};
}
// Normalize options
const normalizedOptions = await (0, options_1.normalizeOptions)(context, projectName, options);
const builderName = await context.getBuilderNameForTarget(normalizedOptions.buildTarget);
// Extract messages based on configured builder
let extractionResult;
if (builderName === '@angular-devkit/build-angular:application' ||
builderName === '@angular-devkit/build-angular:browser-esbuild') {
const { extractMessages } = await Promise.resolve().then(() => __importStar(require('./application-extraction')));
extractionResult = await extractMessages(normalizedOptions, builderName, context, localizeToolsModule.MessageExtractor);
if (!extractionResult.success) {
return { success: false };
}
}
else {
// Purge old build disk cache.
// Other build systems handle stale cache purging directly.
await (0, private_1.purgeStaleBuildCache)(context);
const { extractMessages } = await Promise.resolve().then(() => __importStar(require('./webpack-extraction')));
extractionResult = await extractMessages(normalizedOptions, builderName, context, transforms);
// Return the builder result if it failed
if (!extractionResult.builderResult.success) {
return extractionResult.builderResult;
}
}
// Perform duplicate message checks
const { checkDuplicateMessages } = localizeToolsModule;
// The filesystem is used to create a relative path for each file
// from the basePath. This relative path is then used in the error message.
const checkFileSystem = {
relative(from, to) {
return node_path_1.default.relative(from, to);
},
};
const duplicateTranslationBehavior = normalizedOptions.i18nOptions.duplicateTranslationBehavior;
const diagnostics = checkDuplicateMessages(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
checkFileSystem, extractionResult.messages, duplicateTranslationBehavior,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
extractionResult.basePath);
if (diagnostics.messages.length > 0 && duplicateTranslationBehavior !== 'ignore') {
if (duplicateTranslationBehavior === 'error') {
context.logger.error(`Extraction Failed: ${diagnostics.formatDiagnostics('')}`);
return { success: false };
}
else {
context.logger.warn(diagnostics.formatDiagnostics(''));
}
}
// Serialize all extracted messages
const serializer = await createSerializer(localizeToolsModule, normalizedOptions.format, normalizedOptions.i18nOptions.sourceLocale, extractionResult.basePath, extractionResult.useLegacyIds, diagnostics);
const content = serializer.serialize(extractionResult.messages);
// Ensure directory exists
const outputPath = node_path_1.default.dirname(normalizedOptions.outFile);
if (!node_fs_1.default.existsSync(outputPath)) {
node_fs_1.default.mkdirSync(outputPath, { recursive: true });
}
// Write translation file
node_fs_1.default.writeFileSync(normalizedOptions.outFile, content);
if (normalizedOptions.progress) {
context.logger.info(`Extraction Complete. (Messages: ${extractionResult.messages.length})`);
}
return { success: true, outputPath: normalizedOptions.outFile };
}
async function createSerializer(localizeToolsModule, format, sourceLocale, basePath, useLegacyIds, diagnostics) {
const { XmbTranslationSerializer, LegacyMessageIdMigrationSerializer, ArbTranslationSerializer, Xliff1TranslationSerializer, Xliff2TranslationSerializer, SimpleJsonTranslationSerializer, } = localizeToolsModule;
switch (format) {
case schema_1.Format.Xmb:
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return new XmbTranslationSerializer(basePath, useLegacyIds);
case schema_1.Format.Xlf:
case schema_1.Format.Xlif:
case schema_1.Format.Xliff:
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return new Xliff1TranslationSerializer(sourceLocale, basePath, useLegacyIds, {});
case schema_1.Format.Xlf2:
case schema_1.Format.Xliff2:
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return new Xliff2TranslationSerializer(sourceLocale, basePath, useLegacyIds, {});
case schema_1.Format.Json:
return new SimpleJsonTranslationSerializer(sourceLocale);
case schema_1.Format.LegacyMigrate:
return new LegacyMessageIdMigrationSerializer(diagnostics);
case schema_1.Format.Arb:
return new ArbTranslationSerializer(sourceLocale,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
basePath, {
relative(from, to) {
return node_path_1.default.relative(from, to);
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
});
}
}
;