@ngtools/webpack 14.0.3 → 14.0.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 +1 -1
- package/src/ivy/plugin.d.ts +1 -0
- package/src/ivy/plugin.js +116 -109
- package/src/ngcc_processor.d.ts +1 -1
- package/src/ngcc_processor.js +34 -24
package/package.json
CHANGED
package/src/ivy/plugin.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ export declare class AngularWebpackPlugin {
|
|
|
36
36
|
private get compilerCli();
|
|
37
37
|
get options(): AngularWebpackPluginOptions;
|
|
38
38
|
apply(compiler: Compiler): void;
|
|
39
|
+
private setupCompilation;
|
|
39
40
|
private registerWithCompilation;
|
|
40
41
|
private markResourceUsed;
|
|
41
42
|
private rebuildRequiredFiles;
|
package/src/ivy/plugin.js
CHANGED
|
@@ -97,9 +97,8 @@ class AngularWebpackPlugin {
|
|
|
97
97
|
get options() {
|
|
98
98
|
return this.pluginOptions;
|
|
99
99
|
}
|
|
100
|
-
// eslint-disable-next-line max-lines-per-function
|
|
101
100
|
apply(compiler) {
|
|
102
|
-
const { NormalModuleReplacementPlugin, util } = compiler.webpack;
|
|
101
|
+
const { NormalModuleReplacementPlugin, WebpackError, util } = compiler.webpack;
|
|
103
102
|
this.webpackCreateHash = util.createHash;
|
|
104
103
|
// Setup file replacements with webpack
|
|
105
104
|
for (const [key, value] of Object.entries(this.pluginOptions.fileReplacements)) {
|
|
@@ -126,124 +125,132 @@ class AngularWebpackPlugin {
|
|
|
126
125
|
});
|
|
127
126
|
// Load the compiler-cli if not already available
|
|
128
127
|
compiler.hooks.beforeCompile.tapPromise(PLUGIN_NAME, () => this.initializeCompilerCli());
|
|
129
|
-
|
|
130
|
-
let resourceLoader;
|
|
131
|
-
let previousUnused;
|
|
128
|
+
const compilationState = { pathsPlugin };
|
|
132
129
|
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
this.watchMode = compiler.watchMode;
|
|
136
|
-
// Initialize webpack cache
|
|
137
|
-
if (!this.webpackCache && compilation.options.cache) {
|
|
138
|
-
this.webpackCache = compilation.getCache(PLUGIN_NAME);
|
|
130
|
+
try {
|
|
131
|
+
this.setupCompilation(compilation, compilationState);
|
|
139
132
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
resourceLoader = new resource_loader_1.WebpackResourceLoader(this.watchMode);
|
|
133
|
+
catch (error) {
|
|
134
|
+
compilation.errors.push(new WebpackError(`Failed to initialize Angular compilation - ${error instanceof Error ? error.message : error}`));
|
|
143
135
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
setupCompilation(compilation, state) {
|
|
139
|
+
const compiler = compilation.compiler;
|
|
140
|
+
// Register plugin to ensure deterministic emit order in multi-plugin usage
|
|
141
|
+
const emitRegistration = this.registerWithCompilation(compilation);
|
|
142
|
+
this.watchMode = compiler.watchMode;
|
|
143
|
+
// Initialize webpack cache
|
|
144
|
+
if (!this.webpackCache && compilation.options.cache) {
|
|
145
|
+
this.webpackCache = compilation.getCache(PLUGIN_NAME);
|
|
146
|
+
}
|
|
147
|
+
// Initialize the resource loader if not already setup
|
|
148
|
+
if (!state.resourceLoader) {
|
|
149
|
+
state.resourceLoader = new resource_loader_1.WebpackResourceLoader(this.watchMode);
|
|
150
|
+
}
|
|
151
|
+
// Initialize and process eager ngcc if not already setup
|
|
152
|
+
if (!state.ngccProcessor) {
|
|
153
|
+
const { processor, errors, warnings } = initializeNgccProcessor(compiler, this.pluginOptions.tsconfig, this.compilerNgccModule);
|
|
154
|
+
processor.process();
|
|
155
|
+
warnings.forEach((warning) => (0, diagnostics_1.addWarning)(compilation, warning));
|
|
156
|
+
errors.forEach((error) => (0, diagnostics_1.addError)(compilation, error));
|
|
157
|
+
state.ngccProcessor = processor;
|
|
158
|
+
}
|
|
159
|
+
// Setup and read TypeScript and Angular compiler configuration
|
|
160
|
+
const { compilerOptions, rootNames, errors } = this.loadConfiguration();
|
|
161
|
+
// Create diagnostics reporter and report configuration file errors
|
|
162
|
+
const diagnosticsReporter = (0, diagnostics_1.createDiagnosticsReporter)(compilation, (diagnostic) => this.compilerCli.formatDiagnostics([diagnostic]));
|
|
163
|
+
diagnosticsReporter(errors);
|
|
164
|
+
// Update TypeScript path mapping plugin with new configuration
|
|
165
|
+
state.pathsPlugin.update(compilerOptions);
|
|
166
|
+
// Create a Webpack-based TypeScript compiler host
|
|
167
|
+
const system = (0, system_1.createWebpackSystem)(
|
|
168
|
+
// Webpack lacks an InputFileSytem type definition with sync functions
|
|
169
|
+
compiler.inputFileSystem, (0, paths_1.normalizePath)(compiler.context));
|
|
170
|
+
const host = ts.createIncrementalCompilerHost(compilerOptions, system);
|
|
171
|
+
// Setup source file caching and reuse cache from previous compilation if present
|
|
172
|
+
let cache = this.sourceFileCache;
|
|
173
|
+
let changedFiles;
|
|
174
|
+
if (cache) {
|
|
175
|
+
changedFiles = new Set();
|
|
176
|
+
for (const changedFile of [...compiler.modifiedFiles, ...compiler.removedFiles]) {
|
|
177
|
+
const normalizedChangedFile = (0, paths_1.normalizePath)(changedFile);
|
|
178
|
+
// Invalidate file dependencies
|
|
179
|
+
this.fileDependencies.delete(normalizedChangedFile);
|
|
180
|
+
// Invalidate existing cache
|
|
181
|
+
cache.invalidate(normalizedChangedFile);
|
|
182
|
+
changedFiles.add(normalizedChangedFile);
|
|
151
183
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
// Create a Webpack-based TypeScript compiler host
|
|
160
|
-
const system = (0, system_1.createWebpackSystem)(
|
|
161
|
-
// Webpack lacks an InputFileSytem type definition with sync functions
|
|
162
|
-
compiler.inputFileSystem, (0, paths_1.normalizePath)(compiler.context));
|
|
163
|
-
const host = ts.createIncrementalCompilerHost(compilerOptions, system);
|
|
164
|
-
// Setup source file caching and reuse cache from previous compilation if present
|
|
165
|
-
let cache = this.sourceFileCache;
|
|
166
|
-
let changedFiles;
|
|
167
|
-
if (cache) {
|
|
168
|
-
changedFiles = new Set();
|
|
169
|
-
for (const changedFile of [...compiler.modifiedFiles, ...compiler.removedFiles]) {
|
|
170
|
-
const normalizedChangedFile = (0, paths_1.normalizePath)(changedFile);
|
|
171
|
-
// Invalidate file dependencies
|
|
172
|
-
this.fileDependencies.delete(normalizedChangedFile);
|
|
173
|
-
// Invalidate existing cache
|
|
174
|
-
cache.invalidate(normalizedChangedFile);
|
|
175
|
-
changedFiles.add(normalizedChangedFile);
|
|
176
|
-
}
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
// Initialize a new cache
|
|
187
|
+
cache = new cache_1.SourceFileCache();
|
|
188
|
+
// Only store cache if in watch mode
|
|
189
|
+
if (this.watchMode) {
|
|
190
|
+
this.sourceFileCache = cache;
|
|
177
191
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
192
|
+
}
|
|
193
|
+
(0, host_1.augmentHostWithCaching)(host, cache);
|
|
194
|
+
const moduleResolutionCache = ts.createModuleResolutionCache(host.getCurrentDirectory(), host.getCanonicalFileName.bind(host), compilerOptions);
|
|
195
|
+
// Setup source file dependency collection
|
|
196
|
+
(0, host_1.augmentHostWithDependencyCollection)(host, this.fileDependencies, moduleResolutionCache);
|
|
197
|
+
// Setup on demand ngcc
|
|
198
|
+
(0, host_1.augmentHostWithNgcc)(host, state.ngccProcessor, moduleResolutionCache);
|
|
199
|
+
// Setup resource loading
|
|
200
|
+
state.resourceLoader.update(compilation, changedFiles);
|
|
201
|
+
(0, host_1.augmentHostWithResources)(host, state.resourceLoader, {
|
|
202
|
+
directTemplateLoading: this.pluginOptions.directTemplateLoading,
|
|
203
|
+
inlineStyleFileExtension: this.pluginOptions.inlineStyleFileExtension,
|
|
204
|
+
});
|
|
205
|
+
// Setup source file adjustment options
|
|
206
|
+
(0, host_1.augmentHostWithReplacements)(host, this.pluginOptions.fileReplacements, moduleResolutionCache);
|
|
207
|
+
(0, host_1.augmentHostWithSubstitutions)(host, this.pluginOptions.substitutions);
|
|
208
|
+
// Create the file emitter used by the webpack loader
|
|
209
|
+
const { fileEmitter, builder, internalFiles } = this.pluginOptions.jitMode
|
|
210
|
+
? this.updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter)
|
|
211
|
+
: this.updateAotProgram(compilerOptions, rootNames, host, diagnosticsReporter, state.resourceLoader);
|
|
212
|
+
// Set of files used during the unused TypeScript file analysis
|
|
213
|
+
const currentUnused = new Set();
|
|
214
|
+
for (const sourceFile of builder.getSourceFiles()) {
|
|
215
|
+
if (internalFiles === null || internalFiles === void 0 ? void 0 : internalFiles.has(sourceFile)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
// Ensure all program files are considered part of the compilation and will be watched.
|
|
219
|
+
// Webpack does not normalize paths. Therefore, we need to normalize the path with FS seperators.
|
|
220
|
+
compilation.fileDependencies.add((0, paths_1.externalizePath)(sourceFile.fileName));
|
|
221
|
+
// Add all non-declaration files to the initial set of unused files. The set will be
|
|
222
|
+
// analyzed and pruned after all Webpack modules are finished building.
|
|
223
|
+
if (!sourceFile.isDeclarationFile) {
|
|
224
|
+
currentUnused.add((0, paths_1.normalizePath)(sourceFile.fileName));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
compilation.hooks.finishModules.tapPromise(PLUGIN_NAME, async (modules) => {
|
|
228
|
+
var _a, _b;
|
|
229
|
+
// Rebuild any remaining AOT required modules
|
|
230
|
+
await this.rebuildRequiredFiles(modules, compilation, fileEmitter);
|
|
231
|
+
// Clear out the Webpack compilation to avoid an extra retaining reference
|
|
232
|
+
(_a = state.resourceLoader) === null || _a === void 0 ? void 0 : _a.clearParentCompilation();
|
|
233
|
+
// Analyze program for unused files
|
|
234
|
+
if (compilation.errors.length > 0) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
for (const webpackModule of modules) {
|
|
238
|
+
const resource = webpackModule.resource;
|
|
239
|
+
if (resource) {
|
|
240
|
+
this.markResourceUsed((0, paths_1.normalizePath)(resource), currentUnused);
|
|
184
241
|
}
|
|
185
242
|
}
|
|
186
|
-
(
|
|
187
|
-
|
|
188
|
-
// Setup source file dependency collection
|
|
189
|
-
(0, host_1.augmentHostWithDependencyCollection)(host, this.fileDependencies, moduleResolutionCache);
|
|
190
|
-
// Setup on demand ngcc
|
|
191
|
-
(0, host_1.augmentHostWithNgcc)(host, ngccProcessor, moduleResolutionCache);
|
|
192
|
-
// Setup resource loading
|
|
193
|
-
resourceLoader.update(compilation, changedFiles);
|
|
194
|
-
(0, host_1.augmentHostWithResources)(host, resourceLoader, {
|
|
195
|
-
directTemplateLoading: this.pluginOptions.directTemplateLoading,
|
|
196
|
-
inlineStyleFileExtension: this.pluginOptions.inlineStyleFileExtension,
|
|
197
|
-
});
|
|
198
|
-
// Setup source file adjustment options
|
|
199
|
-
(0, host_1.augmentHostWithReplacements)(host, this.pluginOptions.fileReplacements, moduleResolutionCache);
|
|
200
|
-
(0, host_1.augmentHostWithSubstitutions)(host, this.pluginOptions.substitutions);
|
|
201
|
-
// Create the file emitter used by the webpack loader
|
|
202
|
-
const { fileEmitter, builder, internalFiles } = this.pluginOptions.jitMode
|
|
203
|
-
? this.updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter)
|
|
204
|
-
: this.updateAotProgram(compilerOptions, rootNames, host, diagnosticsReporter, resourceLoader);
|
|
205
|
-
// Set of files used during the unused TypeScript file analysis
|
|
206
|
-
const currentUnused = new Set();
|
|
207
|
-
for (const sourceFile of builder.getSourceFiles()) {
|
|
208
|
-
if (internalFiles === null || internalFiles === void 0 ? void 0 : internalFiles.has(sourceFile)) {
|
|
243
|
+
for (const unused of currentUnused) {
|
|
244
|
+
if ((_b = state.previousUnused) === null || _b === void 0 ? void 0 : _b.has(unused)) {
|
|
209
245
|
continue;
|
|
210
246
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
compilation.fileDependencies.add((0, paths_1.externalizePath)(sourceFile.fileName));
|
|
214
|
-
// Add all non-declaration files to the initial set of unused files. The set will be
|
|
215
|
-
// analyzed and pruned after all Webpack modules are finished building.
|
|
216
|
-
if (!sourceFile.isDeclarationFile) {
|
|
217
|
-
currentUnused.add((0, paths_1.normalizePath)(sourceFile.fileName));
|
|
218
|
-
}
|
|
247
|
+
(0, diagnostics_1.addWarning)(compilation, `${unused} is part of the TypeScript compilation but it's unused.\n` +
|
|
248
|
+
`Add only entry points to the 'files' or 'include' properties in your tsconfig.`);
|
|
219
249
|
}
|
|
220
|
-
|
|
221
|
-
// Rebuild any remaining AOT required modules
|
|
222
|
-
await this.rebuildRequiredFiles(modules, compilation, fileEmitter);
|
|
223
|
-
// Clear out the Webpack compilation to avoid an extra retaining reference
|
|
224
|
-
resourceLoader === null || resourceLoader === void 0 ? void 0 : resourceLoader.clearParentCompilation();
|
|
225
|
-
// Analyze program for unused files
|
|
226
|
-
if (compilation.errors.length > 0) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
for (const webpackModule of modules) {
|
|
230
|
-
const resource = webpackModule.resource;
|
|
231
|
-
if (resource) {
|
|
232
|
-
this.markResourceUsed((0, paths_1.normalizePath)(resource), currentUnused);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
for (const unused of currentUnused) {
|
|
236
|
-
if (previousUnused && previousUnused.has(unused)) {
|
|
237
|
-
continue;
|
|
238
|
-
}
|
|
239
|
-
(0, diagnostics_1.addWarning)(compilation, `${unused} is part of the TypeScript compilation but it's unused.\n` +
|
|
240
|
-
`Add only entry points to the 'files' or 'include' properties in your tsconfig.`);
|
|
241
|
-
}
|
|
242
|
-
previousUnused = currentUnused;
|
|
243
|
-
});
|
|
244
|
-
// Store file emitter for loader usage
|
|
245
|
-
emitRegistration.update(fileEmitter);
|
|
250
|
+
state.previousUnused = currentUnused;
|
|
246
251
|
});
|
|
252
|
+
// Store file emitter for loader usage
|
|
253
|
+
emitRegistration.update(fileEmitter);
|
|
247
254
|
}
|
|
248
255
|
registerWithCompilation(compilation) {
|
|
249
256
|
let fileEmitters = compilationFileEmitters.get(compilation);
|
package/src/ngcc_processor.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare class NgccProcessor {
|
|
|
24
24
|
constructor(compilerNgcc: typeof import('@angular/compiler-cli/ngcc'), propertiesToConsider: string[], compilationWarnings: (Error | string)[], compilationErrors: (Error | string)[], basePath: string, tsConfigPath: string, inputFileSystem: InputFileSystem, resolver: ResolverWithOptions);
|
|
25
25
|
/** Process the entire node modules tree. */
|
|
26
26
|
process(): void;
|
|
27
|
-
/** Process a module and
|
|
27
|
+
/** Process a module and its dependencies. */
|
|
28
28
|
processModule(moduleName: string, resolvedModule: ts.ResolvedModule | ts.ResolvedTypeReferenceDirective): void;
|
|
29
29
|
invalidate(fileName: string): void;
|
|
30
30
|
/**
|
package/src/ngcc_processor.js
CHANGED
|
@@ -59,8 +59,10 @@ class NgccProcessor {
|
|
|
59
59
|
}
|
|
60
60
|
/** Process the entire node modules tree. */
|
|
61
61
|
process() {
|
|
62
|
-
// Under Bazel when running in sandbox mode parts of the filesystem is read-only
|
|
63
|
-
|
|
62
|
+
// Under Bazel when running in sandbox mode parts of the filesystem is read-only, or when using
|
|
63
|
+
// Yarn PnP there may not be a node_modules directory. ngcc can't run in those cases, so the
|
|
64
|
+
// processing is skipped.
|
|
65
|
+
if (process.env.BAZEL_TARGET || !this._nodeModulesDirectory) {
|
|
64
66
|
return;
|
|
65
67
|
}
|
|
66
68
|
// Skip if node_modules are read-only
|
|
@@ -115,24 +117,30 @@ class NgccProcessor {
|
|
|
115
117
|
// that we cannot setup multiple cluster masters with different options.
|
|
116
118
|
// - We will not be able to have concurrent builds otherwise Ex: App-Shell,
|
|
117
119
|
// as NGCC will create a lock file for both builds and it will cause builds to fails.
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
120
|
+
const originalProcessTitle = process.title;
|
|
121
|
+
try {
|
|
122
|
+
const { status, error } = (0, child_process_1.spawnSync)(process.execPath, [
|
|
123
|
+
this.compilerNgcc.ngccMainFilePath,
|
|
124
|
+
'--source' /** basePath */,
|
|
125
|
+
this._nodeModulesDirectory,
|
|
126
|
+
'--properties' /** propertiesToConsider */,
|
|
127
|
+
...this.propertiesToConsider,
|
|
128
|
+
'--first-only' /** compileAllFormats */,
|
|
129
|
+
'--create-ivy-entry-points' /** createNewEntryPointFormats */,
|
|
130
|
+
'--async',
|
|
131
|
+
'--tsconfig' /** tsConfigPath */,
|
|
132
|
+
this.tsConfigPath,
|
|
133
|
+
'--use-program-dependencies',
|
|
134
|
+
], {
|
|
135
|
+
stdio: ['inherit', process.stderr, process.stderr],
|
|
136
|
+
});
|
|
137
|
+
if (status !== 0) {
|
|
138
|
+
const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || '';
|
|
139
|
+
throw new Error(errorMessage + `NGCC failed${errorMessage ? ', see above' : ''}.`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
process.title = originalProcessTitle;
|
|
136
144
|
}
|
|
137
145
|
(0, benchmark_1.timeEnd)(timeLabel);
|
|
138
146
|
// ngcc was successful so if a run hash was generated, write it for next time
|
|
@@ -148,14 +156,16 @@ class NgccProcessor {
|
|
|
148
156
|
}
|
|
149
157
|
}
|
|
150
158
|
}
|
|
151
|
-
/** Process a module and
|
|
159
|
+
/** Process a module and its dependencies. */
|
|
152
160
|
processModule(moduleName, resolvedModule) {
|
|
153
161
|
var _a, _b;
|
|
154
162
|
const resolvedFileName = resolvedModule.resolvedFileName;
|
|
155
|
-
if (!
|
|
163
|
+
if (!this._nodeModulesDirectory ||
|
|
164
|
+
!resolvedFileName ||
|
|
156
165
|
moduleName.startsWith('.') ||
|
|
157
166
|
this._processedModules.has(resolvedFileName)) {
|
|
158
|
-
// Skip when
|
|
167
|
+
// Skip when module_modules directory is not present, module is unknown, relative or the
|
|
168
|
+
// NGCC compiler is not found or already processed.
|
|
159
169
|
return;
|
|
160
170
|
}
|
|
161
171
|
const packageJsonPath = this.tryResolvePackage(moduleName, resolvedFileName);
|
|
@@ -210,7 +220,7 @@ class NgccProcessor {
|
|
|
210
220
|
}
|
|
211
221
|
current = path.dirname(current);
|
|
212
222
|
}
|
|
213
|
-
|
|
223
|
+
return null;
|
|
214
224
|
}
|
|
215
225
|
findPackageManagerLockFile(projectBasePath) {
|
|
216
226
|
for (const lockFile of ['yarn.lock', 'pnpm-lock.yaml', 'package-lock.json']) {
|