@ngtools/webpack 11.1.0 → 11.1.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ngtools/webpack",
3
- "version": "11.1.0",
3
+ "version": "11.1.4",
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,18 +25,18 @@
25
25
  },
26
26
  "homepage": "https://github.com/angular/angular-cli",
27
27
  "dependencies": {
28
- "@angular-devkit/core": "11.1.0",
28
+ "@angular-devkit/core": "11.1.4",
29
29
  "enhanced-resolve": "5.6.0",
30
30
  "webpack-sources": "2.2.0"
31
31
  },
32
32
  "peerDependencies": {
33
- "@angular/compiler-cli": "^11.0.0 || ^11.1.0-next",
33
+ "@angular/compiler-cli": "^11.0.0",
34
34
  "typescript": "~4.0.0 || ~4.1.0",
35
35
  "webpack": "^4.0.0"
36
36
  },
37
37
  "engines": {
38
38
  "node": ">= 10.13.0",
39
- "npm": ">= 6.11.0",
39
+ "npm": "^6.11.0",
40
40
  "yarn": ">= 1.13.0"
41
41
  }
42
42
  }
@@ -16,6 +16,7 @@ export interface AngularPluginOptions {
16
16
  emitClassMetadata: boolean;
17
17
  emitNgModuleScope: boolean;
18
18
  suppressZoneJsIncompatibilityWarning: boolean;
19
+ jitMode: boolean;
19
20
  }
20
21
  export declare class AngularWebpackPlugin {
21
22
  private readonly pluginOptions;
package/src/ivy/plugin.js CHANGED
@@ -42,6 +42,7 @@ class AngularWebpackPlugin {
42
42
  this.pluginOptions = {
43
43
  emitClassMetadata: false,
44
44
  emitNgModuleScope: false,
45
+ jitMode: false,
45
46
  fileReplacements: {},
46
47
  substitutions: {},
47
48
  directTemplateLoading: true,
@@ -136,7 +137,7 @@ class AngularWebpackPlugin {
136
137
  host_1.augmentHostWithReplacements(host, this.pluginOptions.fileReplacements, moduleResolutionCache);
137
138
  host_1.augmentHostWithSubstitutions(host, this.pluginOptions.substitutions);
138
139
  // Create the file emitter used by the webpack loader
139
- const { fileEmitter, builder, internalFiles } = compilerOptions.skipTemplateCodegen
140
+ const { fileEmitter, builder, internalFiles } = this.pluginOptions.jitMode
140
141
  ? this.updateJitProgram(compilerOptions, rootNames, host, diagnosticsReporter)
141
142
  : this.updateAotProgram(compilerOptions, rootNames, host, diagnosticsReporter, resourceLoader);
142
143
  const allProgramFiles = builder
@@ -23,7 +23,7 @@ function createAotTransformers(builder, options) {
23
23
  const removeNgModuleScope = !options.emitNgModuleScope;
24
24
  if (removeClassMetadata || removeNgModuleScope) {
25
25
  // tslint:disable-next-line: no-non-null-assertion
26
- transformers.after.push(remove_ivy_jit_support_calls_1.removeIvyJitSupportCalls(removeClassMetadata, removeNgModuleScope, getTypeChecker));
26
+ transformers.before.push(remove_ivy_jit_support_calls_1.removeIvyJitSupportCalls(removeClassMetadata, removeNgModuleScope, getTypeChecker));
27
27
  }
28
28
  return transformers;
29
29
  }
@@ -1,11 +1,9 @@
1
1
  export declare class WebpackResourceLoader {
2
2
  private _parentCompilation;
3
- private _context;
4
3
  private _fileDependencies;
5
4
  private _reverseDependencies;
6
- private _cachedSources;
7
- private _cachedEvaluatedSources;
8
- changedFiles?: Iterable<string>;
5
+ private cache;
6
+ private modifiedResources;
9
7
  update(parentCompilation: import('webpack').compilation.Compilation, changedFiles?: Iterable<string>): void;
10
8
  getModifiedResourceFiles(): Set<string>;
11
9
  getResourceDependencies(filePath: string): never[] | Set<string>;
@@ -21,27 +21,29 @@ const LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
21
21
  const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
22
22
  class WebpackResourceLoader {
23
23
  constructor() {
24
- this._context = '';
25
24
  this._fileDependencies = new Map();
26
25
  this._reverseDependencies = new Map();
27
- this._cachedSources = new Map();
28
- this._cachedEvaluatedSources = new Map();
26
+ this.cache = new Map();
27
+ this.modifiedResources = new Set();
29
28
  }
30
29
  update(parentCompilation, changedFiles) {
31
30
  this._parentCompilation = parentCompilation;
32
- this._context = parentCompilation.context;
33
- // Update changed file list
34
- this.changedFiles = changedFiles;
35
- }
36
- getModifiedResourceFiles() {
37
- const modifiedResources = new Set();
38
- if (!this.changedFiles) {
39
- return modifiedResources;
31
+ // Update resource cache and modified resources
32
+ this.modifiedResources.clear();
33
+ if (changedFiles) {
34
+ for (const changedFile of changedFiles) {
35
+ for (const affectedResource of this.getAffectedResources(changedFile)) {
36
+ this.cache.delete(paths_1.normalizePath(affectedResource));
37
+ this.modifiedResources.add(affectedResource);
38
+ }
39
+ }
40
40
  }
41
- for (const changedFile of this.changedFiles) {
42
- this.getAffectedResources(changedFile).forEach((affected) => modifiedResources.add(affected));
41
+ else {
42
+ this.cache.clear();
43
43
  }
44
- return modifiedResources;
44
+ }
45
+ getModifiedResourceFiles() {
46
+ return this.modifiedResources;
45
47
  }
46
48
  getResourceDependencies(filePath) {
47
49
  return this._fileDependencies.get(filePath) || [];
@@ -53,6 +55,7 @@ class WebpackResourceLoader {
53
55
  this._reverseDependencies.set(file, new Set(resources));
54
56
  }
55
57
  async _compile(filePath) {
58
+ var _a;
56
59
  if (!this._parentCompilation) {
57
60
  throw new Error('WebpackResourceLoader cannot be used without parentCompilation');
58
61
  }
@@ -61,34 +64,29 @@ class WebpackResourceLoader {
61
64
  return Promise.reject(`Cannot use a JavaScript or TypeScript file (${filePath}) in a component's styleUrls or templateUrl.`);
62
65
  }
63
66
  const outputOptions = { filename: filePath };
64
- const relativePath = path.relative(this._context || '', filePath);
67
+ const context = this._parentCompilation.context;
68
+ const relativePath = path.relative(context || '', filePath);
65
69
  const childCompiler = this._parentCompilation.createChildCompiler(relativePath, outputOptions);
66
- childCompiler.context = this._context;
70
+ childCompiler.context = context;
67
71
  new NodeTemplatePlugin(outputOptions).apply(childCompiler);
68
72
  new NodeTargetPlugin().apply(childCompiler);
69
- new SingleEntryPlugin(this._context, filePath).apply(childCompiler);
73
+ new SingleEntryPlugin(context, filePath).apply(childCompiler);
70
74
  new LibraryTemplatePlugin('resource', 'var').apply(childCompiler);
71
75
  childCompiler.hooks.thisCompilation.tap('ngtools-webpack', (compilation) => {
72
- compilation.hooks.additionalAssets.tapAsync('ngtools-webpack', (callback) => {
73
- if (this._cachedEvaluatedSources.has(compilation.fullHash)) {
74
- const cachedEvaluatedSource = this._cachedEvaluatedSources.get(compilation.fullHash);
75
- compilation.assets[filePath] = cachedEvaluatedSource;
76
- callback();
76
+ compilation.hooks.additionalAssets.tap('ngtools-webpack', () => {
77
+ const asset = compilation.assets[filePath];
78
+ if (!asset) {
77
79
  return;
78
80
  }
79
- const asset = compilation.assets[filePath];
80
- if (asset) {
81
- this._evaluate({ outputName: filePath, source: asset.source() })
82
- .then(output => {
83
- const evaluatedSource = new webpack_sources_1.RawSource(output);
84
- this._cachedEvaluatedSources.set(compilation.fullHash, evaluatedSource);
85
- compilation.assets[filePath] = evaluatedSource;
86
- callback();
87
- })
88
- .catch(err => callback(err));
81
+ try {
82
+ const output = this._evaluate(filePath, asset.source());
83
+ if (typeof output === 'string') {
84
+ compilation.assets[filePath] = new webpack_sources_1.RawSource(output);
85
+ }
89
86
  }
90
- else {
91
- callback();
87
+ catch (error) {
88
+ // Use compilation errors, as otherwise webpack will choke
89
+ compilation.errors.push(error);
92
90
  }
93
91
  });
94
92
  });
@@ -111,12 +109,12 @@ class WebpackResourceLoader {
111
109
  if (errors && errors.length) {
112
110
  this._parentCompilation.errors.push(...errors);
113
111
  }
114
- Object.keys(childCompilation.assets).forEach(assetName => {
112
+ Object.keys(childCompilation.assets).forEach((assetName) => {
115
113
  // Add all new assets to the parent compilation, with the exception of
116
114
  // the file we're loading and its sourcemap.
117
- if (assetName !== filePath
118
- && assetName !== `${filePath}.map`
119
- && this._parentCompilation.assets[assetName] == undefined) {
115
+ if (assetName !== filePath &&
116
+ assetName !== `${filePath}.map` &&
117
+ this._parentCompilation.assets[assetName] == undefined) {
120
118
  this._parentCompilation.assets[assetName] = childCompilation.assets[assetName];
121
119
  }
122
120
  });
@@ -132,33 +130,41 @@ class WebpackResourceLoader {
132
130
  this._reverseDependencies.set(resolvedFile, new Set([filePath]));
133
131
  }
134
132
  }
135
- const compilationHash = childCompilation.fullHash;
136
- const maybeSource = this._cachedSources.get(compilationHash);
137
- if (maybeSource) {
138
- return { outputName: filePath, source: maybeSource };
139
- }
140
- else {
141
- const source = childCompilation.assets[filePath].source();
142
- this._cachedSources.set(compilationHash, source);
143
- return { outputName: filePath, source };
144
- }
133
+ const finalOutput = (_a = childCompilation.assets[filePath]) === null || _a === void 0 ? void 0 : _a.source();
134
+ return { outputName: filePath, source: finalOutput !== null && finalOutput !== void 0 ? finalOutput : '', success: !(errors === null || errors === void 0 ? void 0 : errors.length) };
145
135
  }
146
- async _evaluate({ outputName, source }) {
136
+ _evaluate(filename, source) {
147
137
  var _a;
148
138
  // Evaluate code
149
139
  const context = {};
150
- vm.runInNewContext(source, context, { filename: outputName });
140
+ try {
141
+ vm.runInNewContext(source, context, { filename });
142
+ }
143
+ catch (_b) {
144
+ // Error are propagated through the child compilation.
145
+ return null;
146
+ }
151
147
  if (typeof context.resource === 'string') {
152
148
  return context.resource;
153
149
  }
154
150
  else if (typeof ((_a = context.resource) === null || _a === void 0 ? void 0 : _a.default) === 'string') {
155
151
  return context.resource.default;
156
152
  }
157
- throw new Error(`The loader "${outputName}" didn't return a string.`);
153
+ throw new Error(`The loader "${filename}" didn't return a string.`);
158
154
  }
159
- get(filePath) {
160
- return this._compile(filePath)
161
- .then((result) => result.source);
155
+ async get(filePath) {
156
+ const normalizedFile = paths_1.normalizePath(filePath);
157
+ let data = this.cache.get(normalizedFile);
158
+ if (data === undefined) {
159
+ // cache miss so compile resource
160
+ const compilationResult = await this._compile(filePath);
161
+ data = compilationResult.source;
162
+ // Only cache if compilation was successful
163
+ if (compilationResult.success) {
164
+ this.cache.set(normalizedFile, data);
165
+ }
166
+ }
167
+ return data;
162
168
  }
163
169
  }
164
170
  exports.WebpackResourceLoader = WebpackResourceLoader;
@@ -102,6 +102,10 @@ function elideImports(sourceFile, removedNodes, getTypeChecker, compilerOptions)
102
102
  return [];
103
103
  }
104
104
  const isUnused = (node) => {
105
+ // Do not remove JSX factory imports
106
+ if (node.text === compilerOptions.jsxFactory) {
107
+ return false;
108
+ }
105
109
  const symbol = typeChecker.getSymbolAtLocation(node);
106
110
  return symbol && !usedSymbols.has(symbol);
107
111
  };
@@ -1,6 +1,6 @@
1
1
  import * as ts from 'typescript';
2
2
  import { WebpackCompilerHost } from '../compiler_host';
3
- export declare function createTypescriptContext(content: string, additionalFiles?: Record<string, string>, useLibs?: boolean, extraCompilerOptions?: ts.CompilerOptions): {
3
+ export declare function createTypescriptContext(content: string, additionalFiles?: Record<string, string>, useLibs?: boolean, extraCompilerOptions?: ts.CompilerOptions, jsxFile?: boolean): {
4
4
  compilerHost: WebpackCompilerHost;
5
5
  program: ts.Program;
6
6
  };
@@ -15,10 +15,11 @@ const ts = require("typescript");
15
15
  const compiler_host_1 = require("../compiler_host");
16
16
  // Test transform helpers.
17
17
  const basePath = '/project/src/';
18
- const fileName = basePath + 'test-file.ts';
18
+ const basefileName = basePath + 'test-file.ts';
19
19
  const typeScriptLibFiles = loadTypeScriptLibFiles();
20
20
  const tsLibFiles = loadTsLibFiles();
21
- function createTypescriptContext(content, additionalFiles, useLibs = false, extraCompilerOptions = {}) {
21
+ function createTypescriptContext(content, additionalFiles, useLibs = false, extraCompilerOptions = {}, jsxFile = false) {
22
+ const fileName = basefileName + (jsxFile ? 'x' : '');
22
23
  // Set compiler options.
23
24
  const compilerOptions = {
24
25
  noEmitOnError: useLibs,
@@ -81,7 +82,7 @@ function transformTypescript(content, transformers, program, compilerHost) {
81
82
  throw new Error(ts.formatDiagnostics(diagnostics, compilerHost));
82
83
  }
83
84
  // Return the transpiled js.
84
- return compilerHost.readFile(fileName.replace(/\.tsx?$/, '.js'));
85
+ return compilerHost.readFile(basefileName.replace(/\.tsx?$/, '.js'));
85
86
  }
86
87
  exports.transformTypescript = transformTypescript;
87
88
  function loadTypeScriptLibFiles() {