@ngtools/webpack 11.2.2 → 11.2.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/package.json +2 -2
- package/src/ivy/host.d.ts +17 -2
- package/src/ivy/host.js +55 -1
- package/src/ivy/plugin.d.ts +2 -0
- package/src/ivy/plugin.js +71 -32
- package/src/resource_loader.d.ts +14 -0
- package/src/resource_loader.js +15 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ngtools/webpack",
|
|
3
|
-
"version": "11.2.
|
|
3
|
+
"version": "11.2.6",
|
|
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",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/angular/angular-cli",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@angular-devkit/core": "11.2.
|
|
28
|
+
"@angular-devkit/core": "11.2.6",
|
|
29
29
|
"enhanced-resolve": "5.7.0",
|
|
30
30
|
"webpack-sources": "2.2.0"
|
|
31
31
|
},
|
package/src/ivy/host.d.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import { NgccProcessor } from '../ngcc_processor';
|
|
3
|
-
import {
|
|
4
|
-
export declare function augmentHostWithResources(host: ts.CompilerHost, resourceLoader:
|
|
3
|
+
import { ResourceLoader } from '../resource_loader';
|
|
4
|
+
export declare function augmentHostWithResources(host: ts.CompilerHost, resourceLoader: ResourceLoader, options?: {
|
|
5
5
|
directTemplateLoading?: boolean;
|
|
6
6
|
}): void;
|
|
7
|
+
/**
|
|
8
|
+
* Augments a TypeScript Compiler Host's resolveModuleNames function to collect dependencies
|
|
9
|
+
* of the containing file passed to the resolveModuleNames function. This process assumes
|
|
10
|
+
* that consumers of the Compiler Host will only call resolveModuleNames with modules that are
|
|
11
|
+
* actually present in a containing file.
|
|
12
|
+
* This process is a workaround for gathering a TypeScript SourceFile's dependencies as there
|
|
13
|
+
* is no currently exposed public method to do so. A BuilderProgram does have a `getAllDependencies`
|
|
14
|
+
* function. However, that function returns all transitive dependencies as well which can cause
|
|
15
|
+
* excessive Webpack rebuilds.
|
|
16
|
+
*
|
|
17
|
+
* @param host The CompilerHost to augment.
|
|
18
|
+
* @param dependencies A Map which will be used to store file dependencies.
|
|
19
|
+
* @param moduleResolutionCache An optional resolution cache to use when the host resolves a module.
|
|
20
|
+
*/
|
|
21
|
+
export declare function augmentHostWithDependencyCollection(host: ts.CompilerHost, dependencies: Map<string, Set<string>>, moduleResolutionCache?: ts.ModuleResolutionCache): void;
|
|
7
22
|
export declare function augmentHostWithNgcc(host: ts.CompilerHost, ngcc: NgccProcessor, moduleResolutionCache?: ts.ModuleResolutionCache): void;
|
|
8
23
|
export declare function augmentHostWithReplacements(host: ts.CompilerHost, replacements: Record<string, string>, moduleResolutionCache?: ts.ModuleResolutionCache): void;
|
|
9
24
|
export declare function augmentHostWithSubstitutions(host: ts.CompilerHost, substitutions: Record<string, string>): void;
|
package/src/ivy/host.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.augmentHostWithCaching = exports.augmentProgramWithVersioning = exports.augmentHostWithVersioning = exports.augmentHostWithSubstitutions = exports.augmentHostWithReplacements = exports.augmentHostWithNgcc = exports.augmentHostWithResources = void 0;
|
|
3
|
+
exports.augmentHostWithCaching = exports.augmentProgramWithVersioning = exports.augmentHostWithVersioning = exports.augmentHostWithSubstitutions = exports.augmentHostWithReplacements = exports.augmentHostWithNgcc = exports.augmentHostWithDependencyCollection = exports.augmentHostWithResources = void 0;
|
|
4
4
|
const crypto_1 = require("crypto");
|
|
5
5
|
const path = require("path");
|
|
6
6
|
const ts = require("typescript");
|
|
@@ -49,6 +49,60 @@ function augmentResolveModuleNames(host, resolvedModuleModifier, moduleResolutio
|
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Augments a TypeScript Compiler Host's resolveModuleNames function to collect dependencies
|
|
54
|
+
* of the containing file passed to the resolveModuleNames function. This process assumes
|
|
55
|
+
* that consumers of the Compiler Host will only call resolveModuleNames with modules that are
|
|
56
|
+
* actually present in a containing file.
|
|
57
|
+
* This process is a workaround for gathering a TypeScript SourceFile's dependencies as there
|
|
58
|
+
* is no currently exposed public method to do so. A BuilderProgram does have a `getAllDependencies`
|
|
59
|
+
* function. However, that function returns all transitive dependencies as well which can cause
|
|
60
|
+
* excessive Webpack rebuilds.
|
|
61
|
+
*
|
|
62
|
+
* @param host The CompilerHost to augment.
|
|
63
|
+
* @param dependencies A Map which will be used to store file dependencies.
|
|
64
|
+
* @param moduleResolutionCache An optional resolution cache to use when the host resolves a module.
|
|
65
|
+
*/
|
|
66
|
+
function augmentHostWithDependencyCollection(host, dependencies, moduleResolutionCache) {
|
|
67
|
+
if (host.resolveModuleNames) {
|
|
68
|
+
const baseResolveModuleNames = host.resolveModuleNames;
|
|
69
|
+
host.resolveModuleNames = function (moduleNames, containingFile, ...parameters) {
|
|
70
|
+
const results = baseResolveModuleNames.call(host, moduleNames, containingFile, ...parameters);
|
|
71
|
+
const containingFilePath = paths_1.normalizePath(containingFile);
|
|
72
|
+
for (const result of results) {
|
|
73
|
+
if (result) {
|
|
74
|
+
const containingFileDependencies = dependencies.get(containingFilePath);
|
|
75
|
+
if (containingFileDependencies) {
|
|
76
|
+
containingFileDependencies.add(result.resolvedFileName);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
dependencies.set(containingFilePath, new Set([result.resolvedFileName]));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return results;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
host.resolveModuleNames = function (moduleNames, containingFile, _reusedNames, redirectedReference, options) {
|
|
88
|
+
return moduleNames.map((name) => {
|
|
89
|
+
const result = ts.resolveModuleName(name, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule;
|
|
90
|
+
if (result) {
|
|
91
|
+
const containingFilePath = paths_1.normalizePath(containingFile);
|
|
92
|
+
const containingFileDependencies = dependencies.get(containingFilePath);
|
|
93
|
+
if (containingFileDependencies) {
|
|
94
|
+
containingFileDependencies.add(result.resolvedFileName);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
dependencies.set(containingFilePath, new Set([result.resolvedFileName]));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.augmentHostWithDependencyCollection = augmentHostWithDependencyCollection;
|
|
52
106
|
function augmentHostWithNgcc(host, ngcc, moduleResolutionCache) {
|
|
53
107
|
augmentResolveModuleNames(host, (resolvedModule, moduleName) => {
|
|
54
108
|
if (resolvedModule && ngcc) {
|
package/src/ivy/plugin.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare class AngularWebpackPlugin {
|
|
|
26
26
|
private sourceFileCache?;
|
|
27
27
|
private buildTimestamp;
|
|
28
28
|
private readonly lazyRouteMap;
|
|
29
|
+
private readonly fileDependencies;
|
|
29
30
|
private readonly requiredFilesToEmit;
|
|
30
31
|
private readonly requiredFilesToEmitCache;
|
|
31
32
|
private readonly fileEmitHistory;
|
|
@@ -34,6 +35,7 @@ export declare class AngularWebpackPlugin {
|
|
|
34
35
|
apply(compiler: Compiler & {
|
|
35
36
|
watchMode?: boolean;
|
|
36
37
|
}): void;
|
|
38
|
+
private markResourceUsed;
|
|
37
39
|
private rebuildRequiredFiles;
|
|
38
40
|
private loadConfiguration;
|
|
39
41
|
private updateAotProgram;
|
package/src/ivy/plugin.js
CHANGED
|
@@ -14,6 +14,7 @@ const crypto_1 = require("crypto");
|
|
|
14
14
|
const path = require("path");
|
|
15
15
|
const ts = require("typescript");
|
|
16
16
|
const webpack_1 = require("webpack");
|
|
17
|
+
const lazy_routes_1 = require("../lazy_routes");
|
|
17
18
|
const ngcc_processor_1 = require("../ngcc_processor");
|
|
18
19
|
const paths_plugin_1 = require("../paths-plugin");
|
|
19
20
|
const resource_loader_1 = require("../resource_loader");
|
|
@@ -42,6 +43,7 @@ const PLUGIN_NAME = 'angular-compiler';
|
|
|
42
43
|
class AngularWebpackPlugin {
|
|
43
44
|
constructor(options = {}) {
|
|
44
45
|
this.lazyRouteMap = {};
|
|
46
|
+
this.fileDependencies = new Map();
|
|
45
47
|
this.requiredFilesToEmit = new Set();
|
|
46
48
|
this.requiredFilesToEmitCache = new Map();
|
|
47
49
|
this.fileEmitHistory = new Map();
|
|
@@ -89,7 +91,9 @@ class AngularWebpackPlugin {
|
|
|
89
91
|
});
|
|
90
92
|
});
|
|
91
93
|
let ngccProcessor;
|
|
92
|
-
const resourceLoader =
|
|
94
|
+
const resourceLoader = this.pluginOptions.jitMode
|
|
95
|
+
? new resource_loader_1.NoopResourceLoader()
|
|
96
|
+
: new resource_loader_1.WebpackResourceLoader();
|
|
93
97
|
let previousUnused;
|
|
94
98
|
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (thisCompilation) => {
|
|
95
99
|
var _a;
|
|
@@ -120,6 +124,10 @@ class AngularWebpackPlugin {
|
|
|
120
124
|
if (cache) {
|
|
121
125
|
// Invalidate existing cache based on compiler file timestamps
|
|
122
126
|
changedFiles = cache.invalidate(compiler.fileTimestamps, this.buildTimestamp);
|
|
127
|
+
// Invalidate file dependencies of changed files
|
|
128
|
+
for (const changedFile of changedFiles) {
|
|
129
|
+
this.fileDependencies.delete(paths_1.normalizePath(changedFile));
|
|
130
|
+
}
|
|
123
131
|
}
|
|
124
132
|
else {
|
|
125
133
|
// Initialize a new cache
|
|
@@ -132,19 +140,21 @@ class AngularWebpackPlugin {
|
|
|
132
140
|
this.buildTimestamp = Date.now();
|
|
133
141
|
host_1.augmentHostWithCaching(host, cache);
|
|
134
142
|
const moduleResolutionCache = ts.createModuleResolutionCache(host.getCurrentDirectory(), host.getCanonicalFileName.bind(host), compilerOptions);
|
|
143
|
+
// Setup source file dependency collection
|
|
144
|
+
host_1.augmentHostWithDependencyCollection(host, this.fileDependencies, moduleResolutionCache);
|
|
135
145
|
// Setup on demand ngcc
|
|
136
146
|
host_1.augmentHostWithNgcc(host, ngccProcessor, moduleResolutionCache);
|
|
137
147
|
// Setup resource loading
|
|
138
148
|
resourceLoader.update(compilation, changedFiles);
|
|
139
149
|
host_1.augmentHostWithResources(host, resourceLoader, {
|
|
140
|
-
directTemplateLoading: this.pluginOptions.directTemplateLoading,
|
|
150
|
+
directTemplateLoading: !this.pluginOptions.jitMode && this.pluginOptions.directTemplateLoading,
|
|
141
151
|
});
|
|
142
152
|
// Setup source file adjustment options
|
|
143
153
|
host_1.augmentHostWithReplacements(host, this.pluginOptions.fileReplacements, moduleResolutionCache);
|
|
144
154
|
host_1.augmentHostWithSubstitutions(host, this.pluginOptions.substitutions);
|
|
145
155
|
// Create the file emitter used by the webpack loader
|
|
146
156
|
const { fileEmitter, builder, internalFiles } = this.pluginOptions.jitMode
|
|
147
|
-
? this.updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter)
|
|
157
|
+
? this.updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter, changedFiles)
|
|
148
158
|
: this.updateAotProgram(compilerOptions, rootNames, host, diagnosticsReporter, resourceLoader);
|
|
149
159
|
const allProgramFiles = builder
|
|
150
160
|
.getSourceFiles()
|
|
@@ -165,13 +175,11 @@ class AngularWebpackPlugin {
|
|
|
165
175
|
}
|
|
166
176
|
const currentUnused = new Set(allProgramFiles
|
|
167
177
|
.filter((sourceFile) => !sourceFile.isDeclarationFile)
|
|
168
|
-
.map((sourceFile) => sourceFile.fileName));
|
|
178
|
+
.map((sourceFile) => paths_1.normalizePath(sourceFile.fileName)));
|
|
169
179
|
modules.forEach(({ resource }) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return;
|
|
180
|
+
if (resource) {
|
|
181
|
+
this.markResourceUsed(paths_1.normalizePath(resource), currentUnused);
|
|
173
182
|
}
|
|
174
|
-
builder.getAllDependencies(sourceFile).forEach((dep) => currentUnused.delete(dep));
|
|
175
183
|
});
|
|
176
184
|
for (const unused of currentUnused) {
|
|
177
185
|
if (previousUnused && previousUnused.has(unused)) {
|
|
@@ -186,6 +194,19 @@ class AngularWebpackPlugin {
|
|
|
186
194
|
compilation[symbol_1.AngularPluginSymbol] = fileEmitter;
|
|
187
195
|
});
|
|
188
196
|
}
|
|
197
|
+
markResourceUsed(normalizedResourcePath, currentUnused) {
|
|
198
|
+
if (!currentUnused.has(normalizedResourcePath)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
currentUnused.delete(normalizedResourcePath);
|
|
202
|
+
const dependencies = this.fileDependencies.get(normalizedResourcePath);
|
|
203
|
+
if (!dependencies) {
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
for (const dependency of dependencies) {
|
|
207
|
+
this.markResourceUsed(paths_1.normalizePath(dependency), currentUnused);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
189
210
|
async rebuildRequiredFiles(modules, compilation, fileEmitter) {
|
|
190
211
|
if (this.requiredFilesToEmit.size === 0) {
|
|
191
212
|
return;
|
|
@@ -342,7 +363,7 @@ class AngularWebpackPlugin {
|
|
|
342
363
|
internalFiles: ignoreForEmit,
|
|
343
364
|
};
|
|
344
365
|
}
|
|
345
|
-
updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter) {
|
|
366
|
+
updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter, changedFiles) {
|
|
346
367
|
const builder = ts.createEmitAndSemanticDiagnosticsBuilderProgram(rootNames, compilerOptions, host, this.builder);
|
|
347
368
|
// Save for next rebuild
|
|
348
369
|
if (this.watchMode) {
|
|
@@ -357,30 +378,48 @@ class AngularWebpackPlugin {
|
|
|
357
378
|
];
|
|
358
379
|
diagnosticsReporter(diagnostics);
|
|
359
380
|
const transformers = transformation_1.createJitTransformers(builder, this.pluginOptions);
|
|
360
|
-
//
|
|
361
|
-
//
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
381
|
+
// Only do a full, expensive Angular compiler string lazy route analysis on the first build
|
|
382
|
+
// `changedFiles` will be undefined on a first build
|
|
383
|
+
if (!changedFiles) {
|
|
384
|
+
// Required to support asynchronous resource loading
|
|
385
|
+
// Must be done before listing lazy routes
|
|
386
|
+
// NOTE: This can be removed once support for the deprecated lazy route string format is removed
|
|
387
|
+
const angularProgram = new program_1.NgtscProgram(rootNames, compilerOptions, host);
|
|
388
|
+
const angularCompiler = angularProgram.compiler;
|
|
389
|
+
const pendingAnalysis = angularCompiler.analyzeAsync().then(() => {
|
|
390
|
+
for (const lazyRoute of angularCompiler.listLazyRoutes()) {
|
|
391
|
+
const [routeKey] = lazyRoute.route.split('#');
|
|
392
|
+
this.lazyRouteMap[routeKey] = lazyRoute.referencedModule.filePath;
|
|
393
|
+
}
|
|
394
|
+
return this.createFileEmitter(builder, transformers, () => []);
|
|
395
|
+
});
|
|
396
|
+
const analyzingFileEmitter = async (file) => {
|
|
397
|
+
const innerFileEmitter = await pendingAnalysis;
|
|
398
|
+
return innerFileEmitter(file);
|
|
399
|
+
};
|
|
400
|
+
return {
|
|
401
|
+
fileEmitter: analyzingFileEmitter,
|
|
402
|
+
builder,
|
|
403
|
+
internalFiles: undefined,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
// Update lazy route map for changed files using fast but less accurate method
|
|
408
|
+
for (const changedFile of changedFiles) {
|
|
409
|
+
if (!builder.getSourceFile(changedFile)) {
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
const routes = lazy_routes_1.findLazyRoutes(changedFile, host, builder.getProgram());
|
|
413
|
+
for (const [routeKey, filePath] of Object.entries(routes)) {
|
|
414
|
+
this.lazyRouteMap[routeKey] = filePath;
|
|
415
|
+
}
|
|
369
416
|
}
|
|
370
|
-
return
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
};
|
|
376
|
-
if (this.watchMode) {
|
|
377
|
-
this.ngtscNextProgram = angularProgram;
|
|
417
|
+
return {
|
|
418
|
+
fileEmitter: this.createFileEmitter(builder, transformers, () => []),
|
|
419
|
+
builder,
|
|
420
|
+
internalFiles: undefined,
|
|
421
|
+
};
|
|
378
422
|
}
|
|
379
|
-
return {
|
|
380
|
-
fileEmitter: analyzingFileEmitter,
|
|
381
|
-
builder,
|
|
382
|
-
internalFiles: undefined,
|
|
383
|
-
};
|
|
384
423
|
}
|
|
385
424
|
createFileEmitter(program, transformers = {}, getExtraDependencies, onAfterEmit) {
|
|
386
425
|
return async (file) => {
|
|
@@ -410,7 +449,7 @@ class AngularWebpackPlugin {
|
|
|
410
449
|
this.fileEmitHistory.set(filePath, { length: content.length, hash });
|
|
411
450
|
}
|
|
412
451
|
const dependencies = [
|
|
413
|
-
...
|
|
452
|
+
...(this.fileDependencies.get(filePath) || []),
|
|
414
453
|
...getExtraDependencies(sourceFile),
|
|
415
454
|
].map(paths_1.externalizePath);
|
|
416
455
|
return { content, map, dependencies, hash };
|
package/src/resource_loader.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
export interface ResourceLoader {
|
|
2
|
+
get(file: string): Promise<string>;
|
|
3
|
+
getModifiedResourceFiles(): Set<string>;
|
|
4
|
+
getResourceDependencies(file: string): Iterable<string>;
|
|
5
|
+
setAffectedResources(file: string, resources: Iterable<string>): void;
|
|
6
|
+
update(parentCompilation: import('webpack').compilation.Compilation, changedFiles?: Iterable<string>): void;
|
|
7
|
+
}
|
|
8
|
+
export declare class NoopResourceLoader implements ResourceLoader {
|
|
9
|
+
get(): Promise<string>;
|
|
10
|
+
getModifiedResourceFiles(): Set<string>;
|
|
11
|
+
getResourceDependencies(): Iterable<string>;
|
|
12
|
+
setAffectedResources(): void;
|
|
13
|
+
update(): void;
|
|
14
|
+
}
|
|
1
15
|
export declare class WebpackResourceLoader {
|
|
2
16
|
private _parentCompilation;
|
|
3
17
|
private _fileDependencies;
|
package/src/resource_loader.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WebpackResourceLoader = void 0;
|
|
3
|
+
exports.WebpackResourceLoader = exports.NoopResourceLoader = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright Google Inc. All Rights Reserved.
|
|
@@ -19,6 +19,20 @@ const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
|
|
|
19
19
|
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
|
|
20
20
|
const LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
|
|
21
21
|
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
|
|
22
|
+
class NoopResourceLoader {
|
|
23
|
+
async get() {
|
|
24
|
+
return '';
|
|
25
|
+
}
|
|
26
|
+
getModifiedResourceFiles() {
|
|
27
|
+
return new Set();
|
|
28
|
+
}
|
|
29
|
+
getResourceDependencies() {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
setAffectedResources() { }
|
|
33
|
+
update() { }
|
|
34
|
+
}
|
|
35
|
+
exports.NoopResourceLoader = NoopResourceLoader;
|
|
22
36
|
class WebpackResourceLoader {
|
|
23
37
|
constructor() {
|
|
24
38
|
this._fileDependencies = new Map();
|