@angular-devkit/build-angular 17.1.0-next.1 → 17.1.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/package.json +18 -18
  2. package/src/builders/application/build-action.d.ts +4 -3
  3. package/src/builders/application/build-action.js +24 -14
  4. package/src/builders/application/execute-build.js +3 -3
  5. package/src/builders/application/index.d.ts +20 -10
  6. package/src/builders/application/index.js +38 -26
  7. package/src/builders/application/options.d.ts +11 -3
  8. package/src/builders/application/options.js +39 -26
  9. package/src/builders/application/schema.d.ts +32 -2
  10. package/src/builders/application/schema.json +40 -2
  11. package/src/builders/browser-esbuild/builder-status-warnings.js +1 -3
  12. package/src/builders/browser-esbuild/index.js +8 -4
  13. package/src/builders/dev-server/builder.js +5 -0
  14. package/src/builders/dev-server/vite-server.js +16 -16
  15. package/src/builders/karma/index.js +4 -1
  16. package/src/builders/karma/schema.d.ts +6 -2
  17. package/src/builders/karma/schema.json +12 -2
  18. package/src/builders/ssr-dev-server/index.js +17 -31
  19. package/src/tools/esbuild/angular/angular-host.js +7 -1
  20. package/src/tools/esbuild/angular/compiler-plugin.js +11 -27
  21. package/src/tools/esbuild/angular/component-stylesheets.d.ts +3 -6
  22. package/src/tools/esbuild/angular/component-stylesheets.js +42 -47
  23. package/src/tools/esbuild/angular/jit-plugin-callbacks.d.ts +2 -1
  24. package/src/tools/esbuild/angular/jit-plugin-callbacks.js +16 -16
  25. package/src/tools/esbuild/angular/source-file-cache.js +0 -1
  26. package/src/tools/esbuild/bundler-context.d.ts +1 -1
  27. package/src/tools/esbuild/bundler-context.js +18 -2
  28. package/src/tools/esbuild/compiler-plugin-options.js +5 -3
  29. package/src/tools/esbuild/global-styles.js +4 -2
  30. package/src/tools/esbuild/index-html-generator.js +3 -1
  31. package/src/tools/esbuild/stylesheets/bundle-options.d.ts +4 -1
  32. package/src/tools/esbuild/stylesheets/bundle-options.js +11 -6
  33. package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.d.ts +25 -0
  34. package/src/tools/esbuild/stylesheets/css-inline-fonts-plugin.js +57 -0
  35. package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js +9 -1
  36. package/src/tools/esbuild/utils.d.ts +2 -2
  37. package/src/tools/esbuild/utils.js +61 -74
  38. package/src/tools/esbuild/watcher.js +56 -121
  39. package/src/utils/check-port.js +15 -29
  40. package/src/utils/delete-output-dir.d.ts +1 -1
  41. package/src/utils/delete-output-dir.js +11 -2
  42. package/src/utils/index-file/index-html-generator.js +15 -28
  43. package/src/utils/index-file/inline-fonts.d.ts +6 -1
  44. package/src/utils/index-file/inline-fonts.js +30 -14
  45. package/src/utils/index.d.ts +1 -0
  46. package/src/utils/index.js +1 -0
  47. package/src/{builders/dev-server → utils}/load-proxy-config.js +2 -2
  48. package/src/utils/server-rendering/esm-in-memory-loader/node-18-utils.js +6 -5
  49. package/src/tools/esbuild/normalize-path.d.ts +0 -8
  50. package/src/tools/esbuild/normalize-path.js +0 -22
  51. /package/src/{builders/dev-server → utils}/load-proxy-config.d.ts +0 -0
@@ -30,9 +30,7 @@ function logBuilderStatusWarnings(options, { logger }) {
30
30
  if (typeof value === 'object' && Object.keys(value).length === 0) {
31
31
  continue;
32
32
  }
33
- if (unsupportedOption === 'vendorChunk' ||
34
- unsupportedOption === 'resourcesOutputPath' ||
35
- unsupportedOption === 'deployUrl') {
33
+ if (unsupportedOption === 'vendorChunk' || unsupportedOption === 'resourcesOutputPath') {
36
34
  logger.warn(`The '${unsupportedOption}' option is not used by this builder and will be ignored.`);
37
35
  continue;
38
36
  }
@@ -31,13 +31,13 @@ async function* buildEsbuildBrowser(userOptions, context, infrastructureSettings
31
31
  (0, builder_status_warnings_1.logBuilderStatusWarnings)(userOptions, context);
32
32
  const normalizedOptions = normalizeOptions(userOptions);
33
33
  const { deleteOutputPath, outputPath } = normalizedOptions;
34
- const fullOutputPath = node_path_1.default.join(context.workspaceRoot, outputPath);
34
+ const fullOutputPath = node_path_1.default.join(context.workspaceRoot, outputPath.base);
35
35
  if (deleteOutputPath && infrastructureSettings?.write !== false) {
36
- await (0, utils_2.deleteOutputDir)(context.workspaceRoot, outputPath);
36
+ await (0, utils_2.deleteOutputDir)(context.workspaceRoot, outputPath.base);
37
37
  }
38
38
  for await (const result of (0, application_1.buildApplicationInternal)(normalizedOptions, context, {
39
39
  write: false,
40
- }, plugins)) {
40
+ }, plugins && { codePlugins: plugins })) {
41
41
  if (infrastructureSettings?.write !== false && result.outputFiles) {
42
42
  // Write output files
43
43
  await writeResultFiles(result.outputFiles, result.assetFiles, fullOutputPath);
@@ -55,11 +55,15 @@ async function* buildEsbuildBrowser(userOptions, context, infrastructureSettings
55
55
  }
56
56
  exports.buildEsbuildBrowser = buildEsbuildBrowser;
57
57
  function normalizeOptions(options) {
58
- const { main: browser, ngswConfigPath, serviceWorker, polyfills, ...otherOptions } = options;
58
+ const { main: browser, outputPath, ngswConfigPath, serviceWorker, polyfills, ...otherOptions } = options;
59
59
  return {
60
60
  browser,
61
61
  serviceWorker: serviceWorker ? ngswConfigPath : false,
62
62
  polyfills: typeof polyfills === 'string' ? [polyfills] : polyfills,
63
+ outputPath: {
64
+ base: outputPath,
65
+ browser: '',
66
+ },
63
67
  ...otherOptions,
64
68
  };
65
69
  }
@@ -65,6 +65,11 @@ function execute(options, context, transforms = {}, extensions) {
65
65
  if (transforms?.logging || transforms?.webpackConfiguration) {
66
66
  throw new Error('The `application` and `browser-esbuild` builders do not support Webpack transforms.');
67
67
  }
68
+ if (normalizedOptions.forceEsbuild &&
69
+ builderName === '@angular-devkit/build-angular:browser') {
70
+ // The compatibility builder should be used if esbuild is force enabled with the official Webpack-based builder.
71
+ builderName = '@angular-devkit/build-angular:browser-esbuild';
72
+ }
68
73
  return (0, rxjs_1.defer)(() => Promise.resolve().then(() => __importStar(require('./vite-server')))).pipe((0, rxjs_1.switchMap)(({ serveWithVite }) => serveWithVite(normalizedOptions, builderName, context, transforms, extensions)));
69
74
  }
70
75
  if (extensions?.buildPlugins?.length) {
@@ -51,7 +51,6 @@ const supported_browsers_1 = require("../../utils/supported-browsers");
51
51
  const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
52
52
  const application_1 = require("../application");
53
53
  const browser_esbuild_1 = require("../browser-esbuild");
54
- const load_proxy_config_1 = require("./load-proxy-config");
55
54
  // eslint-disable-next-line max-lines-per-function
56
55
  async function* serveWithVite(serverOptions, builderName, context, transformers, extensions) {
57
56
  // Get the browser configuration from the target name.
@@ -74,8 +73,11 @@ async function* serveWithVite(serverOptions, builderName, context, transformers,
74
73
  }
75
74
  // Set all packages as external to support Vite's prebundle caching
76
75
  browserOptions.externalPackages = serverOptions.cacheOptions.enabled;
77
- if (serverOptions.servePath === undefined && browserOptions.baseHref !== undefined) {
78
- serverOptions.servePath = browserOptions.baseHref;
76
+ const baseHref = browserOptions.baseHref;
77
+ if (serverOptions.servePath === undefined && baseHref !== undefined) {
78
+ // Remove trailing slash
79
+ serverOptions.servePath =
80
+ baseHref[baseHref.length - 1] === '/' ? baseHref.slice(0, -1) : baseHref;
79
81
  }
80
82
  // The development server currently only supports a single locale when localizing.
81
83
  // This matches the behavior of the Webpack-based development server but could be expanded in the future.
@@ -119,14 +121,10 @@ async function* serveWithVite(serverOptions, builderName, context, transformers,
119
121
  deferred?.();
120
122
  });
121
123
  const build = builderName === '@angular-devkit/build-angular:browser-esbuild'
122
- ? browser_esbuild_1.buildEsbuildBrowser
123
- : application_1.buildApplicationInternal;
124
+ ? browser_esbuild_1.buildEsbuildBrowser.bind(undefined, browserOptions, context, { write: false }, extensions?.buildPlugins)
125
+ : application_1.buildApplicationInternal.bind(undefined, browserOptions, context, { write: false }, { codePlugins: extensions?.buildPlugins });
124
126
  // TODO: Switch this to an architect schedule call when infrastructure settings are supported
125
- for await (const result of build(
126
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
127
- browserOptions, context, {
128
- write: false,
129
- }, extensions?.buildPlugins)) {
127
+ for await (const result of build()) {
130
128
  (0, node_assert_1.default)(result.outputFiles, 'Builder did not provide result files.');
131
129
  // If build failed, nothing to serve
132
130
  if (!result.success) {
@@ -179,7 +177,7 @@ async function* serveWithVite(serverOptions, builderName, context, transformers,
179
177
  if (server) {
180
178
  // Update fs allow list to include any new assets from the build option.
181
179
  server.config.server.fs.allow = [
182
- ...new Set(...server.config.server.fs.allow, ...assetFiles.values()),
180
+ ...new Set([...server.config.server.fs.allow, ...assetFiles.values()]),
183
181
  ];
184
182
  handleUpdate(normalizePath, generatedFiles, server, serverOptions, context.logger);
185
183
  }
@@ -328,7 +326,7 @@ function analyzeResultFiles(normalizePath, htmlIndexPath, resultFiles, generated
328
326
  }
329
327
  // eslint-disable-next-line max-lines-per-function
330
328
  async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks, externalMetadata, ssr, prebundleTransformer, target, prebundleLoaderExtensions, extensionMiddleware, indexHtmlTransformer, thirdPartySourcemaps = false) {
331
- const proxy = await (0, load_proxy_config_1.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig, true);
329
+ const proxy = await (0, utils_2.loadProxyConfiguration)(serverOptions.workspaceRoot, serverOptions.proxyConfig, true);
332
330
  // dynamically import Vite for ESM compatibility
333
331
  const { normalizePath } = await (0, load_esm_1.loadEsmModule)('vite');
334
332
  // Path will not exist on disk and only used to provide separate path for Vite requests
@@ -350,7 +348,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
350
348
  css: {
351
349
  devSourcemap: true,
352
350
  },
353
- // Vite will normalize the `base` option by adding a leading and trailing forward slash.
351
+ // Vite will normalize the `base` option by adding a leading slash.
354
352
  base: serverOptions.servePath,
355
353
  resolve: {
356
354
  mainFields: ['es2020', 'browser', 'module', 'main'],
@@ -476,6 +474,10 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
476
474
  // Rewrite all build assets to a vite raw fs URL
477
475
  const assetSourcePath = assets.get(pathname);
478
476
  if (assetSourcePath !== undefined) {
477
+ // Workaround to disable Vite transformer middleware.
478
+ // See: https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/middlewares/transform.ts#L201 and
479
+ // https://github.com/vitejs/vite/blob/746a1daab0395f98f0afbdee8f364cb6cf2f3b3f/packages/vite/src/node/server/transformRequest.ts#L204-L206
480
+ req.headers.accept = 'text/html';
479
481
  // The encoding needs to match what happens in the vite static middleware.
480
482
  // ref: https://github.com/vitejs/vite/blob/d4f13bd81468961c8c926438e815ab6b1c82735e/packages/vite/src/node/server/middlewares/static.ts#L163
481
483
  req.url = `${server.config.base}@fs/${encodeURI(assetSourcePath)}`;
@@ -525,11 +527,9 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
525
527
  return;
526
528
  }
527
529
  transformIndexHtmlAndAddHeaders(url, rawHtml, res, next, async (html) => {
528
- const protocol = serverOptions.ssl ? 'https' : 'http';
529
- const route = `${protocol}://${req.headers.host}${req.originalUrl}`;
530
530
  const { content } = await (0, render_page_1.renderPage)({
531
531
  document: html,
532
- route,
532
+ route: new URL(req.originalUrl ?? '/', server.resolvedUrls?.local[0]).toString(),
533
533
  serverContext: 'ssr',
534
534
  loadBundle: (uri) =>
535
535
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -90,9 +90,12 @@ function execute(options, context, transforms = {}) {
90
90
  : getBuiltInKarmaConfig(context.workspaceRoot, projectName);
91
91
  karmaOptions.singleRun = singleRun;
92
92
  // Convert browsers from a string to an array
93
- if (options.browsers) {
93
+ if (typeof options.browsers === 'string' && options.browsers) {
94
94
  karmaOptions.browsers = options.browsers.split(',');
95
95
  }
96
+ else if (options.browsers === false) {
97
+ karmaOptions.browsers = [];
98
+ }
96
99
  if (options.reporters) {
97
100
  // Split along commas to make it more natural, and remove empty strings.
98
101
  const reporters = options.reporters
@@ -7,9 +7,9 @@ export interface Schema {
7
7
  */
8
8
  assets?: AssetPattern[];
9
9
  /**
10
- * Override which browsers tests are run against.
10
+ * Override which browsers tests are run against. Set to `false` to not use any browser.
11
11
  */
12
- browsers?: string;
12
+ browsers?: Browsers;
13
13
  /**
14
14
  * Output a code coverage report.
15
15
  */
@@ -117,6 +117,10 @@ export interface AssetPatternClass {
117
117
  */
118
118
  output: string;
119
119
  }
120
+ /**
121
+ * Override which browsers tests are run against. Set to `false` to not use any browser.
122
+ */
123
+ export type Browsers = boolean | string;
120
124
  export interface FileReplacement {
121
125
  replace?: string;
122
126
  replaceWith?: string;
@@ -199,8 +199,18 @@
199
199
  "description": "Do not use the real path when resolving modules. If unset then will default to `true` if NodeJS option --preserve-symlinks is set."
200
200
  },
201
201
  "browsers": {
202
- "type": "string",
203
- "description": "Override which browsers tests are run against."
202
+ "description": "Override which browsers tests are run against. Set to `false` to not use any browser.",
203
+ "oneOf": [
204
+ {
205
+ "type": "string",
206
+ "description": "A comma seperate list of browsers to run tests against."
207
+ },
208
+ {
209
+ "const": false,
210
+ "type": "boolean",
211
+ "description": "Does use run tests against a browser."
212
+ }
213
+ ]
204
214
  },
205
215
  "codeCoverage": {
206
216
  "type": "boolean",
@@ -36,8 +36,8 @@ const core_1 = require("@angular-devkit/core");
36
36
  const path_1 = require("path");
37
37
  const rxjs_1 = require("rxjs");
38
38
  const url = __importStar(require("url"));
39
- const error_1 = require("../../utils/error");
40
- const utils_1 = require("./utils");
39
+ const utils_1 = require("../../utils");
40
+ const utils_2 = require("./utils");
41
41
  /** Log messages to ignore and not rely to the logger */
42
42
  const IGNORED_STDOUT_MESSAGES = [
43
43
  'server listening on',
@@ -78,7 +78,7 @@ function execute(options, context) {
78
78
  DON'T USE IT FOR PRODUCTION!
79
79
  ****************************************************************************************
80
80
  `);
81
- return (0, rxjs_1.zip)(browserTargetRun, serverTargetRun, (0, utils_1.getAvailablePort)()).pipe((0, rxjs_1.switchMap)(([br, sr, nodeServerPort]) => {
81
+ return (0, rxjs_1.zip)(browserTargetRun, serverTargetRun, (0, utils_2.getAvailablePort)()).pipe((0, rxjs_1.switchMap)(([br, sr, nodeServerPort]) => {
82
82
  return (0, rxjs_1.combineLatest)([br.output, sr.output]).pipe(
83
83
  // This is needed so that if both server and browser emit close to each other
84
84
  // we only emit once. This typically happens on the first build.
@@ -101,7 +101,7 @@ function execute(options, context) {
101
101
  context.logger.info('\nCompiled successfully.');
102
102
  }
103
103
  }), (0, rxjs_1.debounce)(([builderOutput]) => builderOutput.success && !options.inspect
104
- ? (0, utils_1.waitUntilServerIsListening)(nodeServerPort)
104
+ ? (0, utils_2.waitUntilServerIsListening)(nodeServerPort)
105
105
  : rxjs_1.EMPTY), (0, rxjs_1.finalize)(() => {
106
106
  void br.stop();
107
107
  void sr.stop();
@@ -162,7 +162,7 @@ function startNodeServer(serverOutput, port, logger, inspectMode = false) {
162
162
  args.unshift('--inspect-brk');
163
163
  }
164
164
  return (0, rxjs_1.of)(null).pipe((0, rxjs_1.delay)(0), // Avoid EADDRINUSE error since it will cause the kill event to be finish.
165
- (0, rxjs_1.switchMap)(() => (0, utils_1.spawnAsObservable)('node', args, { env, shell: true })), (0, rxjs_1.tap)((res) => log({ stderr: res.stderr, stdout: res.stdout }, logger)), (0, rxjs_1.ignoreElements)(),
165
+ (0, rxjs_1.switchMap)(() => (0, utils_2.spawnAsObservable)('node', args, { env, shell: true })), (0, rxjs_1.tap)((res) => log({ stderr: res.stderr, stdout: res.stdout }, logger)), (0, rxjs_1.ignoreElements)(),
166
166
  // Emit a signal after the process has been started
167
167
  (0, rxjs_1.startWith)(undefined));
168
168
  }
@@ -171,7 +171,7 @@ async function initBrowserSync(browserSyncInstance, nodeServerPort, options, con
171
171
  return browserSyncInstance;
172
172
  }
173
173
  const { port: browserSyncPort, open, host, publicHost, proxyConfig } = options;
174
- const bsPort = browserSyncPort || (await (0, utils_1.getAvailablePort)());
174
+ const bsPort = browserSyncPort || (await (0, utils_2.getAvailablePort)());
175
175
  const bsOptions = {
176
176
  proxy: {
177
177
  target: `localhost:${nodeServerPort}`,
@@ -283,33 +283,19 @@ function getSslConfig(root, options) {
283
283
  return ssl;
284
284
  }
285
285
  async function getProxyConfig(root, proxyConfig) {
286
- const proxyPath = (0, path_1.resolve)(root, proxyConfig);
287
- let proxySettings;
288
- try {
289
- proxySettings = require(proxyPath);
290
- }
291
- catch (error) {
292
- (0, error_1.assertIsError)(error);
293
- if (error.code === 'MODULE_NOT_FOUND') {
294
- throw new Error(`Proxy config file ${proxyPath} does not exist.`);
295
- }
296
- throw error;
297
- }
298
- const proxies = Array.isArray(proxySettings) ? proxySettings : [proxySettings];
286
+ const proxy = await (0, utils_1.loadProxyConfiguration)(root, proxyConfig, false);
299
287
  const createdProxies = [];
300
288
  const { createProxyMiddleware } = await Promise.resolve().then(() => __importStar(require('http-proxy-middleware')));
301
- for (const proxy of proxies) {
302
- for (const [key, context] of Object.entries(proxy)) {
303
- if (typeof key === 'string') {
304
- createdProxies.push(createProxyMiddleware(key.replace(/^\*$/, '**').replace(/\/\*$/, ''),
305
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
306
- context));
307
- }
308
- else {
309
- createdProxies.push(
310
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
311
- createProxyMiddleware(key, context));
312
- }
289
+ for (const [key, context] of Object.entries(proxy)) {
290
+ if (typeof key === 'string') {
291
+ createdProxies.push(createProxyMiddleware(key.replace(/^\*$/, '**').replace(/\/\*$/, ''),
292
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
293
+ context));
294
+ }
295
+ else {
296
+ createdProxies.push(
297
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
298
+ createProxyMiddleware(key, context));
313
299
  }
314
300
  }
315
301
  return createdProxies;
@@ -28,6 +28,12 @@ exports.ensureSourceFileVersions = ensureSourceFileVersions;
28
28
  function createAngularCompilerHost(compilerOptions, hostOptions) {
29
29
  // Create TypeScript compiler host
30
30
  const host = typescript_1.default.createIncrementalCompilerHost(compilerOptions);
31
+ // Set the parsing mode to the same as TS 5.3 default for tsc. This provides a parse
32
+ // performance improvement by skipping non-type related JSDoc parsing.
33
+ // NOTE: The check for this enum can be removed when TS 5.3 support is the minimum.
34
+ if (typescript_1.default.JSDocParsingMode) {
35
+ host.jsDocParsingMode = typescript_1.default.JSDocParsingMode.ParseForTypeErrors;
36
+ }
31
37
  // The AOT compiler currently requires this hook to allow for a transformResource hook.
32
38
  // Once the AOT compiler allows only a transformResource hook, this can be reevaluated.
33
39
  host.readResource = async function (filename) {
@@ -40,7 +46,7 @@ function createAngularCompilerHost(compilerOptions, hostOptions) {
40
46
  return null;
41
47
  }
42
48
  const result = await hostOptions.transformStylesheet(data, context.containingFile, context.resourceFile ?? undefined);
43
- return result ? { content: result } : null;
49
+ return typeof result === 'string' ? { content: result } : null;
44
50
  };
45
51
  // Allow the AOT compiler to request the set of changed templates and styles
46
52
  host.getModifiedResourceFiles = function () {
@@ -35,7 +35,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.createCompilerPlugin = void 0;
37
37
  const node_assert_1 = __importDefault(require("node:assert"));
38
- const node_fs_1 = require("node:fs");
39
38
  const path = __importStar(require("node:path"));
40
39
  const environment_options_1 = require("../../../utils/environment-options");
41
40
  const javascript_transformer_1 = require("../javascript-transformer");
@@ -54,18 +53,6 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
54
53
  async setup(build) {
55
54
  let setupWarnings = [];
56
55
  const preserveSymlinks = build.initialOptions.preserveSymlinks;
57
- let tsconfigPath = pluginOptions.tsconfig;
58
- if (!preserveSymlinks) {
59
- // Use the real path of the tsconfig if not preserving symlinks.
60
- // This ensures the TS source file paths are based on the real path of the configuration.
61
- // NOTE: promises.realpath should not be used here since it uses realpath.native which
62
- // can cause case conversion and other undesirable behavior on Windows systems.
63
- // ref: https://github.com/nodejs/node/issues/7726
64
- try {
65
- tsconfigPath = (0, node_fs_1.realpathSync)(tsconfigPath);
66
- }
67
- catch { }
68
- }
69
56
  // Initialize a worker pool for JavaScript transformations
70
57
  const javascriptTransformer = new javascript_transformer_1.JavaScriptTransformer(pluginOptions, environment_options_1.maxWorkers);
71
58
  // Setup defines based on the values used by the Angular compiler-cli
@@ -132,14 +119,14 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
132
119
  else {
133
120
  stylesheetResult = await stylesheetBundler.bundleInline(data, containingFile, styleOptions.inlineStyleLanguage);
134
121
  }
135
- const { contents, resourceFiles, referencedFiles, errors, warnings } = stylesheetResult;
122
+ const { contents, outputFiles, metafile, referencedFiles, errors, warnings } = stylesheetResult;
136
123
  if (errors) {
137
124
  (result.errors ??= []).push(...errors);
138
125
  }
139
126
  (result.warnings ??= []).push(...warnings);
140
127
  additionalResults.set(stylesheetFile ?? containingFile, {
141
- outputFiles: resourceFiles,
142
- metafile: stylesheetResult.metafile,
128
+ outputFiles,
129
+ metafile,
143
130
  });
144
131
  if (referencedFiles) {
145
132
  referencedFileTracker.add(containingFile, referencedFiles);
@@ -185,7 +172,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
185
172
  // In watch mode, previous build state will be reused.
186
173
  let referencedFiles;
187
174
  try {
188
- const initializationResult = await compilation.initialize(tsconfigPath, hostOptions, createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks));
175
+ const initializationResult = await compilation.initialize(pluginOptions.tsconfig, hostOptions, createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserveSymlinks));
189
176
  shouldTsIgnoreJs = !initializationResult.compilerOptions.allowJs;
190
177
  referencedFiles = initializationResult.referencedFiles;
191
178
  }
@@ -308,7 +295,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
308
295
  }));
309
296
  // Setup bundling of component templates and stylesheets when in JIT mode
310
297
  if (pluginOptions.jit) {
311
- (0, jit_plugin_callbacks_1.setupJitPluginCallbacks)(build, stylesheetBundler, additionalResults, styleOptions.inlineStyleLanguage);
298
+ (0, jit_plugin_callbacks_1.setupJitPluginCallbacks)(build, stylesheetBundler, additionalResults, styleOptions.inlineStyleLanguage, pluginOptions.loadResultCache);
312
299
  }
313
300
  build.onEnd((result) => {
314
301
  // Ensure other compilations are unblocked if the main compilation throws during start
@@ -401,22 +388,19 @@ function createCompilerOptionsTransformer(setupWarnings, pluginOptions, preserve
401
388
  function bundleWebWorker(build, pluginOptions, workerFile) {
402
389
  try {
403
390
  return build.esbuild.buildSync({
391
+ ...build.initialOptions,
404
392
  platform: 'browser',
405
393
  write: false,
406
394
  bundle: true,
407
395
  metafile: true,
408
396
  format: 'esm',
409
- mainFields: ['es2020', 'es2015', 'browser', 'module', 'main'],
410
- logLevel: 'silent',
411
- sourcemap: pluginOptions.sourcemap,
412
397
  entryNames: 'worker-[hash]',
413
398
  entryPoints: [workerFile],
414
- absWorkingDir: build.initialOptions.absWorkingDir,
415
- outdir: build.initialOptions.outdir,
416
- minifyIdentifiers: build.initialOptions.minifyIdentifiers,
417
- minifySyntax: build.initialOptions.minifySyntax,
418
- minifyWhitespace: build.initialOptions.minifyWhitespace,
419
- target: build.initialOptions.target,
399
+ sourcemap: pluginOptions.sourcemap,
400
+ // Zone.js is not used in Web workers so no need to disable
401
+ supported: undefined,
402
+ // Plugins are not supported in sync esbuild calls
403
+ plugins: undefined,
420
404
  });
421
405
  }
422
406
  catch (error) {
@@ -26,9 +26,7 @@ export declare class ComponentStylesheetBundler {
26
26
  errors: import("esbuild").Message[] | undefined;
27
27
  warnings: import("esbuild").Message[];
28
28
  contents: string;
29
- map: string | undefined;
30
- path: string | undefined;
31
- resourceFiles: OutputFile[];
29
+ outputFiles: OutputFile[];
32
30
  metafile: import("esbuild").Metafile | undefined;
33
31
  referencedFiles: Set<string> | undefined;
34
32
  }>;
@@ -36,12 +34,11 @@ export declare class ComponentStylesheetBundler {
36
34
  errors: import("esbuild").Message[] | undefined;
37
35
  warnings: import("esbuild").Message[];
38
36
  contents: string;
39
- map: string | undefined;
40
- path: string | undefined;
41
- resourceFiles: OutputFile[];
37
+ outputFiles: OutputFile[];
42
38
  metafile: import("esbuild").Metafile | undefined;
43
39
  referencedFiles: Set<string> | undefined;
44
40
  }>;
45
41
  invalidate(files: Iterable<string>): void;
46
42
  dispose(): Promise<void>;
43
+ private extractResult;
47
44
  }
@@ -52,7 +52,7 @@ class ComponentStylesheetBundler {
52
52
  return buildOptions;
53
53
  });
54
54
  });
55
- return extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles);
55
+ return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles);
56
56
  }
57
57
  async bundleInline(data, filename, language) {
58
58
  // Use a hash of the inline stylesheet content to ensure a consistent identifier. External stylesheets will resolve
@@ -79,7 +79,7 @@ class ComponentStylesheetBundler {
79
79
  namespace,
80
80
  };
81
81
  });
82
- build.onLoad({ filter: /^css;/, namespace }, async () => {
82
+ build.onLoad({ filter: /^css;/, namespace }, () => {
83
83
  return {
84
84
  contents: data,
85
85
  loader: 'css',
@@ -92,7 +92,7 @@ class ComponentStylesheetBundler {
92
92
  });
93
93
  });
94
94
  // Extract the result of the bundling from the output files
95
- return extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles);
95
+ return this.extractResult(await bundlerContext.bundle(), bundlerContext.watchFiles);
96
96
  }
97
97
  invalidate(files) {
98
98
  if (!this.incremental) {
@@ -112,51 +112,46 @@ class ComponentStylesheetBundler {
112
112
  this.#inlineContexts.clear();
113
113
  await Promise.allSettled(contexts.map((context) => context.dispose()));
114
114
  }
115
- }
116
- exports.ComponentStylesheetBundler = ComponentStylesheetBundler;
117
- function extractResult(result, referencedFiles) {
118
- let contents = '';
119
- let map;
120
- let outputPath;
121
- const resourceFiles = [];
122
- if (!result.errors) {
123
- for (const outputFile of result.outputFiles) {
124
- const filename = node_path_1.default.basename(outputFile.path);
125
- if (outputFile.type === bundler_context_1.BuildOutputFileType.Media) {
126
- // The output files could also contain resources (images/fonts/etc.) that were referenced
127
- resourceFiles.push(outputFile);
128
- }
129
- else if (filename.endsWith('.css')) {
130
- outputPath = outputFile.path;
131
- contents = outputFile.text;
132
- }
133
- else if (filename.endsWith('.css.map')) {
134
- map = outputFile.text;
135
- }
136
- else {
137
- throw new Error(`Unexpected non CSS/Media file "${filename}" outputted during component stylesheet processing.`);
115
+ extractResult(result, referencedFiles) {
116
+ let contents = '';
117
+ let metafile;
118
+ const outputFiles = [];
119
+ if (!result.errors) {
120
+ for (const outputFile of result.outputFiles) {
121
+ const filename = node_path_1.default.basename(outputFile.path);
122
+ // Needed for Bazel as otherwise the files will not be written in the correct place.
123
+ outputFile.path = node_path_1.default.join(this.options.workspaceRoot, outputFile.path);
124
+ if (outputFile.type === bundler_context_1.BuildOutputFileType.Media) {
125
+ // The output files could also contain resources (images/fonts/etc.) that were referenced
126
+ outputFiles.push(outputFile);
127
+ }
128
+ else if (filename.endsWith('.css')) {
129
+ contents = outputFile.text;
130
+ }
131
+ else if (filename.endsWith('.css.map')) {
132
+ outputFiles.push(outputFile);
133
+ }
134
+ else {
135
+ throw new Error(`Unexpected non CSS/Media file "${filename}" outputted during component stylesheet processing.`);
136
+ }
138
137
  }
138
+ metafile = result.metafile;
139
+ // Remove entryPoint fields from outputs to prevent the internal component styles from being
140
+ // treated as initial files. Also mark the entry as a component resource for stat reporting.
141
+ Object.values(metafile.outputs).forEach((output) => {
142
+ delete output.entryPoint;
143
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
144
+ output['ng-component'] = true;
145
+ });
139
146
  }
147
+ return {
148
+ errors: result.errors,
149
+ warnings: result.warnings,
150
+ contents,
151
+ outputFiles,
152
+ metafile,
153
+ referencedFiles,
154
+ };
140
155
  }
141
- let metafile;
142
- if (!result.errors) {
143
- metafile = result.metafile;
144
- // Remove entryPoint fields from outputs to prevent the internal component styles from being
145
- // treated as initial files. Also mark the entry as a component resource for stat reporting.
146
- Object.values(metafile.outputs).forEach((output) => {
147
- delete output.entryPoint;
148
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
- output['ng-component'] = true;
150
- });
151
- }
152
- return {
153
- errors: result.errors,
154
- warnings: result.warnings,
155
- contents,
156
- map,
157
- path: outputPath,
158
- resourceFiles,
159
- metafile,
160
- referencedFiles,
161
- };
162
156
  }
157
+ exports.ComponentStylesheetBundler = ComponentStylesheetBundler;
@@ -6,6 +6,7 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import type { Metafile, OutputFile, PluginBuild } from 'esbuild';
9
+ import { LoadResultCache } from '../load-result-cache';
9
10
  import { ComponentStylesheetBundler } from './component-stylesheets';
10
11
  /**
11
12
  * Sets up esbuild resolve and load callbacks to support Angular JIT mode processing
@@ -19,4 +20,4 @@ import { ComponentStylesheetBundler } from './component-stylesheets';
19
20
  export declare function setupJitPluginCallbacks(build: PluginBuild, stylesheetBundler: ComponentStylesheetBundler, additionalResultFiles: Map<string, {
20
21
  outputFiles?: OutputFile[];
21
22
  metafile?: Metafile;
22
- }>, inlineStyleLanguage: string): void;
23
+ }>, inlineStyleLanguage: string, loadCache?: LoadResultCache): void;