@angular/build 19.1.4 → 19.1.6

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.
package/README.md CHANGED
@@ -2,4 +2,4 @@
2
2
 
3
3
  The sources for this package are in the [Angular CLI](https://github.com/angular/angular-cli) repository. Please file issues and pull requests against that repository.
4
4
 
5
- Usage information and reference details can be found in repository [README](../../../README.md) file.
5
+ Usage information and reference details can be found in repository [README](https://github.com/angular/angular-cli/blob/main/README.md) file.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/build",
3
- "version": "19.1.4",
3
+ "version": "19.1.6",
4
4
  "description": "Official build system for Angular",
5
5
  "keywords": [
6
6
  "Angular CLI",
@@ -23,7 +23,8 @@
23
23
  "builders": "builders.json",
24
24
  "dependencies": {
25
25
  "@ampproject/remapping": "2.3.0",
26
- "@angular-devkit/architect": "0.1901.4",
26
+ "@angular-devkit/core": "19.1.6",
27
+ "@angular-devkit/architect": "0.1901.6",
27
28
  "@babel/core": "7.26.0",
28
29
  "@babel/helper-annotate-as-pure": "7.25.9",
29
30
  "@babel/helper-split-export-declaration": "7.24.7",
@@ -45,7 +46,7 @@
45
46
  "rollup": "4.30.1",
46
47
  "sass": "1.83.1",
47
48
  "semver": "7.6.3",
48
- "vite": "6.0.7",
49
+ "vite": "6.0.11",
49
50
  "watchpack": "2.4.2"
50
51
  },
51
52
  "optionalDependencies": {
@@ -57,11 +58,11 @@
57
58
  "@angular/localize": "^19.0.0",
58
59
  "@angular/platform-server": "^19.0.0",
59
60
  "@angular/service-worker": "^19.0.0",
60
- "@angular/ssr": "^19.1.4",
61
+ "@angular/ssr": "^19.1.6",
61
62
  "less": "^4.2.0",
62
63
  "ng-packagr": "^19.0.0",
63
64
  "postcss": "^8.4.0",
64
- "tailwindcss": "^2.0.0 || ^3.0.0",
65
+ "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0",
65
66
  "typescript": ">=5.5 <5.8"
66
67
  },
67
68
  "peerDependenciesMeta": {
@@ -127,6 +127,9 @@ async function* runEsBuildBuildAction(action, options) {
127
127
  if (!watcher) {
128
128
  return;
129
129
  }
130
+ // Used to force a full result on next rebuild if there were initial errors.
131
+ // This ensures at least one full result is emitted.
132
+ let hasInitialErrors = result.errors.length > 0;
130
133
  // Wait for changes and rebuild as needed
131
134
  const currentWatchFiles = new Set(result.watchFiles);
132
135
  try {
@@ -164,9 +167,11 @@ async function* runEsBuildBuildAction(action, options) {
164
167
  if (staleWatchFiles?.size) {
165
168
  watcher.remove([...staleWatchFiles]);
166
169
  }
167
- for (const outputResult of emitOutputResults(result, outputOptions, changes, incrementalResults ? rebuildState : undefined)) {
170
+ for (const outputResult of emitOutputResults(result, outputOptions, changes, incrementalResults && !hasInitialErrors ? rebuildState : undefined)) {
168
171
  yield outputResult;
169
172
  }
173
+ // Clear initial build errors flag if no errors are now present
174
+ hasInitialErrors &&= result.errors.length > 0;
170
175
  }
171
176
  }
172
177
  finally {
@@ -239,6 +244,7 @@ function* emitOutputResults({ outputFiles, assetFiles, errors, warnings, externa
239
244
  outputOptions,
240
245
  },
241
246
  };
247
+ let hasCssUpdates = false;
242
248
  // Initially assume all previous output files have been removed
243
249
  const removedOutputFiles = new Map(previousOutputInfo);
244
250
  for (const file of outputFiles) {
@@ -254,8 +260,11 @@ function* emitOutputResults({ outputFiles, assetFiles, errors, warnings, externa
254
260
  incrementalResult.modified.push(file.path);
255
261
  }
256
262
  if (needFile) {
257
- // Updates to non-JS files must signal an update with the dev server
258
- if (!/(?:\.m?js|\.map)$/.test(file.path)) {
263
+ if (file.path.endsWith('.css')) {
264
+ hasCssUpdates = true;
265
+ }
266
+ else if (!/(?:\.m?js|\.map)$/.test(file.path)) {
267
+ // Updates to non-JS files must signal an update with the dev server
259
268
  incrementalResult.background = false;
260
269
  }
261
270
  incrementalResult.files[file.path] = {
@@ -281,12 +290,21 @@ function* emitOutputResults({ outputFiles, assetFiles, errors, warnings, externa
281
290
  else {
282
291
  continue;
283
292
  }
293
+ hasCssUpdates ||= destination.endsWith('.css');
284
294
  incrementalResult.files[destination] = {
285
295
  type: bundler_context_1.BuildOutputFileType.Browser,
286
296
  inputPath: source,
287
297
  origin: 'disk',
288
298
  };
289
299
  }
300
+ // Do not remove stale files yet if there are template updates.
301
+ // Component chunk files may still be referenced in running browser code.
302
+ // Module evaluation time component updates will update any of these files.
303
+ // This typically occurs when a lazy component is changed that has not yet
304
+ // been accessed at runtime.
305
+ if (hasTemplateUpdates && incrementalResult.background) {
306
+ removedOutputFiles.clear();
307
+ }
290
308
  // Include the removed output and asset files
291
309
  incrementalResult.removed.push(...Array.from(removedOutputFiles, ([file, { type }]) => ({
292
310
  path: file,
@@ -299,6 +317,17 @@ function* emitOutputResults({ outputFiles, assetFiles, errors, warnings, externa
299
317
  // If there are template updates and the incremental update was background only, a component
300
318
  // update is possible.
301
319
  if (hasTemplateUpdates && incrementalResult.background) {
320
+ // Template changes may be accompanied by stylesheet changes and these should also be updated hot when possible.
321
+ if (hasCssUpdates) {
322
+ const styleResult = {
323
+ kind: results_1.ResultKind.Incremental,
324
+ added: incrementalResult.added.filter(isCssFilePath),
325
+ removed: incrementalResult.removed.filter(({ path }) => isCssFilePath(path)),
326
+ modified: incrementalResult.modified.filter(isCssFilePath),
327
+ files: Object.fromEntries(Object.entries(incrementalResult.files).filter(([path]) => isCssFilePath(path))),
328
+ };
329
+ yield styleResult;
330
+ }
302
331
  const updateResult = {
303
332
  kind: results_1.ResultKind.ComponentUpdate,
304
333
  updates: Array.from(templateUpdates, ([id, content]) => ({
@@ -310,3 +339,6 @@ function* emitOutputResults({ outputFiles, assetFiles, errors, warnings, externa
310
339
  yield updateResult;
311
340
  }
312
341
  }
342
+ function isCssFilePath(filePath) {
343
+ return /\.css(?:\.map)?$/i.test(filePath);
344
+ }
@@ -38,7 +38,7 @@ async function executePostBundleSteps(metafile, options, outputFiles, assetFiles
38
38
  const allErrors = [];
39
39
  const allWarnings = [];
40
40
  const prerenderedRoutes = {};
41
- const { baseHref = '/', serviceWorker, i18nOptions, indexHtmlOptions, optimizationOptions, sourcemapOptions, outputMode, serverEntryPoint, prerenderOptions, appShellOptions, publicPath, workspaceRoot, partialSSRBuild, } = options;
41
+ const { baseHref = '/', serviceWorker, ssrOptions, indexHtmlOptions, optimizationOptions, sourcemapOptions, outputMode, serverEntryPoint, prerenderOptions, appShellOptions, publicPath, workspaceRoot, partialSSRBuild, } = options;
42
42
  // Index HTML content without CSS inlining to be used for server rendering (AppShell, SSG and SSR).
43
43
  // NOTE: Critical CSS inlining is deliberately omitted here, as it will be handled during server rendering.
44
44
  // Additionally, when using prerendering or AppShell, the index HTML file may be regenerated.
@@ -57,7 +57,7 @@ async function executePostBundleSteps(metafile, options, outputFiles, assetFiles
57
57
  }
58
58
  // Create server manifest
59
59
  const initialFilesPaths = new Set(initialFiles.keys());
60
- if (serverEntryPoint) {
60
+ if (serverEntryPoint && (outputMode || prerenderOptions || appShellOptions || ssrOptions)) {
61
61
  const { manifestContent, serverAssetsChunks } = (0, manifest_1.generateAngularServerAppManifest)(additionalHtmlOutputFiles, outputFiles, optimizationOptions.styles.inlineCritical ?? false, undefined, locale, baseHref, initialFilesPaths, metafile, publicPath);
62
62
  additionalOutputFiles.push(...serverAssetsChunks, (0, utils_1.createOutputFile)(manifest_1.SERVER_APP_MANIFEST_FILENAME, manifestContent, bundler_context_1.BuildOutputFileType.ServerApplication));
63
63
  }
@@ -44,4 +44,5 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
44
44
  host?: string;
45
45
  port?: number;
46
46
  };
47
+ allowedHosts: true | string[];
47
48
  }>;
@@ -73,7 +73,7 @@ async function normalizeOptions(context, projectName, options) {
73
73
  }
74
74
  }
75
75
  // Initial options to keep
76
- const { host, port, poll, open, verbose, watch, liveReload, hmr, headers, proxyConfig, servePath, ssl, sslCert, sslKey, prebundle, } = options;
76
+ const { host, port, poll, open, verbose, watch, liveReload, hmr, headers, proxyConfig, servePath, ssl, sslCert, sslKey, prebundle, allowedHosts, } = options;
77
77
  // Return all the normalized options
78
78
  return {
79
79
  buildTarget,
@@ -97,5 +97,6 @@ async function normalizeOptions(context, projectName, options) {
97
97
  // Prebundling defaults to true but requires caching to function
98
98
  prebundle: cacheOptions.enabled && !optimization.scripts && prebundle,
99
99
  inspect,
100
+ allowedHosts: allowedHosts ? allowedHosts : [],
100
101
  };
101
102
  }
@@ -2,6 +2,12 @@
2
2
  * Dev Server target options for Build Facade.
3
3
  */
4
4
  export type Schema = {
5
+ /**
6
+ * The hosts that can access the development server. This option sets the Vite option of the
7
+ * same name. For further details:
8
+ * https://vite.dev/config/server-options.html#server-allowedhosts
9
+ */
10
+ allowedHosts?: AllowedHosts;
5
11
  /**
6
12
  * A build builder target to serve in the format of `project:target[:configuration]`. You
7
13
  * can also pass in more than one configuration name as a comma-separated list. Example:
@@ -79,6 +85,12 @@ export type Schema = {
79
85
  */
80
86
  watch?: boolean;
81
87
  };
88
+ /**
89
+ * The hosts that can access the development server. This option sets the Vite option of the
90
+ * same name. For further details:
91
+ * https://vite.dev/config/server-options.html#server-allowedhosts
92
+ */
93
+ export type AllowedHosts = string[] | boolean;
82
94
  /**
83
95
  * Activate debugging inspector. This option only has an effect when 'SSR' or 'SSG' are
84
96
  * enabled.
@@ -36,6 +36,23 @@
36
36
  "type": "string",
37
37
  "description": "SSL certificate to use for serving HTTPS."
38
38
  },
39
+ "allowedHosts": {
40
+ "description": "The hosts that can access the development server. This option sets the Vite option of the same name. For further details: https://vite.dev/config/server-options.html#server-allowedhosts",
41
+ "default": [],
42
+ "oneOf": [
43
+ {
44
+ "type": "array",
45
+ "description": "List of hosts that are allowed to access the development server.",
46
+ "items": {
47
+ "type": "string"
48
+ }
49
+ },
50
+ {
51
+ "type": "boolean",
52
+ "description": "Indicates that all hosts are allowed. This is not recommended and a security risk."
53
+ }
54
+ ]
55
+ },
39
56
  "headers": {
40
57
  "type": "object",
41
58
  "description": "Custom HTTP headers to be added to all responses.",
@@ -161,6 +161,7 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
161
161
  },
162
162
  });
163
163
  }
164
+ yield { baseUrl: '', success: false };
164
165
  continue;
165
166
  }
166
167
  // Clear existing error overlay on successful result
@@ -304,6 +305,46 @@ async function* serveWithVite(serverOptions, builderName, builderAction, context
304
305
  const serverConfiguration = await setupServer(serverOptions, generatedFiles, assetFiles, browserOptions.preserveSymlinks, externalMetadata, ssrMode, prebundleTransformer, target, (0, internal_1.isZonelessApp)(polyfills), componentStyles, templateUpdates, browserOptions.loader, browserOptions.define, extensions?.middleware, transformers?.indexHtml, thirdPartySourcemaps);
305
306
  server = await createServer(serverConfiguration);
306
307
  await server.listen();
308
+ // Setup builder context logging for browser clients
309
+ server.hot.on('angular:log', (data) => {
310
+ if (typeof data?.text !== 'string') {
311
+ context.logger.warn('Development server client sent invalid internal log event.');
312
+ }
313
+ switch (data.kind) {
314
+ case 'error':
315
+ context.logger.error(`[CLIENT ERROR]: ${data.text}`);
316
+ break;
317
+ case 'warning':
318
+ context.logger.warn(`[CLIENT WARNING]: ${data.text}`);
319
+ break;
320
+ default:
321
+ context.logger.info(`[CLIENT INFO]: ${data.text}`);
322
+ break;
323
+ }
324
+ });
325
+ // Setup component HMR invalidation
326
+ // Invalidation occurs when the runtime cannot update a component
327
+ server.hot.on('angular:invalidate', (data) => {
328
+ if (typeof data?.id !== 'string') {
329
+ context.logger.warn('Development server client sent invalid internal invalidate event.');
330
+ }
331
+ // Clear invalid template update
332
+ templateUpdates.delete(data.id);
333
+ // Some cases are expected unsupported update scenarios but some may be errors.
334
+ // If an error occurred, log the error in addition to the invalidation.
335
+ if (data.error) {
336
+ context.logger.error(`Component update failed${data.message ? `: ${data.message}` : '.'}` +
337
+ '\nPlease consider reporting the error at https://github.com/angular/angular-cli/issues');
338
+ }
339
+ else {
340
+ context.logger.warn(`Component update unsupported${data.message ? `: ${data.message}` : '.'}`);
341
+ }
342
+ server?.ws.send({
343
+ type: 'full-reload',
344
+ path: '*',
345
+ });
346
+ context.logger.info('Page reload sent to client(s).');
347
+ });
307
348
  const urls = server.resolvedUrls;
308
349
  if (urls && (urls.local.length || urls.network.length)) {
309
350
  serverUrl = new URL(urls.local[0] ?? urls.network[0]);
@@ -353,26 +394,22 @@ async function invalidateUpdatedFiles(normalizePath, generatedFiles, assetFiles,
353
394
  updatedFiles.push(file);
354
395
  }
355
396
  // Invalidate any updated files
356
- let destroyAngularServerAppCalled = false;
397
+ let serverApplicationChanged = false;
357
398
  for (const [file, record] of generatedFiles) {
358
399
  if (!record.updated) {
359
400
  continue;
360
401
  }
361
402
  record.updated = false;
362
- if (record.type === internal_1.BuildOutputFileType.ServerApplication && !destroyAngularServerAppCalled) {
363
- // Clear the server app cache
364
- // This must be done before module invalidation.
365
- const { ɵdestroyAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs'));
366
- ɵdestroyAngularServerApp();
367
- destroyAngularServerAppCalled = true;
368
- }
369
403
  updatedFiles.push(file);
404
+ serverApplicationChanged ||= record.type === internal_1.BuildOutputFileType.ServerApplication;
370
405
  const updatedModules = server.moduleGraph.getModulesByFile(normalizePath((0, node_path_1.join)(server.config.root, file)));
371
406
  updatedModules?.forEach((m) => server.moduleGraph.invalidateModule(m));
372
407
  }
373
- if (destroyAngularServerAppCalled) {
374
- // Trigger module evaluation before reload to initiate dependency optimization.
375
- await server.ssrLoadModule('/main.server.mjs');
408
+ if (serverApplicationChanged) {
409
+ // Clear the server app cache and
410
+ // trigger module evaluation before reload to initiate dependency optimization.
411
+ const { ɵdestroyAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs'));
412
+ ɵdestroyAngularServerApp();
376
413
  }
377
414
  return updatedFiles;
378
415
  }
@@ -424,7 +461,7 @@ function handleUpdate(server, serverOptions, logger, componentStyles, updatedFil
424
461
  type: 'update',
425
462
  updates,
426
463
  });
427
- logger.info('HMR update sent to client(s).');
464
+ logger.info('Stylesheet update sent to client(s).');
428
465
  return;
429
466
  }
430
467
  }
@@ -537,6 +574,14 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
537
574
  mainFields: ['es2020', 'browser', 'module', 'main'],
538
575
  preserveSymlinks,
539
576
  },
577
+ dev: {
578
+ // This is needed when `externalDependencies` is used to prevent Vite load errors.
579
+ // NOTE: If Vite adds direct support for externals, this can be removed.
580
+ // NOTE: Vite breaks the resolution of browser modules in SSR
581
+ // when accessing a url with two or more segments (e.g., 'foo/bar'),
582
+ // as they are not re-based from the base href.
583
+ preTransformRequests: externalMetadata.explicitBrowser.length === 0 && ssrMode === plugins_1.ServerSsrMode.NoSsr,
584
+ },
540
585
  server: {
541
586
  warmup: {
542
587
  ssrFiles,
@@ -545,6 +590,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
545
590
  strictPort: true,
546
591
  host: serverOptions.host,
547
592
  open: serverOptions.open,
593
+ allowedHosts: serverOptions.allowedHosts,
548
594
  headers: serverOptions.headers,
549
595
  // Disable the websocket if live reload is disabled (false/undefined are the only valid values)
550
596
  ws: serverOptions.liveReload === false && serverOptions.hmr === false ? false : undefined,
@@ -573,9 +619,6 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
573
619
  ...[...assets.values()].map(({ source }) => source),
574
620
  ],
575
621
  },
576
- // This is needed when `externalDependencies` is used to prevent Vite load errors.
577
- // NOTE: If Vite adds direct support for externals, this can be removed.
578
- preTransformRequests: externalMetadata.explicitBrowser.length === 0,
579
622
  },
580
623
  ssr: {
581
624
  // Note: `true` and `/.*/` have different sematics. When true, the `external` option is ignored.
@@ -80,6 +80,9 @@ class AngularCompilation {
80
80
  enableResourceInlining: false,
81
81
  supportTestBed: false,
82
82
  supportJitMode: false,
83
+ // Disable removing of comments as TS is quite aggressive with these and can
84
+ // remove important annotations, such as /* @__PURE__ */ and comments like /* vite-ignore */.
85
+ removeComments: false,
83
86
  }));
84
87
  }
85
88
  async diagnoseFiles(modes = DiagnosticModes.All) {
@@ -22,6 +22,10 @@ function createAngularSsrInternalMiddleware(server, indexHtmlTransformer) {
22
22
  // which must be processed by the runtime linker, even if they are not used.
23
23
  await (0, load_esm_1.loadEsmModule)('@angular/compiler');
24
24
  const { writeResponseToNodeResponse, createWebRequestFromNodeRequest } = await (0, load_esm_1.loadEsmModule)('@angular/ssr/node');
25
+ // The following is necessary because accessing the module after invalidation may result in an empty module,
26
+ // which can trigger a `TypeError: ɵgetOrCreateAngularServerApp is not a function` error.
27
+ // TODO: look into why.
28
+ await server.ssrLoadModule('/main.server.mjs');
25
29
  const { ɵgetOrCreateAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs'));
26
30
  const angularServerApp = ɵgetOrCreateAngularServerApp({
27
31
  allowStaticRouteRender: true,
@@ -47,24 +47,13 @@ async function createAngularMemoryPlugin(options) {
47
47
  // `/@id/${source}` but is currently closer to a raw external than a resolved file path.
48
48
  return source;
49
49
  }
50
- if (importer) {
50
+ if (importer && source[0] === '.') {
51
51
  const normalizedImporter = normalizePath(importer);
52
- if (source[0] === '.' && normalizedImporter.startsWith(virtualProjectRoot)) {
52
+ if (normalizedImporter.startsWith(virtualProjectRoot)) {
53
53
  // Remove query if present
54
54
  const [importerFile] = normalizedImporter.split('?', 1);
55
55
  source = '/' + (0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.relative)(virtualProjectRoot, importerFile)), source);
56
56
  }
57
- else if (!ssr &&
58
- source[0] === '/' &&
59
- importer.endsWith('index.html') &&
60
- normalizedImporter.startsWith(virtualProjectRoot)) {
61
- // This is only needed when using SSR and `angularSsrMiddleware` (old style) to correctly resolve
62
- // .js files when using lazy-loading.
63
- // Remove query if present
64
- const [importerFile] = normalizedImporter.split('?', 1);
65
- source =
66
- '/' + (0, node_path_1.join)((0, node_path_1.dirname)((0, node_path_1.relative)(virtualProjectRoot, importerFile)), (0, node_path_1.basename)(source));
67
- }
68
57
  }
69
58
  const [file] = source.split('?', 1);
70
59
  if (outputFiles.has(normalizePath(file))) {
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.normalizeCacheOptions = normalizeCacheOptions;
11
11
  const node_path_1 = require("node:path");
12
12
  /** Version placeholder is replaced during the build process with actual package version */
13
- const VERSION = '19.1.4';
13
+ const VERSION = '19.1.6';
14
14
  function hasCacheMetadata(value) {
15
15
  return (!!value &&
16
16
  typeof value === 'object' &&
@@ -9,7 +9,7 @@ import type { Config, Filesystem } from '@angular/service-worker/config';
9
9
  import { promises as fsPromises } from 'node:fs';
10
10
  import { BuildOutputFile } from '../tools/esbuild/bundler-context';
11
11
  import { BuildOutputAsset } from '../tools/esbuild/bundler-execution-result';
12
- export declare function augmentAppWithServiceWorker(appRoot: string, workspaceRoot: string, outputPath: string, baseHref: string, ngswConfigPath?: string, inputputFileSystem?: typeof fsPromises, outputFileSystem?: typeof fsPromises): Promise<void>;
12
+ export declare function augmentAppWithServiceWorker(appRoot: string, workspaceRoot: string, outputPath: string, baseHref: string, ngswConfigPath?: string, inputFileSystem?: typeof fsPromises, outputFileSystem?: typeof fsPromises): Promise<void>;
13
13
  export declare function augmentAppWithServiceWorkerEsbuild(workspaceRoot: string, configPath: string, baseHref: string, indexHtml: string | undefined, outputFiles: BuildOutputFile[], assetFiles: BuildOutputAsset[]): Promise<{
14
14
  manifest: string;
15
15
  assetFiles: BuildOutputAsset[];
@@ -133,7 +133,7 @@ class ResultFilesystem {
133
133
  throw new Error('Serviceworker manifest generator should not attempted to write.');
134
134
  }
135
135
  }
136
- async function augmentAppWithServiceWorker(appRoot, workspaceRoot, outputPath, baseHref, ngswConfigPath, inputputFileSystem = node_fs_1.promises, outputFileSystem = node_fs_1.promises) {
136
+ async function augmentAppWithServiceWorker(appRoot, workspaceRoot, outputPath, baseHref, ngswConfigPath, inputFileSystem = node_fs_1.promises, outputFileSystem = node_fs_1.promises) {
137
137
  // Determine the configuration file path
138
138
  const configPath = ngswConfigPath
139
139
  ? path.join(workspaceRoot, ngswConfigPath)
@@ -141,7 +141,7 @@ async function augmentAppWithServiceWorker(appRoot, workspaceRoot, outputPath, b
141
141
  // Read the configuration file
142
142
  let config;
143
143
  try {
144
- const configurationData = await inputputFileSystem.readFile(configPath, 'utf-8');
144
+ const configurationData = await inputFileSystem.readFile(configPath, 'utf-8');
145
145
  config = JSON.parse(configurationData);
146
146
  }
147
147
  catch (error) {
@@ -158,11 +158,7 @@ async function augmentAppWithServiceWorker(appRoot, workspaceRoot, outputPath, b
158
158
  const result = await augmentAppWithServiceWorkerCore(config, new CliFilesystem(outputFileSystem, outputPath), baseHref);
159
159
  const copy = async (src, dest) => {
160
160
  const resolvedDest = path.join(outputPath, dest);
161
- return inputputFileSystem === outputFileSystem
162
- ? // Native FS (Builder).
163
- inputputFileSystem.copyFile(src, resolvedDest, node_fs_1.constants.COPYFILE_FICLONE)
164
- : // memfs (Webpack): Read the file from the input FS (disk) and write it to the output FS (memory).
165
- outputFileSystem.writeFile(resolvedDest, await inputputFileSystem.readFile(src));
161
+ return outputFileSystem.writeFile(resolvedDest, await inputFileSystem.readFile(src));
166
162
  };
167
163
  await outputFileSystem.writeFile(path.join(outputPath, 'ngsw.json'), result.manifest);
168
164
  for (const { source, destination } of result.assetFiles) {