@angular-devkit/build-angular 17.1.1 → 17.1.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.
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@angular-devkit/build-angular",
3
- "version": "17.1.1",
3
+ "version": "17.1.3",
4
4
  "description": "Angular Webpack Build Facade",
5
5
  "main": "src/index.js",
6
6
  "typings": "src/index.d.ts",
7
7
  "builders": "builders.json",
8
8
  "dependencies": {
9
9
  "@ampproject/remapping": "2.2.1",
10
- "@angular-devkit/architect": "0.1701.1",
11
- "@angular-devkit/build-webpack": "0.1701.1",
12
- "@angular-devkit/core": "17.1.1",
10
+ "@angular-devkit/architect": "0.1701.3",
11
+ "@angular-devkit/build-webpack": "0.1701.3",
12
+ "@angular-devkit/core": "17.1.3",
13
13
  "@babel/core": "7.23.7",
14
14
  "@babel/generator": "7.23.6",
15
15
  "@babel/helper-annotate-as-pure": "7.22.5",
@@ -20,7 +20,7 @@
20
20
  "@babel/preset-env": "7.23.7",
21
21
  "@babel/runtime": "7.23.7",
22
22
  "@discoveryjs/json-ext": "0.5.7",
23
- "@ngtools/webpack": "17.1.1",
23
+ "@ngtools/webpack": "17.1.3",
24
24
  "@vitejs/plugin-basic-ssl": "1.0.2",
25
25
  "ansi-colors": "4.1.3",
26
26
  "autoprefixer": "10.4.16",
@@ -70,7 +70,7 @@ async function normalizeOptions(context, projectName, options, extensions) {
70
70
  server: 'server',
71
71
  media: 'media',
72
72
  ...(typeof outputPath === 'string' ? undefined : outputPath),
73
- base: normalizeDirectoryPath(node_path_1.default.join(workspaceRoot, typeof outputPath === 'string' ? outputPath : outputPath.base)),
73
+ base: normalizeDirectoryPath(node_path_1.default.resolve(workspaceRoot, typeof outputPath === 'string' ? outputPath : outputPath.base)),
74
74
  };
75
75
  const outputNames = {
76
76
  bundles: options.outputHashing === schema_1.OutputHashing.All || options.outputHashing === schema_1.OutputHashing.Bundles
@@ -66,7 +66,6 @@ async function* serveWithVite(serverOptions, builderName, context, transformers,
66
66
  // Avoid bundling and processing the ssr entry-point as this is not used by the dev-server.
67
67
  browserOptions.ssr = true;
68
68
  // https://nodejs.org/api/process.html#processsetsourcemapsenabledval
69
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
69
  process.setSourceMapsEnabled(true);
71
70
  }
72
71
  // Set all packages as external to support Vite's prebundle caching
@@ -75,7 +74,7 @@ async function* serveWithVite(serverOptions, builderName, context, transformers,
75
74
  if (serverOptions.servePath === undefined && baseHref !== undefined) {
76
75
  // Remove trailing slash
77
76
  serverOptions.servePath =
78
- baseHref[baseHref.length - 1] === '/' ? baseHref.slice(0, -1) : baseHref;
77
+ baseHref !== './' && baseHref[baseHref.length - 1] === '/' ? baseHref.slice(0, -1) : baseHref;
79
78
  }
80
79
  // The development server currently only supports a single locale when localizing.
81
80
  // This matches the behavior of the Webpack-based development server but could be expanded in the future.
@@ -341,7 +340,7 @@ async function setupServer(serverOptions, outputFiles, assets, preserveSymlinks,
341
340
  publicDir: false,
342
341
  esbuild: false,
343
342
  mode: 'development',
344
- appType: 'spa',
343
+ appType: 'mpa',
345
344
  css: {
346
345
  devSourcemap: true,
347
346
  },
@@ -20,9 +20,11 @@ async function extractMessages(options, builderName, context, extractorConstruct
20
20
  // Setup the build options for the application based on the buildTarget option
21
21
  const buildOptions = (await context.validateOptions(await context.getTargetOptions(options.buildTarget), builderName));
22
22
  buildOptions.optimization = false;
23
- buildOptions.sourceMap = { scripts: true, vendor: true };
23
+ buildOptions.sourceMap = { scripts: true, vendor: true, styles: false };
24
24
  buildOptions.localize = false;
25
25
  buildOptions.budgets = undefined;
26
+ buildOptions.index = false;
27
+ buildOptions.serviceWorker = false;
26
28
  let build;
27
29
  if (builderName === '@angular-devkit/build-angular:application') {
28
30
  build = application_1.buildApplicationInternal;
@@ -162,7 +162,7 @@ function createCompilerPlugin(pluginOptions, styleOptions) {
162
162
  });
163
163
  referencedFileTracker.add(containingFile, Object.keys(workerResult.metafile.inputs).map((input) => path.join(build.initialOptions.absWorkingDir ?? '', input)));
164
164
  // Return bundled worker file entry name to be used in the built output
165
- const workerCodeFile = workerResult.outputFiles.find((file) => file.path.endsWith('.js'));
165
+ const workerCodeFile = workerResult.outputFiles.find((file) => /^worker-[A-Z0-9]{8}.[cm]?js$/.test(path.basename(file.path)));
166
166
  (0, node_assert_1.default)(workerCodeFile, 'Web Worker bundled code file should always be present.');
167
167
  const workerCodePath = path.relative(build.initialOptions.outdir ?? '', workerCodeFile.path);
168
168
  return workerCodePath.replaceAll('\\', '/');
@@ -260,7 +260,9 @@ class BundlerContext {
260
260
  for (const { imports } of Object.values(result.metafile.outputs)) {
261
261
  for (const importData of imports) {
262
262
  if (!importData.external ||
263
- (importData.kind !== 'import-statement' && importData.kind !== 'dynamic-import')) {
263
+ (importData.kind !== 'import-statement' &&
264
+ importData.kind !== 'dynamic-import' &&
265
+ importData.kind !== 'require-call')) {
264
266
  continue;
265
267
  }
266
268
  externalImports.add(importData.path);
@@ -61,6 +61,7 @@ function createAngularMemoryPlugin(options) {
61
61
  map: mapContents && Buffer.from(mapContents).toString('utf-8'),
62
62
  };
63
63
  },
64
+ // eslint-disable-next-line max-lines-per-function
64
65
  configureServer(server) {
65
66
  const originalssrTransform = server.ssrTransform;
66
67
  server.ssrTransform = async (code, map, url, originalCode) => {
@@ -124,14 +125,15 @@ function createAngularMemoryPlugin(options) {
124
125
  // Returning a function, installs middleware after the main transform middleware but
125
126
  // before the built-in HTML middleware
126
127
  return () => {
128
+ server.middlewares.use(angularHtmlFallbackMiddleware);
127
129
  function angularSSRMiddleware(req, res, next) {
128
130
  const url = req.originalUrl;
129
131
  if (!req.url ||
130
132
  // Skip if path is not defined.
131
133
  !url ||
132
134
  // Skip if path is like a file.
133
- // NOTE: We use a regexp to mitigate against matching requests like: /browse/pl.0ef59752c0cd457dbf1391f08cbd936f
134
- /^\.[a-z]{2,4}$/i.test((0, node_path_1.extname)(url.split('?')[0]))) {
135
+ // NOTE: We use a mime type lookup to mitigate against matching requests like: /browse/pl.0ef59752c0cd457dbf1391f08cbd936f
136
+ lookupMimeTypeFromRequest(url)) {
135
137
  next();
136
138
  return;
137
139
  }
@@ -227,3 +229,23 @@ function pathnameWithoutBasePath(url, basePath) {
227
229
  ? pathname.slice(basePath.length - 1)
228
230
  : pathname;
229
231
  }
232
+ function angularHtmlFallbackMiddleware(req, res, next) {
233
+ // Similar to how it is handled in vite
234
+ // https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L15C19-L15C45
235
+ if ((req.method === 'GET' || req.method === 'HEAD') &&
236
+ (!req.url || !lookupMimeTypeFromRequest(req.url)) &&
237
+ (!req.headers.accept ||
238
+ req.headers.accept.includes('text/html') ||
239
+ req.headers.accept.includes('text/*') ||
240
+ req.headers.accept.includes('*/*'))) {
241
+ req.url = '/index.html';
242
+ }
243
+ next();
244
+ }
245
+ function lookupMimeTypeFromRequest(url) {
246
+ const extension = (0, node_path_1.extname)(url.split('?')[0]);
247
+ if (extension === '.ico') {
248
+ return 'image/x-icon';
249
+ }
250
+ return extension && (0, mrmime_1.lookup)(extension);
251
+ }
@@ -135,9 +135,9 @@ function normalizeProxyConfiguration(proxy) {
135
135
  }
136
136
  // TODO: Consider upstreaming glob support
137
137
  for (const key of Object.keys(normalizedProxy)) {
138
- if ((0, fast_glob_1.isDynamicPattern)(key)) {
139
- const { output } = (0, picomatch_1.parse)(key);
140
- normalizedProxy[`^${output}$`] = normalizedProxy[key];
138
+ if (key[0] !== '^' && (0, fast_glob_1.isDynamicPattern)(key)) {
139
+ const pattern = (0, picomatch_1.makeRe)(key).source;
140
+ normalizedProxy[pattern] = normalizedProxy[key];
141
141
  delete normalizedProxy[key];
142
142
  }
143
143
  }