@ngtools/webpack 14.0.3 → 14.0.4
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.js +24 -18
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.js
CHANGED
|
@@ -115,24 +115,30 @@ class NgccProcessor {
|
|
|
115
115
|
// that we cannot setup multiple cluster masters with different options.
|
|
116
116
|
// - We will not be able to have concurrent builds otherwise Ex: App-Shell,
|
|
117
117
|
// 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
|
-
|
|
118
|
+
const originalProcessTitle = process.title;
|
|
119
|
+
try {
|
|
120
|
+
const { status, error } = (0, child_process_1.spawnSync)(process.execPath, [
|
|
121
|
+
this.compilerNgcc.ngccMainFilePath,
|
|
122
|
+
'--source' /** basePath */,
|
|
123
|
+
this._nodeModulesDirectory,
|
|
124
|
+
'--properties' /** propertiesToConsider */,
|
|
125
|
+
...this.propertiesToConsider,
|
|
126
|
+
'--first-only' /** compileAllFormats */,
|
|
127
|
+
'--create-ivy-entry-points' /** createNewEntryPointFormats */,
|
|
128
|
+
'--async',
|
|
129
|
+
'--tsconfig' /** tsConfigPath */,
|
|
130
|
+
this.tsConfigPath,
|
|
131
|
+
'--use-program-dependencies',
|
|
132
|
+
], {
|
|
133
|
+
stdio: ['inherit', process.stderr, process.stderr],
|
|
134
|
+
});
|
|
135
|
+
if (status !== 0) {
|
|
136
|
+
const errorMessage = (error === null || error === void 0 ? void 0 : error.message) || '';
|
|
137
|
+
throw new Error(errorMessage + `NGCC failed${errorMessage ? ', see above' : ''}.`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
process.title = originalProcessTitle;
|
|
136
142
|
}
|
|
137
143
|
(0, benchmark_1.timeEnd)(timeLabel);
|
|
138
144
|
// ngcc was successful so if a run hash was generated, write it for next time
|