@angular/build 18.1.0-rc.0 → 18.1.0

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 (40) hide show
  1. package/package.json +11 -9
  2. package/src/builders/application/chunk-optimizer.d.ts +9 -0
  3. package/src/builders/application/chunk-optimizer.js +169 -0
  4. package/src/builders/application/execute-build.js +9 -3
  5. package/src/builders/application/execute-post-bundle.js +4 -4
  6. package/src/builders/dev-server/vite-server.js +0 -1
  7. package/src/tools/angular/compilation/aot-compilation.js +3 -1
  8. package/src/tools/angular/compilation/parallel-worker.d.ts +1 -0
  9. package/src/tools/angular/compilation/parallel-worker.js +2 -1
  10. package/src/tools/esbuild/angular/compiler-plugin.js +3 -1
  11. package/src/tools/esbuild/application-code-bundle.js +7 -2
  12. package/src/tools/esbuild/budget-stats.d.ts +2 -2
  13. package/src/tools/esbuild/budget-stats.js +19 -14
  14. package/src/tools/esbuild/bundler-context.d.ts +1 -0
  15. package/src/tools/esbuild/bundler-execution-result.d.ts +1 -1
  16. package/src/tools/esbuild/bundler-execution-result.js +1 -1
  17. package/src/tools/esbuild/i18n-inliner.js +2 -2
  18. package/src/tools/esbuild/javascript-transformer-worker.js +3 -1
  19. package/src/tools/esbuild/utils.d.ts +4 -3
  20. package/src/tools/esbuild/utils.js +97 -56
  21. package/src/tools/esbuild/wasm-plugin.d.ts +28 -0
  22. package/src/tools/esbuild/wasm-plugin.js +210 -0
  23. package/src/tools/esbuild/wasm.d.ts +25 -0
  24. package/src/tools/vite/angular-memory-plugin.d.ts +2 -5
  25. package/src/tools/vite/angular-memory-plugin.js +7 -161
  26. package/src/tools/vite/middlewares/assets-middleware.d.ts +10 -0
  27. package/src/tools/vite/middlewares/assets-middleware.js +94 -0
  28. package/src/tools/vite/middlewares/html-fallback-middleware.d.ts +10 -0
  29. package/src/tools/vite/middlewares/html-fallback-middleware.js +24 -0
  30. package/src/tools/vite/middlewares/index-html-middleware.d.ts +10 -0
  31. package/src/tools/vite/middlewares/index-html-middleware.js +43 -0
  32. package/src/tools/vite/middlewares/index.d.ts +11 -0
  33. package/src/tools/vite/middlewares/index.js +18 -0
  34. package/src/tools/vite/middlewares/ssr-middleware.d.ts +12 -0
  35. package/src/tools/vite/middlewares/ssr-middleware.js +57 -0
  36. package/src/tools/vite/utils.d.ts +16 -0
  37. package/src/tools/vite/utils.js +40 -0
  38. package/src/utils/environment-options.d.ts +1 -0
  39. package/src/utils/environment-options.js +4 -2
  40. package/src/utils/normalize-cache.js +1 -1
@@ -11,20 +11,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.logBuildStats = logBuildStats;
14
+ exports.getChunkNameFromMetafile = getChunkNameFromMetafile;
14
15
  exports.calculateEstimatedTransferSizes = calculateEstimatedTransferSizes;
15
16
  exports.withSpinner = withSpinner;
16
17
  exports.withNoProgress = withNoProgress;
17
18
  exports.getFeatureSupport = getFeatureSupport;
18
19
  exports.writeResultFiles = writeResultFiles;
19
20
  exports.emitFilesToDisk = emitFilesToDisk;
20
- exports.createOutputFileFromText = createOutputFileFromText;
21
- exports.createOutputFileFromData = createOutputFileFromData;
21
+ exports.createOutputFile = createOutputFile;
22
22
  exports.convertOutputFile = convertOutputFile;
23
23
  exports.transformSupportedBrowsersToTargets = transformSupportedBrowsersToTargets;
24
24
  exports.getSupportedNodeTargets = getSupportedNodeTargets;
25
25
  exports.createJsonBuildManifest = createJsonBuildManifest;
26
26
  exports.logMessages = logMessages;
27
27
  exports.isZonelessApp = isZonelessApp;
28
+ exports.getEntryPointName = getEntryPointName;
28
29
  const esbuild_1 = require("esbuild");
29
30
  const node_crypto_1 = require("node:crypto");
30
31
  const node_fs_1 = require("node:fs");
@@ -36,40 +37,29 @@ const semver_1 = require("semver");
36
37
  const spinner_1 = require("../../utils/spinner");
37
38
  const stats_table_1 = require("../../utils/stats-table");
38
39
  const bundler_context_1 = require("./bundler-context");
39
- function logBuildStats(metafile, initial, budgetFailures, colors, changedFiles, estimatedTransferSizes, ssrOutputEnabled, verbose) {
40
+ function logBuildStats(metafile, outputFiles, initial, budgetFailures, colors, changedFiles, estimatedTransferSizes, ssrOutputEnabled, verbose) {
40
41
  const browserStats = [];
41
42
  const serverStats = [];
42
43
  let unchangedCount = 0;
43
- for (const [file, output] of Object.entries(metafile.outputs)) {
44
+ for (const { path: file, size, type } of outputFiles) {
44
45
  // Only display JavaScript and CSS files
45
46
  if (!/\.(?:css|m?js)$/.test(file)) {
46
47
  continue;
47
48
  }
48
- // Skip internal component resources
49
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
- if (output['ng-component']) {
51
- continue;
52
- }
53
49
  // Show only changed files if a changed list is provided
54
50
  if (changedFiles && !changedFiles.has(file)) {
55
51
  ++unchangedCount;
56
52
  continue;
57
53
  }
58
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
- const isPlatformServer = output['ng-platform-server'];
54
+ const isPlatformServer = type === bundler_context_1.BuildOutputFileType.Server;
60
55
  if (isPlatformServer && !ssrOutputEnabled) {
61
56
  // Only log server build stats when SSR is enabled.
62
57
  continue;
63
58
  }
64
- let name = initial.get(file)?.name;
65
- if (name === undefined && output.entryPoint) {
66
- name = (0, node_path_1.basename)(output.entryPoint)
67
- .replace(/\.[cm]?[jt]s$/, '')
68
- .replace(/[\\/.]/g, '-');
69
- }
59
+ const name = initial.get(file)?.name ?? getChunkNameFromMetafile(metafile, file);
70
60
  const stat = {
71
61
  initial: initial.has(file),
72
- stats: [file, name ?? '-', output.bytes, estimatedTransferSizes?.get(file) ?? '-'],
62
+ stats: [file, name ?? '-', size, estimatedTransferSizes?.get(file) ?? '-'],
73
63
  };
74
64
  if (isPlatformServer) {
75
65
  serverStats.push(stat);
@@ -90,6 +80,11 @@ function logBuildStats(metafile, initial, budgetFailures, colors, changedFiles,
90
80
  }
91
81
  return '';
92
82
  }
83
+ function getChunkNameFromMetafile(metafile, file) {
84
+ if (metafile.outputs[file]?.entryPoint) {
85
+ return getEntryPointName(metafile.outputs[file].entryPoint);
86
+ }
87
+ }
93
88
  async function calculateEstimatedTransferSizes(outputFiles) {
94
89
  const sizes = new Map();
95
90
  if (outputFiles.length <= 0) {
@@ -158,8 +153,6 @@ function getFeatureSupport(target, nativeAsyncAwait) {
158
153
  // will be used instead which provides a workaround for the performance issue.
159
154
  // For more details: https://bugs.chromium.org/p/v8/issues/detail?id=11536
160
155
  'object-rest-spread': false,
161
- // Using top-level-await is not guaranteed to be safe with some code optimizations.
162
- 'top-level-await': false,
163
156
  };
164
157
  // Detect Safari browser versions that have a class field behavior bug
165
158
  // See: https://github.com/angular/angular-cli/issues/24355#issuecomment-1333477033
@@ -245,49 +238,91 @@ async function emitFilesToDisk(files, writeFileCallback) {
245
238
  await Promise.all(actions);
246
239
  }
247
240
  }
248
- function createOutputFileFromText(path, text, type) {
249
- return {
250
- path,
251
- text,
252
- type,
253
- get hash() {
254
- return (0, node_crypto_1.createHash)('sha256').update(this.text).digest('hex');
255
- },
256
- get contents() {
257
- return Buffer.from(this.text, 'utf-8');
258
- },
259
- clone() {
260
- return createOutputFileFromText(this.path, this.text, this.type);
261
- },
262
- };
241
+ function createOutputFile(path, data, type) {
242
+ if (typeof data === 'string') {
243
+ let cachedContents = null;
244
+ let cachedText = data;
245
+ let cachedHash = null;
246
+ return {
247
+ path,
248
+ type,
249
+ get contents() {
250
+ cachedContents ??= new TextEncoder().encode(data);
251
+ return cachedContents;
252
+ },
253
+ set contents(value) {
254
+ cachedContents = value;
255
+ cachedText = null;
256
+ },
257
+ get text() {
258
+ cachedText ??= new TextDecoder('utf-8').decode(this.contents);
259
+ return cachedText;
260
+ },
261
+ get size() {
262
+ return this.contents.byteLength;
263
+ },
264
+ get hash() {
265
+ cachedHash ??= (0, node_crypto_1.createHash)('sha256')
266
+ .update(cachedText ?? this.contents)
267
+ .digest('hex');
268
+ return cachedHash;
269
+ },
270
+ clone() {
271
+ return createOutputFile(this.path, cachedText ?? this.contents, this.type);
272
+ },
273
+ };
274
+ }
275
+ else {
276
+ let cachedContents = data;
277
+ let cachedText = null;
278
+ let cachedHash = null;
279
+ return {
280
+ get contents() {
281
+ return cachedContents;
282
+ },
283
+ set contents(value) {
284
+ cachedContents = value;
285
+ cachedText = null;
286
+ },
287
+ path,
288
+ type,
289
+ get size() {
290
+ return this.contents.byteLength;
291
+ },
292
+ get text() {
293
+ cachedText ??= new TextDecoder('utf-8').decode(this.contents);
294
+ return cachedText;
295
+ },
296
+ get hash() {
297
+ cachedHash ??= (0, node_crypto_1.createHash)('sha256').update(this.contents).digest('hex');
298
+ return cachedHash;
299
+ },
300
+ clone() {
301
+ return createOutputFile(this.path, this.contents, this.type);
302
+ },
303
+ };
304
+ }
263
305
  }
264
- function createOutputFileFromData(path, data, type) {
306
+ function convertOutputFile(file, type) {
307
+ let { contents: cachedContents } = file;
308
+ let cachedText = null;
265
309
  return {
266
- path,
267
- type,
268
- get text() {
269
- return Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('utf-8');
270
- },
271
- get hash() {
272
- return (0, node_crypto_1.createHash)('sha256').update(this.text).digest('hex');
273
- },
274
310
  get contents() {
275
- return data;
311
+ return cachedContents;
276
312
  },
277
- clone() {
278
- return createOutputFileFromData(this.path, this.contents, this.type);
313
+ set contents(value) {
314
+ cachedContents = value;
315
+ cachedText = null;
279
316
  },
280
- };
281
- }
282
- function convertOutputFile(file, type) {
283
- const { path, contents, hash } = file;
284
- return {
285
- contents,
286
- hash,
287
- path,
317
+ hash: file.hash,
318
+ path: file.path,
288
319
  type,
320
+ get size() {
321
+ return this.contents.byteLength;
322
+ },
289
323
  get text() {
290
- return Buffer.from(this.contents.buffer, this.contents.byteOffset, this.contents.byteLength).toString('utf-8');
324
+ cachedText ??= new TextDecoder('utf-8').decode(this.contents);
325
+ return cachedText;
291
326
  },
292
327
  clone() {
293
328
  return convertOutputFile(this, this.type);
@@ -389,3 +424,9 @@ function isZonelessApp(polyfills) {
389
424
  // TODO: Instead, we should rely on the presence of zone.js in the polyfills build metadata.
390
425
  return !polyfills?.some((p) => p === 'zone.js' || /\.[mc]?[jt]s$/.test(p));
391
426
  }
427
+ function getEntryPointName(entryPoint) {
428
+ return (0, node_path_1.basename)(entryPoint)
429
+ .replace(/(.*:)/, '') // global:bundle.css -> bundle.css
430
+ .replace(/\.[cm]?[jt]s$/, '')
431
+ .replace(/[\\/.]/g, '-');
432
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.dev/license
7
+ */
8
+ import type { Plugin } from 'esbuild';
9
+ import { LoadResultCache } from './load-result-cache';
10
+ /**
11
+ * Options for the Angular WASM esbuild plugin
12
+ * @see createWasmPlugin
13
+ */
14
+ export interface WasmPluginOptions {
15
+ /** Allow generation of async (proposal compliant) WASM imports. This requires zoneless to enable async/await. */
16
+ allowAsync?: boolean;
17
+ /** Load results cache. */
18
+ cache?: LoadResultCache;
19
+ }
20
+ /**
21
+ * Creates an esbuild plugin to use WASM files with import statements and expressions.
22
+ * The default behavior follows the WebAssembly/ES mode integration proposal found at
23
+ * https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration.
24
+ * This behavior requires top-level await support which is only available in zoneless
25
+ * Angular applications.
26
+ * @returns An esbuild plugin.
27
+ */
28
+ export declare function createWasmPlugin(options: WasmPluginOptions): Plugin;
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ /**
3
+ * @license
4
+ * Copyright Google LLC All Rights Reserved.
5
+ *
6
+ * Use of this source code is governed by an MIT-style license that can be
7
+ * found in the LICENSE file at https://angular.dev/license
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.createWasmPlugin = createWasmPlugin;
14
+ const node_assert_1 = __importDefault(require("node:assert"));
15
+ const node_crypto_1 = require("node:crypto");
16
+ const promises_1 = require("node:fs/promises");
17
+ const node_path_1 = require("node:path");
18
+ const error_1 = require("../../utils/error");
19
+ const load_result_cache_1 = require("./load-result-cache");
20
+ const WASM_INIT_NAMESPACE = 'angular:wasm:init';
21
+ const WASM_CONTENTS_NAMESPACE = 'angular:wasm:contents';
22
+ const WASM_RESOLVE_SYMBOL = Symbol('WASM_RESOLVE_SYMBOL');
23
+ // See: https://github.com/tc39/proposal-regexp-unicode-property-escapes/blob/fe6d07fad74cd0192d154966baa1e95e7cda78a1/README.md#other-examples
24
+ const ecmaIdentifierNameRegExp = /^(?:[$_\p{ID_Start}])(?:[$_\u200C\u200D\p{ID_Continue}])*$/u;
25
+ /**
26
+ * Creates an esbuild plugin to use WASM files with import statements and expressions.
27
+ * The default behavior follows the WebAssembly/ES mode integration proposal found at
28
+ * https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration.
29
+ * This behavior requires top-level await support which is only available in zoneless
30
+ * Angular applications.
31
+ * @returns An esbuild plugin.
32
+ */
33
+ function createWasmPlugin(options) {
34
+ const { allowAsync = false, cache } = options;
35
+ return {
36
+ name: 'angular-wasm',
37
+ setup(build) {
38
+ build.onResolve({ filter: /.wasm$/ }, async (args) => {
39
+ // Skip if already resolving the WASM file to avoid infinite resolution
40
+ if (args.pluginData?.[WASM_RESOLVE_SYMBOL]) {
41
+ return;
42
+ }
43
+ // Skip if not an import statement or expression
44
+ if (args.kind !== 'import-statement' && args.kind !== 'dynamic-import') {
45
+ return;
46
+ }
47
+ // When in the initialization namespace, the content has already been resolved
48
+ // and only needs to be loaded for use with the initialization code.
49
+ if (args.namespace === WASM_INIT_NAMESPACE) {
50
+ return {
51
+ namespace: WASM_CONTENTS_NAMESPACE,
52
+ path: (0, node_path_1.join)(args.resolveDir, args.path),
53
+ pluginData: args.pluginData,
54
+ };
55
+ }
56
+ // Skip if a custom loader is defined
57
+ if (build.initialOptions.loader?.['.wasm'] || args.with['loader']) {
58
+ return;
59
+ }
60
+ // Attempt full resolution of the WASM file
61
+ const resolveOptions = {
62
+ ...args,
63
+ pluginData: { [WASM_RESOLVE_SYMBOL]: true },
64
+ };
65
+ // The "path" property will cause an error if used in the resolve call
66
+ delete resolveOptions.path;
67
+ const result = await build.resolve(args.path, resolveOptions);
68
+ // Skip if there are errors, is external, or another plugin resolves to a custom namespace
69
+ if (result.errors.length > 0 || result.external || result.namespace !== 'file') {
70
+ // Reuse already resolved result
71
+ return result;
72
+ }
73
+ return {
74
+ ...result,
75
+ namespace: WASM_INIT_NAMESPACE,
76
+ };
77
+ });
78
+ build.onLoad({ filter: /.wasm$/, namespace: WASM_INIT_NAMESPACE }, (0, load_result_cache_1.createCachedLoad)(cache, async (args) => {
79
+ // Ensure async mode is supported
80
+ if (!allowAsync) {
81
+ return {
82
+ errors: [
83
+ {
84
+ text: 'WASM/ES module integration imports are not supported with Zone.js applications',
85
+ notes: [
86
+ {
87
+ text: 'Information about zoneless Angular applications can be found here: https://angular.dev/guide/experimental/zoneless',
88
+ },
89
+ ],
90
+ },
91
+ ],
92
+ };
93
+ }
94
+ const wasmContents = await (0, promises_1.readFile)(args.path);
95
+ // Inline WASM code less than 10kB
96
+ const inlineWasm = wasmContents.byteLength < 10_000;
97
+ // Add import of WASM contents
98
+ let initContents = `import ${inlineWasm ? 'wasmData' : 'wasmPath'} from ${JSON.stringify((0, node_path_1.basename)(args.path))}`;
99
+ initContents += inlineWasm ? ' with { loader: "binary" };' : ';\n\n';
100
+ // Read from the file system when on Node.js (SSR) and not inline
101
+ if (!inlineWasm && build.initialOptions.platform === 'node') {
102
+ initContents += 'import { readFile } from "node:fs/promises";\n';
103
+ initContents +=
104
+ 'const wasmData = await readFile(new URL(wasmPath, import.meta.url));\n';
105
+ }
106
+ // Create initialization function
107
+ initContents += generateInitHelper(!inlineWasm && build.initialOptions.platform !== 'node', wasmContents);
108
+ // Analyze WASM for imports and exports
109
+ let importModuleNames, exportNames;
110
+ try {
111
+ const wasm = await WebAssembly.compile(wasmContents);
112
+ importModuleNames = new Set(WebAssembly.Module.imports(wasm).map((value) => value.module));
113
+ exportNames = WebAssembly.Module.exports(wasm).map((value) => value.name);
114
+ }
115
+ catch (error) {
116
+ (0, error_1.assertIsError)(error);
117
+ return {
118
+ errors: [{ text: 'Unable to analyze WASM file', notes: [{ text: error.message }] }],
119
+ };
120
+ }
121
+ // Ensure export names are valid JavaScript identifiers
122
+ const invalidExportNames = exportNames.filter((name) => !ecmaIdentifierNameRegExp.test(name));
123
+ if (invalidExportNames.length > 0) {
124
+ return {
125
+ errors: invalidExportNames.map((name) => ({
126
+ text: 'WASM export names must be valid JavaScript identifiers',
127
+ notes: [
128
+ {
129
+ text: `The export "${name}" is not valid. The WASM file should be updated to remove this error.`,
130
+ },
131
+ ],
132
+ })),
133
+ };
134
+ }
135
+ // Add import statements and setup import object
136
+ initContents += 'const importObject = Object.create(null);\n';
137
+ let importIndex = 0;
138
+ for (const moduleName of importModuleNames) {
139
+ // Add a namespace import for each module name
140
+ initContents += `import * as wasm_import_${++importIndex} from ${JSON.stringify(moduleName)};\n`;
141
+ // Add the namespace object to the import object
142
+ initContents += `importObject[${JSON.stringify(moduleName)}] = wasm_import_${importIndex};\n`;
143
+ }
144
+ // Instantiate the module
145
+ initContents += 'const instance = await init(importObject);\n';
146
+ // Add exports
147
+ const exportNameList = exportNames.join(', ');
148
+ initContents += `const { ${exportNameList} } = instance.exports;\n`;
149
+ initContents += `export { ${exportNameList} }\n`;
150
+ return {
151
+ contents: initContents,
152
+ loader: 'js',
153
+ resolveDir: (0, node_path_1.dirname)(args.path),
154
+ pluginData: { wasmContents },
155
+ watchFiles: [args.path],
156
+ };
157
+ }));
158
+ build.onLoad({ filter: /.wasm$/, namespace: WASM_CONTENTS_NAMESPACE }, async (args) => {
159
+ const contents = args.pluginData.wasmContents ?? (await (0, promises_1.readFile)(args.path));
160
+ let loader = 'file';
161
+ if (args.with.loader) {
162
+ (0, node_assert_1.default)(args.with.loader === 'binary' || args.with.loader === 'file', 'WASM loader type should only be binary or file.');
163
+ loader = args.with.loader;
164
+ }
165
+ return {
166
+ contents,
167
+ loader,
168
+ watchFiles: [args.path],
169
+ };
170
+ });
171
+ },
172
+ };
173
+ }
174
+ /**
175
+ * Generates the string content of the WASM initialization helper function.
176
+ * This function supports both file fetching and inline byte data depending on
177
+ * the preferred option for the WASM file. When fetching, an integrity hash is
178
+ * also generated and used with the fetch action.
179
+ *
180
+ * @param streaming Uses fetch and WebAssembly.instantiateStreaming.
181
+ * @param wasmContents The binary contents to generate an integrity hash.
182
+ * @returns A string containing the initialization function.
183
+ */
184
+ function generateInitHelper(streaming, wasmContents) {
185
+ let resultContents;
186
+ if (streaming) {
187
+ const fetchOptions = {
188
+ integrity: 'sha256-' + (0, node_crypto_1.createHash)('sha-256').update(wasmContents).digest('base64'),
189
+ };
190
+ const fetchContents = `fetch(new URL(wasmPath, import.meta.url), ${JSON.stringify(fetchOptions)})`;
191
+ resultContents = `await WebAssembly.instantiateStreaming(${fetchContents}, imports)`;
192
+ }
193
+ else {
194
+ resultContents = 'await WebAssembly.instantiate(wasmData, imports)';
195
+ }
196
+ const contents = `
197
+ let mod;
198
+ async function init(imports) {
199
+ if (mod) {
200
+ return await WebAssembly.instantiate(mod, imports);
201
+ }
202
+
203
+ const result = ${resultContents};
204
+ mod = result.module;
205
+
206
+ return result.instance;
207
+ }
208
+ `;
209
+ return contents;
210
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google LLC All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.dev/license
7
+ */
8
+
9
+ /** @fileoverview
10
+ * TypeScript does not provide a separate lib for WASM types and the Node.js
11
+ * types (`@types/node`) does not contain them either. This type definition
12
+ * file provides type information for the subset of functionality required
13
+ * by the Angular build process. Ideally this can be removed when the WASM
14
+ * type situation has improved.
15
+ */
16
+
17
+ declare namespace WebAssembly {
18
+ class Module {
19
+ constructor(data: Uint8Array);
20
+
21
+ static imports(mod: Module): { module: string; name: string }[];
22
+ static exports(mode: Module): { name: string }[];
23
+ }
24
+ function compile(data: Uint8Array): Promise<Module>;
25
+ }
@@ -6,18 +6,15 @@
6
6
  * found in the LICENSE file at https://angular.dev/license
7
7
  */
8
8
  import type { Connect, Plugin } from 'vite';
9
+ import { AngularMemoryOutputFiles } from './utils';
9
10
  export interface AngularMemoryPluginOptions {
10
11
  workspaceRoot: string;
11
12
  virtualProjectRoot: string;
12
- outputFiles: Map<string, {
13
- contents: Uint8Array;
14
- servable: boolean;
15
- }>;
13
+ outputFiles: AngularMemoryOutputFiles;
16
14
  assets: Map<string, string>;
17
15
  ssr: boolean;
18
16
  external?: string[];
19
17
  extensionMiddleware?: Connect.NextHandleFunction[];
20
- extraHeaders?: Record<string, string>;
21
18
  indexHtmlTransformer?: (content: string) => Promise<string>;
22
19
  normalizePath: (path: string) => string;
23
20
  }