@ngtools/webpack 12.0.1 → 12.0.5

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngtools/webpack",
3
- "version": "12.0.1",
3
+ "version": "12.0.5",
4
4
  "description": "Webpack plugin that AoT compiles your Angular components and modules.",
5
5
  "main": "./src/index.js",
6
6
  "typings": "src/index.d.ts",
@@ -33,7 +33,7 @@
33
33
  "webpack": "^5.30.0"
34
34
  },
35
35
  "engines": {
36
- "node": "^12.14.1 || ^14.0.0",
36
+ "node": "^12.14.1 || >=14.0.0",
37
37
  "npm": "^6.11.0 || ^7.5.6",
38
38
  "yarn": ">= 1.13.0"
39
39
  }
package/src/ivy/host.js CHANGED
@@ -42,7 +42,7 @@ function augmentHostWithResources(host, resourceLoader, options = {}) {
42
42
  return null;
43
43
  }
44
44
  if (options.inlineStyleMimeType) {
45
- const content = await resourceLoader.process(data, options.inlineStyleMimeType);
45
+ const content = await resourceLoader.process(data, options.inlineStyleMimeType, context.type, context.containingFile);
46
46
  return { content };
47
47
  }
48
48
  return null;
@@ -6,7 +6,7 @@
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
8
  import { CompilerOptions } from '@angular/compiler-cli';
9
- import { Compiler } from 'webpack';
9
+ import type { Compiler } from 'webpack';
10
10
  export interface AngularWebpackPluginOptions {
11
11
  tsconfig: string;
12
12
  compilerOptions?: CompilerOptions;
package/src/ivy/plugin.js CHANGED
@@ -12,7 +12,6 @@ const compiler_cli_1 = require("@angular/compiler-cli");
12
12
  const program_1 = require("@angular/compiler-cli/src/ngtsc/program");
13
13
  const crypto_1 = require("crypto");
14
14
  const ts = require("typescript");
15
- const webpack_1 = require("webpack");
16
15
  const ngcc_processor_1 = require("../ngcc_processor");
17
16
  const paths_plugin_1 = require("../paths-plugin");
18
17
  const resource_loader_1 = require("../resource_loader");
@@ -64,9 +63,10 @@ class AngularWebpackPlugin {
64
63
  return this.pluginOptions;
65
64
  }
66
65
  apply(compiler) {
66
+ const { NormalModuleReplacementPlugin, util } = compiler.webpack;
67
67
  // Setup file replacements with webpack
68
68
  for (const [key, value] of Object.entries(this.pluginOptions.fileReplacements)) {
69
- new webpack_1.NormalModuleReplacementPlugin(new RegExp('^' + key.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&') + '$'), value).apply(compiler);
69
+ new NormalModuleReplacementPlugin(new RegExp('^' + key.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&') + '$'), value).apply(compiler);
70
70
  }
71
71
  // Set resolver options
72
72
  const pathsPlugin = new paths_plugin_1.TypeScriptPathsPlugin();
@@ -84,7 +84,7 @@ class AngularWebpackPlugin {
84
84
  (_b = resolveOptions.plugins) !== null && _b !== void 0 ? _b : (resolveOptions.plugins = []);
85
85
  resolveOptions.plugins.push(pathsPlugin);
86
86
  // https://github.com/webpack/webpack/issues/11635#issuecomment-707016779
87
- return webpack_1.util.cleverMerge(resolveOptions, { mainFields: [...ivyMainFields, '...'] });
87
+ return util.cleverMerge(resolveOptions, { mainFields: [...ivyMainFields, '...'] });
88
88
  });
89
89
  });
90
90
  let ngccProcessor;
@@ -171,8 +171,9 @@ class AngularWebpackPlugin {
171
171
  if (internalFiles === null || internalFiles === void 0 ? void 0 : internalFiles.has(sourceFile)) {
172
172
  continue;
173
173
  }
174
- // Ensure all program files are considered part of the compilation and will be watched
175
- compilation.fileDependencies.add(sourceFile.fileName);
174
+ // Ensure all program files are considered part of the compilation and will be watched.
175
+ // Webpack does not normalize paths. Therefore, we need to normalize the path with FS seperators.
176
+ compilation.fileDependencies.add(paths_1.externalizePath(sourceFile.fileName));
176
177
  // Add all non-declaration files to the initial set of unused files. The set will be
177
178
  // analyzed and pruned after all Webpack modules are finished building.
178
179
  if (!sourceFile.isDeclarationFile) {
@@ -5,13 +5,13 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { Compilation } from 'webpack';
8
+ import type { Compilation } from 'webpack';
9
9
  export declare class WebpackResourceLoader {
10
10
  private _parentCompilation?;
11
11
  private _fileDependencies;
12
12
  private _reverseDependencies;
13
13
  private fileCache?;
14
- private inlineCache?;
14
+ private assetCache?;
15
15
  private modifiedResources;
16
16
  private outputPathCounter;
17
17
  constructor(shouldCache: boolean);
@@ -24,5 +24,5 @@ export declare class WebpackResourceLoader {
24
24
  private _compile;
25
25
  private _evaluate;
26
26
  get(filePath: string): Promise<string>;
27
- process(data: string, mimeType: string): Promise<string>;
27
+ process(data: string, mimeType: string, resourceType: 'template' | 'style', containingFile?: string): Promise<string>;
28
28
  }
@@ -11,7 +11,6 @@ exports.WebpackResourceLoader = void 0;
11
11
  const crypto_1 = require("crypto");
12
12
  const path = require("path");
13
13
  const vm = require("vm");
14
- const webpack_1 = require("webpack");
15
14
  const paths_1 = require("./ivy/paths");
16
15
  class WebpackResourceLoader {
17
16
  constructor(shouldCache) {
@@ -21,24 +20,37 @@ class WebpackResourceLoader {
21
20
  this.outputPathCounter = 1;
22
21
  if (shouldCache) {
23
22
  this.fileCache = new Map();
24
- this.inlineCache = new Map();
23
+ this.assetCache = new Map();
25
24
  }
26
25
  }
27
26
  update(parentCompilation, changedFiles) {
28
- var _a, _b;
27
+ var _a, _b, _c, _d, _e;
29
28
  this._parentCompilation = parentCompilation;
30
29
  // Update resource cache and modified resources
31
30
  this.modifiedResources.clear();
32
31
  if (changedFiles) {
33
32
  for (const changedFile of changedFiles) {
33
+ const changedFileNormalized = paths_1.normalizePath(changedFile);
34
+ (_a = this.assetCache) === null || _a === void 0 ? void 0 : _a.delete(changedFileNormalized);
34
35
  for (const affectedResource of this.getAffectedResources(changedFile)) {
35
- (_a = this.fileCache) === null || _a === void 0 ? void 0 : _a.delete(paths_1.normalizePath(affectedResource));
36
+ const affectedResourceNormalized = paths_1.normalizePath(affectedResource);
37
+ (_b = this.fileCache) === null || _b === void 0 ? void 0 : _b.delete(affectedResourceNormalized);
36
38
  this.modifiedResources.add(affectedResource);
39
+ for (const effectedDependencies of this.getResourceDependencies(affectedResourceNormalized)) {
40
+ (_c = this.assetCache) === null || _c === void 0 ? void 0 : _c.delete(paths_1.normalizePath(effectedDependencies));
41
+ }
37
42
  }
38
43
  }
39
44
  }
40
45
  else {
41
- (_b = this.fileCache) === null || _b === void 0 ? void 0 : _b.clear();
46
+ (_d = this.fileCache) === null || _d === void 0 ? void 0 : _d.clear();
47
+ (_e = this.assetCache) === null || _e === void 0 ? void 0 : _e.clear();
48
+ }
49
+ // Re-emit all assets for un-effected files
50
+ if (this.assetCache) {
51
+ for (const [, { name, source, info }] of this.assetCache) {
52
+ this._parentCompilation.emitAsset(name, source, info);
53
+ }
42
54
  }
43
55
  }
44
56
  clearParentCompilation() {
@@ -56,12 +68,14 @@ class WebpackResourceLoader {
56
68
  setAffectedResources(file, resources) {
57
69
  this._reverseDependencies.set(file, new Set(resources));
58
70
  }
59
- async _compile(filePath, data, mimeType) {
71
+ async _compile(filePath, data, mimeType, resourceType, containingFile) {
60
72
  if (!this._parentCompilation) {
61
73
  throw new Error('WebpackResourceLoader cannot be used without parentCompilation');
62
74
  }
63
75
  // Create a special URL for reading the resource from memory
64
- const entry = data ? 'angular-resource://' : filePath;
76
+ const entry = data
77
+ ? `angular-resource:${resourceType},${crypto_1.createHash('md5').update(data).digest('hex')}`
78
+ : filePath;
65
79
  if (!entry) {
66
80
  throw new Error(`"filePath" or "data" must be specified.`);
67
81
  }
@@ -69,7 +83,8 @@ class WebpackResourceLoader {
69
83
  if (filePath === null || filePath === void 0 ? void 0 : filePath.match(/\.[jt]s$/)) {
70
84
  throw new Error(`Cannot use a JavaScript or TypeScript file (${filePath}) in a component's styleUrls or templateUrl.`);
71
85
  }
72
- const outputFilePath = filePath || `angular-resource-output-${this.outputPathCounter++}.css`;
86
+ const outputFilePath = filePath ||
87
+ `${containingFile}-angular-inline--${this.outputPathCounter++}.${resourceType === 'template' ? 'html' : 'css'}`;
73
88
  const outputOptions = {
74
89
  filename: outputFilePath,
75
90
  library: {
@@ -77,12 +92,13 @@ class WebpackResourceLoader {
77
92
  name: 'resource',
78
93
  },
79
94
  };
80
- const context = this._parentCompilation.compiler.context;
95
+ const { context, webpack } = this._parentCompilation.compiler;
96
+ const { EntryPlugin, NormalModule, library, node, sources } = webpack;
81
97
  const childCompiler = this._parentCompilation.createChildCompiler('angular-compiler:resource', outputOptions, [
82
- new webpack_1.node.NodeTemplatePlugin(outputOptions),
83
- new webpack_1.node.NodeTargetPlugin(),
84
- new webpack_1.EntryPlugin(context, entry, { name: 'resource' }),
85
- new webpack_1.library.EnableLibraryPlugin('var'),
98
+ new node.NodeTemplatePlugin(outputOptions),
99
+ new node.NodeTargetPlugin(),
100
+ new EntryPlugin(context, entry, { name: 'resource' }),
101
+ new library.EnableLibraryPlugin('var'),
86
102
  ]);
87
103
  childCompiler.hooks.thisCompilation.tap('angular-compiler', (compilation, { normalModuleFactory }) => {
88
104
  // If no data is provided, the resource will be read from the filesystem
@@ -99,7 +115,7 @@ class WebpackResourceLoader {
99
115
  }
100
116
  return true;
101
117
  });
102
- webpack_1.NormalModule.getCompilationHooks(compilation)
118
+ NormalModule.getCompilationHooks(compilation)
103
119
  .readResourceForScheme.for('angular-resource')
104
120
  .tap('angular-compiler', () => data);
105
121
  }
@@ -111,7 +127,7 @@ class WebpackResourceLoader {
111
127
  try {
112
128
  const output = this._evaluate(outputFilePath, asset.source().toString());
113
129
  if (typeof output === 'string') {
114
- compilation.assets[outputFilePath] = new webpack_1.sources.RawSource(output);
130
+ compilation.assets[outputFilePath] = new sources.RawSource(output);
115
131
  }
116
132
  }
117
133
  catch (error) {
@@ -123,7 +139,7 @@ class WebpackResourceLoader {
123
139
  let finalContent;
124
140
  let finalMap;
125
141
  childCompiler.hooks.compilation.tap('angular-compiler', (childCompilation) => {
126
- childCompilation.hooks.processAssets.tap({ name: 'angular-compiler', stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_REPORT }, () => {
142
+ childCompilation.hooks.processAssets.tap({ name: 'angular-compiler', stage: webpack.Compilation.PROCESS_ASSETS_STAGE_REPORT }, () => {
127
143
  var _a, _b;
128
144
  finalContent = (_a = childCompilation.assets[outputFilePath]) === null || _a === void 0 ? void 0 : _a.source().toString();
129
145
  finalMap = (_b = childCompilation.assets[outputFilePath + '.map']) === null || _b === void 0 ? void 0 : _b.source().toString();
@@ -133,7 +149,7 @@ class WebpackResourceLoader {
133
149
  });
134
150
  return new Promise((resolve, reject) => {
135
151
  childCompiler.runAsChild((error, _, childCompilation) => {
136
- var _a;
152
+ var _a, _b;
137
153
  if (error) {
138
154
  reject(error);
139
155
  return;
@@ -148,12 +164,26 @@ class WebpackResourceLoader {
148
164
  const parent = childCompiler.parentCompilation;
149
165
  if (parent) {
150
166
  parent.children = parent.children.filter((child) => child !== childCompilation);
151
- parent.fileDependencies.addAll(childCompilation.fileDependencies);
167
+ for (const fileDependency of childCompilation.fileDependencies) {
168
+ if (data && containingFile && fileDependency.endsWith(entry)) {
169
+ // use containing file if the resource was inline
170
+ parent.fileDependencies.add(containingFile);
171
+ }
172
+ else {
173
+ parent.fileDependencies.add(fileDependency);
174
+ }
175
+ }
152
176
  parent.contextDependencies.addAll(childCompilation.contextDependencies);
153
177
  parent.missingDependencies.addAll(childCompilation.missingDependencies);
154
178
  parent.buildDependencies.addAll(childCompilation.buildDependencies);
155
179
  parent.warnings.push(...childCompilation.warnings);
156
180
  parent.errors.push(...childCompilation.errors);
181
+ for (const { info, name, source } of childCompilation.getAssets()) {
182
+ if (info.sourceFilename === undefined) {
183
+ throw new Error(`'${name}' asset info 'sourceFilename' is 'undefined'.`);
184
+ }
185
+ (_a = this.assetCache) === null || _a === void 0 ? void 0 : _a.set(info.sourceFilename, { info, name, source });
186
+ }
157
187
  }
158
188
  // Save the dependencies for this resource.
159
189
  if (filePath) {
@@ -177,7 +207,7 @@ class WebpackResourceLoader {
177
207
  }
178
208
  resolve({
179
209
  content: finalContent !== null && finalContent !== void 0 ? finalContent : '',
180
- success: ((_a = childCompilation.errors) === null || _a === void 0 ? void 0 : _a.length) === 0,
210
+ success: ((_b = childCompilation.errors) === null || _b === void 0 ? void 0 : _b.length) === 0,
181
211
  });
182
212
  });
183
213
  });
@@ -215,19 +245,11 @@ class WebpackResourceLoader {
215
245
  }
216
246
  return compilationResult.content;
217
247
  }
218
- async process(data, mimeType) {
219
- var _a;
248
+ async process(data, mimeType, resourceType, containingFile) {
220
249
  if (data.trim().length === 0) {
221
250
  return '';
222
251
  }
223
- const cacheKey = crypto_1.createHash('md5').update(data).digest('hex');
224
- let compilationResult = (_a = this.inlineCache) === null || _a === void 0 ? void 0 : _a.get(cacheKey);
225
- if (compilationResult === undefined) {
226
- compilationResult = await this._compile(undefined, data, mimeType);
227
- if (this.inlineCache && compilationResult.success) {
228
- this.inlineCache.set(cacheKey, compilationResult);
229
- }
230
- }
252
+ const compilationResult = await this._compile(undefined, data, mimeType, resourceType, containingFile);
231
253
  return compilationResult.content;
232
254
  }
233
255
  }
@@ -5,6 +5,6 @@
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://angular.io/license
7
7
  */
8
- import { Compilation } from 'webpack';
8
+ import type { Compilation } from 'webpack';
9
9
  export declare function addWarning(compilation: Compilation, message: string): void;
10
10
  export declare function addError(compilation: Compilation, message: string): void;
@@ -8,12 +8,11 @@
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.addError = exports.addWarning = void 0;
11
- const webpack_1 = require("webpack");
12
11
  function addWarning(compilation, message) {
13
- compilation.warnings.push(new webpack_1.WebpackError(message));
12
+ compilation.warnings.push(new compilation.compiler.webpack.WebpackError(message));
14
13
  }
15
14
  exports.addWarning = addWarning;
16
15
  function addError(compilation, message) {
17
- compilation.errors.push(new webpack_1.WebpackError(message));
16
+ compilation.errors.push(new compilation.compiler.webpack.WebpackError(message));
18
17
  }
19
18
  exports.addError = addError;