134 lines
7.3 KiB
JavaScript
Executable file
134 lines
7.3 KiB
JavaScript
Executable file
"use strict";
|
|
/**
|
|
* @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.io/license
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.executeBuild = void 0;
|
|
const source_file_cache_1 = require("../../tools/esbuild/angular/source-file-cache");
|
|
const budget_stats_1 = require("../../tools/esbuild/budget-stats");
|
|
const bundler_context_1 = require("../../tools/esbuild/bundler-context");
|
|
const bundler_execution_result_1 = require("../../tools/esbuild/bundler-execution-result");
|
|
const commonjs_checker_1 = require("../../tools/esbuild/commonjs-checker");
|
|
const license_extractor_1 = require("../../tools/esbuild/license-extractor");
|
|
const utils_1 = require("../../tools/esbuild/utils");
|
|
const bundle_calculator_1 = require("../../utils/bundle-calculator");
|
|
const color_1 = require("../../utils/color");
|
|
const copy_assets_1 = require("../../utils/copy-assets");
|
|
const supported_browsers_1 = require("../../utils/supported-browsers");
|
|
const execute_post_bundle_1 = require("./execute-post-bundle");
|
|
const i18n_1 = require("./i18n");
|
|
const setup_bundling_1 = require("./setup-bundling");
|
|
async function executeBuild(options, context, rebuildState) {
|
|
const { projectRoot, workspaceRoot, i18nOptions, optimizationOptions, assets, cacheOptions, prerenderOptions, } = options;
|
|
// TODO: Consider integrating into watch mode. Would require full rebuild on target changes.
|
|
const browsers = (0, supported_browsers_1.getSupportedBrowsers)(projectRoot, context.logger);
|
|
// Load active translations if inlining
|
|
// TODO: Integrate into watch mode and only load changed translations
|
|
if (i18nOptions.shouldInline) {
|
|
await (0, i18n_1.loadActiveTranslations)(context, i18nOptions);
|
|
}
|
|
// Reuse rebuild state or create new bundle contexts for code and global stylesheets
|
|
let bundlerContexts = rebuildState?.rebuildContexts;
|
|
const codeBundleCache = rebuildState?.codeBundleCache ??
|
|
new source_file_cache_1.SourceFileCache(cacheOptions.enabled ? cacheOptions.path : undefined);
|
|
if (bundlerContexts === undefined) {
|
|
bundlerContexts = (0, setup_bundling_1.setupBundlerContexts)(options, browsers, codeBundleCache);
|
|
}
|
|
const bundlingResult = await bundler_context_1.BundlerContext.bundleAll(bundlerContexts, rebuildState?.fileChanges.all);
|
|
const executionResult = new bundler_execution_result_1.ExecutionResult(bundlerContexts, codeBundleCache);
|
|
executionResult.addWarnings(bundlingResult.warnings);
|
|
// Return if the bundling has errors
|
|
if (bundlingResult.errors) {
|
|
executionResult.addErrors(bundlingResult.errors);
|
|
return executionResult;
|
|
}
|
|
// Analyze external imports if external options are enabled
|
|
if (options.externalPackages || bundlingResult.externalConfiguration) {
|
|
const { externalConfiguration, externalImports: { browser, server }, } = bundlingResult;
|
|
const implicitBrowser = browser ? [...browser] : [];
|
|
const implicitServer = server ? [...server] : [];
|
|
// TODO: Implement wildcard externalConfiguration filtering
|
|
executionResult.setExternalMetadata(externalConfiguration
|
|
? implicitBrowser.filter((value) => !externalConfiguration.includes(value))
|
|
: implicitBrowser, externalConfiguration
|
|
? implicitServer.filter((value) => !externalConfiguration.includes(value))
|
|
: implicitServer, externalConfiguration);
|
|
}
|
|
const { metafile, initialFiles, outputFiles } = bundlingResult;
|
|
executionResult.outputFiles.push(...outputFiles);
|
|
const changedFiles = rebuildState && executionResult.findChangedFiles(rebuildState.previousOutputHashes);
|
|
// Analyze files for bundle budget failures if present
|
|
let budgetFailures;
|
|
if (options.budgets) {
|
|
const compatStats = (0, budget_stats_1.generateBudgetStats)(metafile, initialFiles);
|
|
budgetFailures = [...(0, bundle_calculator_1.checkBudgets)(options.budgets, compatStats, true)];
|
|
for (const { message, severity } of budgetFailures) {
|
|
if (severity === 'error') {
|
|
executionResult.addError(message);
|
|
}
|
|
else {
|
|
executionResult.addWarning(message);
|
|
}
|
|
}
|
|
}
|
|
// Calculate estimated transfer size if scripts are optimized
|
|
let estimatedTransferSizes;
|
|
if (optimizationOptions.scripts || optimizationOptions.styles.minify) {
|
|
estimatedTransferSizes = await (0, utils_1.calculateEstimatedTransferSizes)(executionResult.outputFiles);
|
|
}
|
|
// Check metafile for CommonJS module usage if optimizing scripts
|
|
if (optimizationOptions.scripts) {
|
|
const messages = (0, commonjs_checker_1.checkCommonJSModules)(metafile, options.allowedCommonJsDependencies);
|
|
executionResult.addWarnings(messages);
|
|
}
|
|
// Copy assets
|
|
if (assets) {
|
|
// The webpack copy assets helper is used with no base paths defined. This prevents the helper
|
|
// from directly writing to disk. This should eventually be replaced with a more optimized helper.
|
|
executionResult.addAssets(await (0, copy_assets_1.copyAssets)(assets, [], workspaceRoot));
|
|
}
|
|
// Extract and write licenses for used packages
|
|
if (options.extractLicenses) {
|
|
executionResult.addOutputFile('3rdpartylicenses.txt', await (0, license_extractor_1.extractLicenses)(metafile, workspaceRoot), bundler_context_1.BuildOutputFileType.Root);
|
|
}
|
|
// Perform i18n translation inlining if enabled
|
|
let prerenderedRoutes;
|
|
if (i18nOptions.shouldInline) {
|
|
const result = await (0, i18n_1.inlineI18n)(options, executionResult, initialFiles);
|
|
executionResult.addErrors(result.errors);
|
|
executionResult.addWarnings(result.warnings);
|
|
prerenderedRoutes = result.prerenderedRoutes;
|
|
}
|
|
else {
|
|
const result = await (0, execute_post_bundle_1.executePostBundleSteps)(options, executionResult.outputFiles, executionResult.assetFiles, initialFiles,
|
|
// Set lang attribute to the defined source locale if present
|
|
i18nOptions.hasDefinedSourceLocale ? i18nOptions.sourceLocale : undefined);
|
|
executionResult.addErrors(result.errors);
|
|
executionResult.addWarnings(result.warnings);
|
|
prerenderedRoutes = result.prerenderedRoutes;
|
|
executionResult.outputFiles.push(...result.additionalOutputFiles);
|
|
executionResult.assetFiles.push(...result.additionalAssets);
|
|
}
|
|
if (prerenderOptions) {
|
|
executionResult.addOutputFile('prerendered-routes.json', JSON.stringify({ routes: prerenderedRoutes.sort((a, b) => a.localeCompare(b)) }, null, 2), bundler_context_1.BuildOutputFileType.Root);
|
|
let prerenderMsg = `Prerendered ${prerenderedRoutes.length} static route`;
|
|
if (prerenderedRoutes.length > 1) {
|
|
prerenderMsg += 's.';
|
|
}
|
|
else {
|
|
prerenderMsg += '.';
|
|
}
|
|
context.logger.info(color_1.colors.magenta(prerenderMsg) + '\n');
|
|
}
|
|
(0, utils_1.logBuildStats)(context.logger, metafile, initialFiles, budgetFailures, changedFiles, estimatedTransferSizes);
|
|
// Write metafile if stats option is enabled
|
|
if (options.stats) {
|
|
executionResult.addOutputFile('stats.json', JSON.stringify(metafile, null, 2), bundler_context_1.BuildOutputFileType.Root);
|
|
}
|
|
return executionResult;
|
|
}
|
|
exports.executeBuild = executeBuild;
|