@ngtools/webpack 8.2.0-next.1 → 8.2.2

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": "8.2.0-next.1",
3
+ "version": "8.2.2",
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": "8.2.0-next.1",
28
+ "@angular-devkit/core": "8.2.2",
29
29
  "enhanced-resolve": "4.1.0",
30
30
  "rxjs": "6.4.0",
31
31
  "tree-kill": "1.2.1",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@angular/compiler-cli": "^8.0.0-beta.0 || ^8.1.0-beta.0 || ^8.2.0-beta.0 || ^8.3.0-beta.0 || ^8.4.0-beta.0 || >=9.0.0-beta < 9",
36
- "typescript": ">=3.4 < 3.5",
36
+ "typescript": ">=3.4 < 3.6",
37
37
  "webpack": "^4.0.0"
38
38
  },
39
39
  "engines": {
@@ -22,6 +22,7 @@ export declare class AngularCompilerPlugin {
22
22
  private _JitMode;
23
23
  private _emitSkipped;
24
24
  private _hadFullJitEmit;
25
+ private _unusedFiles;
25
26
  private _changedFileExtensions;
26
27
  private _firstRun;
27
28
  private _donePromise;
@@ -55,6 +56,7 @@ export declare class AngularCompilerPlugin {
55
56
  private _createForkedTypeChecker;
56
57
  private _killForkedTypeChecker;
57
58
  private _updateForkedTypeChecker;
59
+ private _warnOnUnusedFiles;
58
60
  apply(compiler: Compiler & {
59
61
  watchMode?: boolean;
60
62
  parentCompilation?: compilation.Compilation;
@@ -42,6 +42,7 @@ class AngularCompilerPlugin {
42
42
  this._platformTransformers = null;
43
43
  this._JitMode = false;
44
44
  this._emitSkipped = true;
45
+ this._unusedFiles = new Set();
45
46
  this._changedFileExtensions = new Set(['ts', 'tsx', 'html', 'css', 'js', 'json']);
46
47
  // Webpack plugin.
47
48
  this._firstRun = true;
@@ -236,8 +237,6 @@ class AngularCompilerPlugin {
236
237
  if (this._forkTypeChecker && this._typeCheckerProcess && !this._firstRun) {
237
238
  this._updateForkedTypeChecker(this._rootNames, this._getChangedCompilationFiles());
238
239
  }
239
- // Use an identity function as all our paths are absolute already.
240
- this._moduleResolutionCache = ts.createModuleResolutionCache(this._basePath, x => x);
241
240
  const oldTsProgram = this._getTsProgram();
242
241
  if (this._JitMode) {
243
242
  // Create the TypeScript program.
@@ -429,6 +428,47 @@ class AngularCompilerPlugin {
429
428
  this._typeCheckerProcess.send(new type_checker_messages_1.UpdateMessage(rootNames, changedCompilationFiles));
430
429
  }
431
430
  }
431
+ _warnOnUnusedFiles(compilation) {
432
+ // Only do the unused TS files checks when under Ivy
433
+ // since previously we did include unused files in the compilation
434
+ // See: https://github.com/angular/angular-cli/pull/15030
435
+ if (!this._compilerOptions.enableIvy) {
436
+ return;
437
+ }
438
+ const program = this._getTsProgram();
439
+ if (!program) {
440
+ return;
441
+ }
442
+ // Exclude the following files from unused checks
443
+ // - ngfactories & ngstyle might not have a correspondent
444
+ // JS file example `@angular/core/core.ngfactory.ts`.
445
+ // - .d.ts files might not have a correspondent JS file due to bundling.
446
+ // - __ng_typecheck__.ts will never be requested.
447
+ const fileExcludeRegExp = /(\.(d|ngfactory|ngstyle)\.ts|ng_typecheck__\.ts)$/;
448
+ const usedFiles = new Set();
449
+ for (const compilationModule of compilation.modules) {
450
+ if (!compilationModule.resource) {
451
+ continue;
452
+ }
453
+ usedFiles.add(utils_1.forwardSlashPath(compilationModule.resource));
454
+ // We need the below for dependencies which
455
+ // are not emitted such as type only TS files
456
+ for (const dependency of compilationModule.buildInfo.fileDependencies) {
457
+ usedFiles.add(utils_1.forwardSlashPath(dependency));
458
+ }
459
+ }
460
+ const sourceFiles = program.getSourceFiles();
461
+ for (const { fileName } of sourceFiles) {
462
+ if (fileExcludeRegExp.test(fileName)
463
+ || usedFiles.has(fileName)
464
+ || this._unusedFiles.has(fileName)) {
465
+ continue;
466
+ }
467
+ compilation.warnings.push(`${fileName} is part of the TypeScript compilation but it's unused.\n` +
468
+ `Add only entry points to the 'files' or 'include' properties in your tsconfig.`);
469
+ this._unusedFiles.add(fileName);
470
+ }
471
+ }
432
472
  // Registration hook for webpack plugin.
433
473
  // tslint:disable-next-line:no-big-function
434
474
  apply(compiler) {
@@ -444,6 +484,7 @@ class AngularCompilerPlugin {
444
484
  // cleanup if not watching
445
485
  compiler.hooks.thisCompilation.tap('angular-compiler', compilation => {
446
486
  compilation.hooks.finishModules.tap('angular-compiler', () => {
487
+ this._warnOnUnusedFiles(compilation);
447
488
  let rootCompiler = compiler;
448
489
  while (rootCompiler.parentCompilation) {
449
490
  // tslint:disable-next-line:no-any
@@ -491,8 +532,10 @@ class AngularCompilerPlugin {
491
532
  if (this._compilerOptions.enableIvy) {
492
533
  ngccProcessor = new ngcc_processor_1.NgccProcessor(this._mainFields, compilerWithFileSystems.inputFileSystem, this._warnings, this._errors, this._basePath, this._compilerOptions);
493
534
  }
535
+ // Use an identity function as all our paths are absolute already.
536
+ this._moduleResolutionCache = ts.createModuleResolutionCache(this._basePath, x => x);
494
537
  // Create the webpack compiler host.
495
- const webpackCompilerHost = new compiler_host_1.WebpackCompilerHost(this._compilerOptions, this._basePath, host, true, this._options.directTemplateLoading, ngccProcessor);
538
+ const webpackCompilerHost = new compiler_host_1.WebpackCompilerHost(this._compilerOptions, this._basePath, host, true, this._options.directTemplateLoading, ngccProcessor, this._moduleResolutionCache);
496
539
  // Create and set a new WebpackResourceLoader in AOT
497
540
  if (!this._JitMode) {
498
541
  this._resourceLoader = new resource_loader_1.WebpackResourceLoader();
@@ -908,8 +951,7 @@ class AngularCompilerPlugin {
908
951
  ...resourceImports,
909
952
  ...this.getResourceDependencies(this._compilerHost.denormalizePath(resolvedFileName)),
910
953
  ].map((p) => p && this._compilerHost.denormalizePath(p)));
911
- return [...uniqueDependencies]
912
- .filter(x => !!x);
954
+ return [...uniqueDependencies];
913
955
  }
914
956
  getResourceDependencies(fileName) {
915
957
  if (!this._resourceLoader) {
@@ -19,6 +19,7 @@ export declare class WebpackCompilerHost implements ts.CompilerHost {
19
19
  private readonly cacheSourceFiles;
20
20
  private readonly directTemplateLoading;
21
21
  private readonly ngccProcessor?;
22
+ private readonly moduleResolutionCache?;
22
23
  private _syncHost;
23
24
  private _memoryHost;
24
25
  private _changedFiles;
@@ -27,7 +28,8 @@ export declare class WebpackCompilerHost implements ts.CompilerHost {
27
28
  private _resourceLoader?;
28
29
  private _sourceFileCache;
29
30
  private _virtualFileExtensions;
30
- constructor(_options: ts.CompilerOptions, basePath: string, host: virtualFs.Host, cacheSourceFiles: boolean, directTemplateLoading?: boolean, ngccProcessor?: NgccProcessor | undefined);
31
+ private _virtualStyleFileExtensions;
32
+ constructor(_options: ts.CompilerOptions, basePath: string, host: virtualFs.Host, cacheSourceFiles: boolean, directTemplateLoading?: boolean, ngccProcessor?: NgccProcessor | undefined, moduleResolutionCache?: ts.ModuleResolutionCache | undefined);
31
33
  private readonly virtualFiles;
32
34
  denormalizePath(path: string): string;
33
35
  resolve(path: string): Path;
@@ -13,11 +13,12 @@ const ts = require("typescript");
13
13
  const utils_1 = require("./utils");
14
14
  const dev = Math.floor(Math.random() * 10000);
15
15
  class WebpackCompilerHost {
16
- constructor(_options, basePath, host, cacheSourceFiles, directTemplateLoading = false, ngccProcessor) {
16
+ constructor(_options, basePath, host, cacheSourceFiles, directTemplateLoading = false, ngccProcessor, moduleResolutionCache) {
17
17
  this._options = _options;
18
18
  this.cacheSourceFiles = cacheSourceFiles;
19
19
  this.directTemplateLoading = directTemplateLoading;
20
20
  this.ngccProcessor = ngccProcessor;
21
+ this.moduleResolutionCache = moduleResolutionCache;
21
22
  this._changedFiles = new Set();
22
23
  this._readResourceFiles = new Set();
23
24
  this._sourceFileCache = new Map();
@@ -26,10 +27,12 @@ class WebpackCompilerHost {
26
27
  '.js.map',
27
28
  '.ngfactory.js',
28
29
  '.ngfactory.js.map',
29
- '.ngstyle.js',
30
- '.ngstyle.js.map',
31
30
  '.ngsummary.json',
32
31
  ];
32
+ this._virtualStyleFileExtensions = [
33
+ '.shim.ngstyle.js',
34
+ '.shim.ngstyle.js.map',
35
+ ];
33
36
  this._syncHost = new core_1.virtualFs.SyncDelegateHost(host);
34
37
  this._memoryHost = new core_1.virtualFs.SyncDelegateHost(new core_1.virtualFs.SimpleMemoryHost());
35
38
  this._basePath = core_1.normalize(basePath);
@@ -84,6 +87,9 @@ class WebpackCompilerHost {
84
87
  }
85
88
  });
86
89
  }
90
+ if (fullPath.endsWith('.ts')) {
91
+ return;
92
+ }
87
93
  // In case resolveJsonModule and allowJs we also need to remove virtual emitted files
88
94
  // both if they exists or not.
89
95
  if ((fullPath.endsWith('.js') || fullPath.endsWith('.json')) &&
@@ -91,6 +97,13 @@ class WebpackCompilerHost {
91
97
  if (this._memoryHost.exists(fullPath)) {
92
98
  this._memoryHost.delete(fullPath);
93
99
  }
100
+ return;
101
+ }
102
+ for (const ext of this._virtualStyleFileExtensions) {
103
+ const virtualFile = (fullPath + ext);
104
+ if (this._memoryHost.exists(virtualFile)) {
105
+ this._memoryHost.delete(virtualFile);
106
+ }
94
107
  }
95
108
  }
96
109
  fileExists(fileName, delegate = true) {
@@ -313,7 +326,7 @@ class WebpackCompilerHost {
313
326
  }
314
327
  resolveModuleNames(moduleNames, containingFile) {
315
328
  return moduleNames.map(moduleName => {
316
- const { resolvedModule } = ts.resolveModuleName(moduleName, utils_1.workaroundResolve(containingFile), this._options, this);
329
+ const { resolvedModule } = ts.resolveModuleName(moduleName, utils_1.workaroundResolve(containingFile), this._options, this, this.moduleResolutionCache);
317
330
  if (this._options.enableIvy && resolvedModule && this.ngccProcessor) {
318
331
  this.ngccProcessor.processModule(moduleName, resolvedModule);
319
332
  }
@@ -77,15 +77,21 @@ class WebpackResourceLoader {
77
77
  // Compile and return a promise
78
78
  return new Promise((resolve, reject) => {
79
79
  childCompiler.compile((err, childCompilation) => {
80
+ if (err) {
81
+ reject(err);
82
+ return;
83
+ }
80
84
  // Resolve / reject the promise
81
- if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
82
- const errorDetails = childCompilation.errors.map(function (error) {
83
- return error.message + (error.error ? ':\n' + error.error : '');
84
- }).join('\n');
85
- reject(new Error('Child compilation failed:\n' + errorDetails));
85
+ const { warnings, errors } = childCompilation;
86
+ if (warnings && warnings.length) {
87
+ this._parentCompilation.warnings.push(...warnings);
86
88
  }
87
- else if (err) {
88
- reject(err);
89
+ if (errors && errors.length) {
90
+ this._parentCompilation.errors.push(...errors);
91
+ const errorDetails = errors
92
+ .map((error) => error.message + (error.error ? ':\n' + error.error : ''))
93
+ .join('\n');
94
+ reject(new Error('Child compilation failed:\n' + errorDetails));
89
95
  }
90
96
  else {
91
97
  Object.keys(childCompilation.assets).forEach(assetName => {
@@ -17,7 +17,6 @@ function downlevelConstructorParameters(getTypeChecker) {
17
17
  exports.downlevelConstructorParameters = downlevelConstructorParameters;
18
18
  // The following is sourced from tsickle with local modifications
19
19
  // Only the creation of `ctorParameters` is retained
20
- // tslint:disable-next-line:max-line-length
21
20
  // https://github.com/angular/tsickle/blob/0ceb7d6bc47f6945a6c4c09689f1388eb48f5c07/src/decorator_downlevel_transformer.ts
22
21
  //
23
22
  /**
@@ -10,6 +10,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  const path_1 = require("path");
11
11
  const ts = require("typescript");
12
12
  const utils_1 = require("../utils");
13
+ // Check if a ts.Symbol is an alias.
14
+ const isAlias = (symbol) => symbol.flags & ts.SymbolFlags.Alias;
13
15
  /**
14
16
  * Given this original source code:
15
17
  *
@@ -153,14 +155,24 @@ function replaceImport(node, context, emitWarning, fileName, typeChecker) {
153
155
  const importStringLit = importCall.arguments[0];
154
156
  // Try to resolve the import. It might be a reexport from somewhere and the ngfactory will only
155
157
  // be present next to the original module.
156
- const exportedSymbol = typeChecker.getSymbolAtLocation(exportNameId);
158
+ let exportedSymbol = typeChecker.getSymbolAtLocation(exportNameId);
157
159
  if (!exportedSymbol) {
158
160
  return warnAndBail();
159
161
  }
162
+ // Named exports are also a declaration in the re-exporting module so we have to follow the
163
+ // re-exports to find the original symbol.
164
+ if (isAlias(exportedSymbol)) {
165
+ exportedSymbol = typeChecker.getAliasedSymbol(exportedSymbol);
166
+ if (!exportedSymbol) {
167
+ return warnAndBail();
168
+ }
169
+ }
170
+ // Find declarations of the original symbol so we can get their source file name.
160
171
  const exportedSymbolDecl = exportedSymbol.getDeclarations();
161
172
  if (!exportedSymbolDecl || exportedSymbolDecl.length === 0) {
162
173
  return warnAndBail();
163
174
  }
175
+ // Let's guess the first declaration is the one we want, because we don't have a better criteria.
164
176
  // Get the relative path from the containing module to the imported module.
165
177
  const relativePath = path_1.relative(path_1.dirname(fileName), exportedSymbolDecl[0].getSourceFile().fileName);
166
178
  // node's `relative` call doesn't actually add `./` so we add it here.