@ngtools/webpack 11.1.4 → 11.2.0

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.4",
3
+ "version": "11.2.0",
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,12 +25,12 @@
25
25
  },
26
26
  "homepage": "https://github.com/angular/angular-cli",
27
27
  "dependencies": {
28
- "@angular-devkit/core": "11.1.4",
29
- "enhanced-resolve": "5.6.0",
28
+ "@angular-devkit/core": "11.2.0",
29
+ "enhanced-resolve": "5.7.0",
30
30
  "webpack-sources": "2.2.0"
31
31
  },
32
32
  "peerDependencies": {
33
- "@angular/compiler-cli": "^11.0.0",
33
+ "@angular/compiler-cli": "^11.0.0 || ^11.2.0-next",
34
34
  "typescript": "~4.0.0 || ~4.1.0",
35
35
  "webpack": "^4.0.0"
36
36
  },
@@ -98,13 +98,13 @@ class AngularCompilerPlugin {
98
98
  basePath = path.resolve(process.cwd(), options.basePath);
99
99
  }
100
100
  // Parse the tsconfig contents.
101
- const config = compiler_cli_1.readConfiguration(this._tsConfigPath);
102
- if (config.errors && config.errors.length) {
103
- throw new Error(compiler_cli_1.formatDiagnostics(config.errors));
101
+ const { errors, rootNames, options: compilerOptions } = compiler_cli_1.readConfiguration(this._tsConfigPath, options.compilerOptions);
102
+ if (errors && errors.length) {
103
+ throw new Error(compiler_cli_1.formatDiagnostics(errors));
104
104
  }
105
- this._rootNames = config.rootNames;
106
- this._compilerOptions = { ...config.options, ...options.compilerOptions };
107
- this._basePath = config.options.basePath || basePath || '';
105
+ this._rootNames = rootNames;
106
+ this._compilerOptions = compilerOptions;
107
+ this._basePath = compilerOptions.basePath || basePath || '';
108
108
  // Overwrite outDir so we can find generated files next to their .ts origin in compilerHost.
109
109
  this._compilerOptions.outDir = '';
110
110
  this._compilerOptions.suppressOutputPathCheck = true;
@@ -27,11 +27,14 @@ export declare class AngularWebpackPlugin {
27
27
  private buildTimestamp;
28
28
  private readonly lazyRouteMap;
29
29
  private readonly requiredFilesToEmit;
30
+ private readonly requiredFilesToEmitCache;
31
+ private readonly fileEmitHistory;
30
32
  constructor(options?: Partial<AngularPluginOptions>);
31
33
  get options(): AngularPluginOptions;
32
34
  apply(compiler: Compiler & {
33
35
  watchMode?: boolean;
34
36
  }): void;
37
+ private rebuildRequiredFiles;
35
38
  private loadConfiguration;
36
39
  private updateAotProgram;
37
40
  private updateJitProgram;
package/src/ivy/plugin.js CHANGED
@@ -10,6 +10,7 @@ exports.AngularWebpackPlugin = void 0;
10
10
  */
11
11
  const compiler_cli_1 = require("@angular/compiler-cli");
12
12
  const program_1 = require("@angular/compiler-cli/src/ngtsc/program");
13
+ const crypto_1 = require("crypto");
13
14
  const path = require("path");
14
15
  const ts = require("typescript");
15
16
  const webpack_1 = require("webpack");
@@ -34,11 +35,16 @@ function initializeNgccProcessor(compiler, tsconfig) {
34
35
  const processor = new ngcc_processor_1.NgccProcessor(mainFields, warnings, errors, compiler.context, tsconfig, inputFileSystem, (_b = webpackOptions.resolve) === null || _b === void 0 ? void 0 : _b.symlinks);
35
36
  return { processor, errors, warnings };
36
37
  }
38
+ function hashContent(content) {
39
+ return crypto_1.createHash('md5').update(content).digest();
40
+ }
37
41
  const PLUGIN_NAME = 'angular-compiler';
38
42
  class AngularWebpackPlugin {
39
43
  constructor(options = {}) {
40
44
  this.lazyRouteMap = {};
41
45
  this.requiredFilesToEmit = new Set();
46
+ this.requiredFilesToEmitCache = new Map();
47
+ this.fileEmitHistory = new Map();
42
48
  this.pluginOptions = {
43
49
  emitClassMetadata: false,
44
50
  emitNgModuleScope: false,
@@ -152,19 +158,7 @@ class AngularWebpackPlugin {
152
158
  }
153
159
  compilation.hooks.finishModules.tapPromise(PLUGIN_NAME, async (modules) => {
154
160
  // Rebuild any remaining AOT required modules
155
- const rebuild = (filename) => new Promise((resolve) => {
156
- const module = modules.find(({ resource }) => resource && paths_1.normalizePath(resource) === filename);
157
- if (!module) {
158
- resolve();
159
- }
160
- else {
161
- compilation.rebuildModule(module, resolve);
162
- }
163
- });
164
- for (const requiredFile of this.requiredFilesToEmit) {
165
- await rebuild(requiredFile);
166
- }
167
- this.requiredFilesToEmit.clear();
161
+ await this.rebuildRequiredFiles(modules, compilation, fileEmitter);
168
162
  // Analyze program for unused files
169
163
  if (compilation.errors.length > 0) {
170
164
  return;
@@ -192,6 +186,41 @@ class AngularWebpackPlugin {
192
186
  compilation[symbol_1.AngularPluginSymbol] = fileEmitter;
193
187
  });
194
188
  }
189
+ async rebuildRequiredFiles(modules, compilation, fileEmitter) {
190
+ if (this.requiredFilesToEmit.size === 0) {
191
+ return;
192
+ }
193
+ const rebuild = (webpackModule) => new Promise((resolve) => compilation.rebuildModule(webpackModule, resolve));
194
+ const filesToRebuild = new Set();
195
+ for (const requiredFile of this.requiredFilesToEmit) {
196
+ const history = this.fileEmitHistory.get(requiredFile);
197
+ if (history) {
198
+ const emitResult = await fileEmitter(requiredFile);
199
+ if ((emitResult === null || emitResult === void 0 ? void 0 : emitResult.content) === undefined ||
200
+ history.length !== emitResult.content.length ||
201
+ emitResult.hash === undefined ||
202
+ Buffer.compare(history.hash, emitResult.hash) !== 0) {
203
+ // New emit result is different so rebuild using new emit result
204
+ this.requiredFilesToEmitCache.set(requiredFile, emitResult);
205
+ filesToRebuild.add(requiredFile);
206
+ }
207
+ }
208
+ else {
209
+ // No emit history so rebuild
210
+ filesToRebuild.add(requiredFile);
211
+ }
212
+ }
213
+ if (filesToRebuild.size > 0) {
214
+ for (const webpackModule of [...modules]) {
215
+ const resource = webpackModule.resource;
216
+ if (resource && filesToRebuild.has(paths_1.normalizePath(resource))) {
217
+ await rebuild(webpackModule);
218
+ }
219
+ }
220
+ }
221
+ this.requiredFilesToEmit.clear();
222
+ this.requiredFilesToEmitCache.clear();
223
+ }
195
224
  loadConfiguration(compilation) {
196
225
  const { options: compilerOptions, rootNames, errors } = compiler_cli_1.readConfiguration(this.pluginOptions.tsconfig, this.pluginOptions.compilerOptions);
197
226
  compilerOptions.enableIvy = true;
@@ -355,12 +384,15 @@ class AngularWebpackPlugin {
355
384
  }
356
385
  createFileEmitter(program, transformers = {}, getExtraDependencies, onAfterEmit) {
357
386
  return async (file) => {
387
+ if (this.requiredFilesToEmitCache.has(file)) {
388
+ return this.requiredFilesToEmitCache.get(file);
389
+ }
358
390
  const sourceFile = program.getSourceFile(file);
359
391
  if (!sourceFile) {
360
392
  return undefined;
361
393
  }
362
- let content = undefined;
363
- let map = undefined;
394
+ let content;
395
+ let map;
364
396
  program.emit(sourceFile, (filename, data) => {
365
397
  if (filename.endsWith('.map')) {
366
398
  map = data;
@@ -370,11 +402,17 @@ class AngularWebpackPlugin {
370
402
  }
371
403
  }, undefined, undefined, transformers);
372
404
  onAfterEmit === null || onAfterEmit === void 0 ? void 0 : onAfterEmit(sourceFile);
405
+ let hash;
406
+ if (content !== undefined && this.watchMode) {
407
+ // Capture emit history info for Angular rebuild analysis
408
+ hash = hashContent(content);
409
+ this.fileEmitHistory.set(file, { length: content.length, hash });
410
+ }
373
411
  const dependencies = [
374
412
  ...program.getAllDependencies(sourceFile),
375
413
  ...getExtraDependencies(sourceFile),
376
414
  ].map(paths_1.externalizePath);
377
- return { content, map, dependencies };
415
+ return { content, map, dependencies, hash };
378
416
  };
379
417
  }
380
418
  }
@@ -10,5 +10,6 @@ export interface EmitFileResult {
10
10
  content?: string;
11
11
  map?: string;
12
12
  dependencies: readonly string[];
13
+ hash?: Uint8Array;
13
14
  }
14
15
  export declare type FileEmitter = (file: string) => Promise<EmitFileResult | undefined>;
@@ -60,16 +60,17 @@ function replaceBootstrap(getTypeChecker) {
60
60
  let bootstrapImport;
61
61
  let bootstrapNamespace;
62
62
  const replacedNodes = [];
63
+ const nodeFactory = context.factory;
63
64
  const visitNode = (node) => {
64
65
  if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
65
66
  const target = node.expression;
66
67
  if (target.text === 'platformBrowserDynamic') {
67
68
  if (!bootstrapNamespace) {
68
- bootstrapNamespace = ts.createUniqueName('__NgCli_bootstrap_');
69
- bootstrapImport = ts.createImportDeclaration(undefined, undefined, ts.createImportClause(undefined, ts.createNamespaceImport(bootstrapNamespace)), ts.createLiteral('@angular/platform-browser'));
69
+ bootstrapNamespace = nodeFactory.createUniqueName('__NgCli_bootstrap_');
70
+ bootstrapImport = nodeFactory.createImportDeclaration(undefined, undefined, nodeFactory.createImportClause(false, undefined, nodeFactory.createNamespaceImport(bootstrapNamespace)), nodeFactory.createStringLiteral('@angular/platform-browser'));
70
71
  }
71
72
  replacedNodes.push(target);
72
- return ts.updateCall(node, ts.createPropertyAccess(bootstrapNamespace, 'platformBrowser'), node.typeArguments, node.arguments);
73
+ return nodeFactory.updateCallExpression(node, nodeFactory.createPropertyAccessExpression(bootstrapNamespace, 'platformBrowser'), node.typeArguments, node.arguments);
73
74
  }
74
75
  }
75
76
  return ts.visitEachChild(node, visitNode, context);
@@ -83,7 +84,7 @@ function replaceBootstrap(getTypeChecker) {
83
84
  updatedSourceFile = ts.visitEachChild(updatedSourceFile, (node) => (removals.includes(node) ? undefined : node), context);
84
85
  }
85
86
  // Add new platform browser import
86
- return ts.updateSourceFileNode(updatedSourceFile, ts.setTextRange(ts.createNodeArray([bootstrapImport, ...updatedSourceFile.statements]), sourceFile.statements));
87
+ return nodeFactory.updateSourceFile(updatedSourceFile, ts.setTextRange(nodeFactory.createNodeArray([bootstrapImport, ...updatedSourceFile.statements]), sourceFile.statements));
87
88
  }
88
89
  else {
89
90
  return updatedSourceFile;
@@ -45,8 +45,8 @@ function exportNgFactory(shouldTransform, getEntryModule) {
45
45
  // Add the transform operations.
46
46
  const factoryClassName = entryModule.className + 'NgFactory';
47
47
  const factoryModulePath = normalizedEntryModulePath + '.ngfactory';
48
- const namedExports = ts.createNamedExports([ts.createExportSpecifier(undefined, ts.createIdentifier(factoryClassName))]);
49
- const newImport = ts.createExportDeclaration(undefined, undefined, namedExports, ts.createLiteral(factoryModulePath));
48
+ const namedExports = ts.factory.createNamedExports([ts.factory.createExportSpecifier(undefined, ts.factory.createIdentifier(factoryClassName))]);
49
+ const newImport = ts.factory.createExportDeclaration(undefined, undefined, false, namedExports, ts.factory.createStringLiteral(factoryModulePath));
50
50
  const firstNode = ast_helpers_1.getFirstNode(sourceFile);
51
51
  if (firstNode) {
52
52
  ops.push(new interfaces_1.AddNodeOperation(sourceFile, firstNode, newImport));
@@ -183,11 +183,11 @@ function replaceImport(node, context, emitWarning, fileName, typeChecker) {
183
183
  const replacementVisitor = (node) => {
184
184
  if (node === importStringLit) {
185
185
  // Transform the import string.
186
- return ts.createStringLiteral(newImportString);
186
+ return ts.factory.createStringLiteral(newImportString);
187
187
  }
188
188
  else if (node === exportNameId) {
189
189
  // Transform the export name.
190
- return ts.createIdentifier(exportNameId.text + 'NgFactory');
190
+ return ts.factory.createIdentifier(exportNameId.text + 'NgFactory');
191
191
  }
192
192
  return ts.visitEachChild(node, replacementVisitor, context);
193
193
  };
@@ -16,9 +16,9 @@ function insertStarImport(sourceFile, identifier, modulePath, target, before = f
16
16
  const allImports = ast_helpers_1.collectDeepNodes(sourceFile, ts.SyntaxKind.ImportDeclaration);
17
17
  // We don't need to verify if the symbol is already imported, star imports should be unique.
18
18
  // Create the new import node.
19
- const namespaceImport = ts.createNamespaceImport(identifier);
20
- const importClause = ts.createImportClause(undefined, namespaceImport);
21
- const newImport = ts.createImportDeclaration(undefined, undefined, importClause, ts.createLiteral(modulePath));
19
+ const namespaceImport = ts.factory.createNamespaceImport(identifier);
20
+ const importClause = ts.factory.createImportClause(false, undefined, namespaceImport);
21
+ const newImport = ts.factory.createImportDeclaration(undefined, undefined, importClause, ts.factory.createStringLiteral(modulePath));
22
22
  if (target) {
23
23
  ops.push(new interfaces_1.AddNodeOperation(sourceFile, target, before ? newImport : undefined, before ? undefined : newImport));
24
24
  }
@@ -71,13 +71,13 @@ function insertImport(sourceFile, symbolName, modulePath) {
71
71
  return ops;
72
72
  }
73
73
  // Just pick the first one and insert at the end of its identifier list.
74
- ops.push(new interfaces_1.AddNodeOperation(sourceFile, maybeImports[0].elements[maybeImports[0].elements.length - 1], undefined, ts.createImportSpecifier(undefined, ts.createIdentifier(symbolName))));
74
+ ops.push(new interfaces_1.AddNodeOperation(sourceFile, maybeImports[0].elements[maybeImports[0].elements.length - 1], undefined, ts.factory.createImportSpecifier(undefined, ts.factory.createIdentifier(symbolName))));
75
75
  }
76
76
  else {
77
77
  // Create the new import node.
78
- const namedImports = ts.createNamedImports([ts.createImportSpecifier(undefined, ts.createIdentifier(symbolName))]);
79
- const importClause = ts.createImportClause(undefined, namedImports);
80
- const newImport = ts.createImportDeclaration(undefined, undefined, importClause, ts.createLiteral(modulePath));
78
+ const namedImports = ts.factory.createNamedImports([ts.factory.createImportSpecifier(undefined, ts.factory.createIdentifier(symbolName))]);
79
+ const importClause = ts.factory.createImportClause(false, undefined, namedImports);
80
+ const newImport = ts.factory.createImportDeclaration(undefined, undefined, importClause, ts.factory.createStringLiteral(modulePath));
81
81
  if (allImports.length > 0) {
82
82
  // Find the last import and insert after.
83
83
  ops.push(new interfaces_1.AddNodeOperation(sourceFile, allImports[allImports.length - 1], undefined, newImport));
@@ -47,15 +47,15 @@ function registerLocaleData(shouldTransform, getEntryModule, locale) {
47
47
  return;
48
48
  }
49
49
  // Create the import node for the locale.
50
- const localeNamespaceId = ts.createUniqueName('__NgCli_locale_');
50
+ const localeNamespaceId = ts.factory.createUniqueName('__NgCli_locale_');
51
51
  ops.push(...insert_import_1.insertStarImport(sourceFile, localeNamespaceId, `@angular/common/locales/${locale}`, firstNode, true));
52
52
  // Create the import node for the registerLocaleData function.
53
- const regIdentifier = ts.createIdentifier(`registerLocaleData`);
54
- const regNamespaceId = ts.createUniqueName('__NgCli_locale_');
53
+ const regIdentifier = ts.factory.createIdentifier(`registerLocaleData`);
54
+ const regNamespaceId = ts.factory.createUniqueName('__NgCli_locale_');
55
55
  ops.push(...insert_import_1.insertStarImport(sourceFile, regNamespaceId, '@angular/common', firstNode, true));
56
56
  // Create the register function call
57
- const registerFunctionCall = ts.createCall(ts.createPropertyAccess(regNamespaceId, regIdentifier), undefined, [ts.createPropertyAccess(localeNamespaceId, 'default')]);
58
- const registerFunctionStatement = ts.createStatement(registerFunctionCall);
57
+ const registerFunctionCall = ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(regNamespaceId, regIdentifier), undefined, [ts.factory.createPropertyAccessExpression(localeNamespaceId, 'default')]);
58
+ const registerFunctionStatement = ts.factory.createExpressionStatement(registerFunctionCall);
59
59
  ops.push(new interfaces_1.AddNodeOperation(sourceFile, firstNode, registerFunctionStatement));
60
60
  });
61
61
  return ops;
@@ -51,8 +51,8 @@ function replaceBootstrap(shouldTransform, getEntryModule, getTypeChecker, useFa
51
51
  return;
52
52
  }
53
53
  const platformBrowserDynamicIdentifier = innerCallExpr.expression;
54
- const idPlatformBrowser = ts.createUniqueName('__NgCli_bootstrap_');
55
- const idNgFactory = ts.createUniqueName('__NgCli_bootstrap_');
54
+ const idPlatformBrowser = ts.factory.createUniqueName('__NgCli_bootstrap_');
55
+ const idNgFactory = ts.factory.createUniqueName('__NgCli_bootstrap_');
56
56
  // Add the transform operations.
57
57
  const relativeEntryModulePath = path_1.relative(path_1.dirname(sourceFile.fileName), entryModule.path);
58
58
  let className = entryModule.className;
@@ -65,9 +65,9 @@ function replaceBootstrap(shouldTransform, getEntryModule, getTypeChecker, useFa
65
65
  }
66
66
  ops.push(
67
67
  // Replace the entry module import.
68
- ...insert_import_1.insertStarImport(sourceFile, idNgFactory, modulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.createPropertyAccess(idNgFactory, ts.createIdentifier(className))),
68
+ ...insert_import_1.insertStarImport(sourceFile, idNgFactory, modulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.factory.createPropertyAccessExpression(idNgFactory, ts.factory.createIdentifier(className))),
69
69
  // Replace the platformBrowserDynamic import.
70
- ...insert_import_1.insertStarImport(sourceFile, idPlatformBrowser, '@angular/platform-browser'), new interfaces_1.ReplaceNodeOperation(sourceFile, platformBrowserDynamicIdentifier, ts.createPropertyAccess(idPlatformBrowser, 'platformBrowser')), new interfaces_1.ReplaceNodeOperation(sourceFile, bootstrapModuleIdentifier, ts.createIdentifier(bootstrapIdentifier)));
70
+ ...insert_import_1.insertStarImport(sourceFile, idPlatformBrowser, '@angular/platform-browser'), new interfaces_1.ReplaceNodeOperation(sourceFile, platformBrowserDynamicIdentifier, ts.factory.createPropertyAccessExpression(idPlatformBrowser, 'platformBrowser')), new interfaces_1.ReplaceNodeOperation(sourceFile, bootstrapModuleIdentifier, ts.factory.createIdentifier(bootstrapIdentifier)));
71
71
  });
72
72
  return ops;
73
73
  };
@@ -14,12 +14,13 @@ function replaceResources(shouldTransform, getTypeChecker, directTemplateLoading
14
14
  const typeChecker = getTypeChecker();
15
15
  const resourceImportDeclarations = [];
16
16
  const moduleKind = context.getCompilerOptions().module;
17
+ const nodeFactory = context.factory;
17
18
  const visitNode = (node) => {
18
19
  if (ts.isClassDeclaration(node)) {
19
20
  const decorators = ts.visitNodes(node.decorators, node => ts.isDecorator(node)
20
- ? visitDecorator(node, typeChecker, directTemplateLoading, resourceImportDeclarations, moduleKind)
21
+ ? visitDecorator(nodeFactory, node, typeChecker, directTemplateLoading, resourceImportDeclarations, moduleKind)
21
22
  : node);
22
- return ts.updateClassDeclaration(node, decorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
23
+ return nodeFactory.updateClassDeclaration(node, decorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses, node.members);
23
24
  }
24
25
  return ts.visitEachChild(node, visitNode, context);
25
26
  };
@@ -30,7 +31,7 @@ function replaceResources(shouldTransform, getTypeChecker, directTemplateLoading
30
31
  const updatedSourceFile = ts.visitNode(sourceFile, visitNode);
31
32
  if (resourceImportDeclarations.length) {
32
33
  // Add resource imports
33
- return ts.updateSourceFileNode(updatedSourceFile, ts.setTextRange(ts.createNodeArray([
34
+ return context.factory.updateSourceFile(updatedSourceFile, ts.setTextRange(context.factory.createNodeArray([
34
35
  ...resourceImportDeclarations,
35
36
  ...updatedSourceFile.statements,
36
37
  ]), updatedSourceFile.statements));
@@ -40,7 +41,7 @@ function replaceResources(shouldTransform, getTypeChecker, directTemplateLoading
40
41
  };
41
42
  }
42
43
  exports.replaceResources = replaceResources;
43
- function visitDecorator(node, typeChecker, directTemplateLoading, resourceImportDeclarations, moduleKind) {
44
+ function visitDecorator(nodeFactory, node, typeChecker, directTemplateLoading, resourceImportDeclarations, moduleKind) {
44
45
  if (!isComponentDecorator(node, typeChecker)) {
45
46
  return node;
46
47
  }
@@ -57,18 +58,18 @@ function visitDecorator(node, typeChecker, directTemplateLoading, resourceImport
57
58
  const styleReplacements = [];
58
59
  // visit all properties
59
60
  let properties = ts.visitNodes(objectExpression.properties, node => ts.isObjectLiteralElementLike(node)
60
- ? visitComponentMetadata(node, styleReplacements, directTemplateLoading, resourceImportDeclarations, moduleKind)
61
+ ? visitComponentMetadata(nodeFactory, node, styleReplacements, directTemplateLoading, resourceImportDeclarations, moduleKind)
61
62
  : node);
62
63
  // replace properties with updated properties
63
64
  if (styleReplacements.length > 0) {
64
- const styleProperty = ts.createPropertyAssignment(ts.createIdentifier('styles'), ts.createArrayLiteral(styleReplacements));
65
- properties = ts.createNodeArray([...properties, styleProperty]);
65
+ const styleProperty = nodeFactory.createPropertyAssignment(nodeFactory.createIdentifier('styles'), nodeFactory.createArrayLiteralExpression(styleReplacements));
66
+ properties = nodeFactory.createNodeArray([...properties, styleProperty]);
66
67
  }
67
- return ts.updateDecorator(node, ts.updateCall(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [
68
- ts.updateObjectLiteral(objectExpression, properties),
68
+ return nodeFactory.updateDecorator(node, nodeFactory.updateCallExpression(decoratorFactory, decoratorFactory.expression, decoratorFactory.typeArguments, [
69
+ nodeFactory.updateObjectLiteralExpression(objectExpression, properties),
69
70
  ]));
70
71
  }
71
- function visitComponentMetadata(node, styleReplacements, directTemplateLoading, resourceImportDeclarations, moduleKind) {
72
+ function visitComponentMetadata(nodeFactory, node, styleReplacements, directTemplateLoading, resourceImportDeclarations, moduleKind) {
72
73
  if (!ts.isPropertyAssignment(node) || ts.isComputedPropertyName(node.name)) {
73
74
  return node;
74
75
  }
@@ -77,11 +78,11 @@ function visitComponentMetadata(node, styleReplacements, directTemplateLoading,
77
78
  case 'moduleId':
78
79
  return undefined;
79
80
  case 'templateUrl':
80
- const importName = createResourceImport(node.initializer, directTemplateLoading ? '!raw-loader!' : '', resourceImportDeclarations, moduleKind);
81
+ const importName = createResourceImport(nodeFactory, node.initializer, directTemplateLoading ? '!raw-loader!' : '', resourceImportDeclarations, moduleKind);
81
82
  if (!importName) {
82
83
  return node;
83
84
  }
84
- return ts.updatePropertyAssignment(node, ts.createIdentifier('template'), importName);
85
+ return nodeFactory.updatePropertyAssignment(node, nodeFactory.createIdentifier('template'), importName);
85
86
  case 'styles':
86
87
  case 'styleUrls':
87
88
  if (!ts.isArrayLiteralExpression(node.initializer)) {
@@ -93,9 +94,9 @@ function visitComponentMetadata(node, styleReplacements, directTemplateLoading,
93
94
  return node;
94
95
  }
95
96
  if (isInlineStyles) {
96
- return ts.createLiteral(node.text);
97
+ return nodeFactory.createStringLiteral(node.text);
97
98
  }
98
- return createResourceImport(node, undefined, resourceImportDeclarations, moduleKind) || node;
99
+ return createResourceImport(nodeFactory, node, undefined, resourceImportDeclarations, moduleKind) || node;
99
100
  });
100
101
  // Styles should be placed first
101
102
  if (isInlineStyles) {
@@ -127,18 +128,18 @@ function isComponentDecorator(node, typeChecker) {
127
128
  }
128
129
  return false;
129
130
  }
130
- function createResourceImport(node, loader, resourceImportDeclarations, moduleKind = ts.ModuleKind.ES2015) {
131
+ function createResourceImport(nodeFactory, node, loader, resourceImportDeclarations, moduleKind = ts.ModuleKind.ES2015) {
131
132
  const url = getResourceUrl(node, loader);
132
133
  if (!url) {
133
134
  return null;
134
135
  }
135
- const urlLiteral = ts.createLiteral(url);
136
+ const urlLiteral = nodeFactory.createStringLiteral(url);
136
137
  if (moduleKind < ts.ModuleKind.ES2015) {
137
- return ts.createPropertyAccess(ts.createCall(ts.createIdentifier('require'), [], [urlLiteral]), 'default');
138
+ return nodeFactory.createPropertyAccessExpression(nodeFactory.createCallExpression(nodeFactory.createIdentifier('require'), [], [urlLiteral]), 'default');
138
139
  }
139
140
  else {
140
- const importName = ts.createIdentifier(`__NG_CLI_RESOURCE__${resourceImportDeclarations.length}`);
141
- resourceImportDeclarations.push(ts.createImportDeclaration(undefined, undefined, ts.createImportClause(importName, undefined), urlLiteral));
141
+ const importName = nodeFactory.createIdentifier(`__NG_CLI_RESOURCE__${resourceImportDeclarations.length}`);
142
+ resourceImportDeclarations.push(nodeFactory.createImportDeclaration(undefined, undefined, nodeFactory.createImportClause(false, importName, undefined), urlLiteral));
142
143
  return importName;
143
144
  }
144
145
  }
@@ -57,14 +57,14 @@ function replaceServerBootstrap(shouldTransform, getEntryModule, getTypeChecker)
57
57
  return;
58
58
  }
59
59
  const platformDynamicServerIdentifier = innerCallExpr.expression;
60
- const idPlatformServer = ts.createUniqueName('__NgCli_bootstrap_');
61
- const idNgFactory = ts.createUniqueName('__NgCli_bootstrap_');
60
+ const idPlatformServer = ts.factory.createUniqueName('__NgCli_bootstrap_');
61
+ const idNgFactory = ts.factory.createUniqueName('__NgCli_bootstrap_');
62
62
  // Add the transform operations.
63
63
  ops.push(
64
64
  // Replace the entry module import.
65
- ...insert_import_1.insertStarImport(sourceFile, idNgFactory, factoryModulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.createPropertyAccess(idNgFactory, ts.createIdentifier(factoryClassName))),
65
+ ...insert_import_1.insertStarImport(sourceFile, idNgFactory, factoryModulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.factory.createPropertyAccessExpression(idNgFactory, ts.factory.createIdentifier(factoryClassName))),
66
66
  // Replace the platformBrowserDynamic import.
67
- ...insert_import_1.insertStarImport(sourceFile, idPlatformServer, '@angular/platform-server'), new interfaces_1.ReplaceNodeOperation(sourceFile, platformDynamicServerIdentifier, ts.createPropertyAccess(idPlatformServer, 'platformServer')), new interfaces_1.ReplaceNodeOperation(sourceFile, bootstrapModuleIdentifier, ts.createIdentifier('bootstrapModuleFactory')));
67
+ ...insert_import_1.insertStarImport(sourceFile, idPlatformServer, '@angular/platform-server'), new interfaces_1.ReplaceNodeOperation(sourceFile, platformDynamicServerIdentifier, ts.factory.createPropertyAccessExpression(idPlatformServer, 'platformServer')), new interfaces_1.ReplaceNodeOperation(sourceFile, bootstrapModuleIdentifier, ts.factory.createIdentifier('bootstrapModuleFactory')));
68
68
  }
69
69
  else if (callExpr.expression.kind === ts.SyntaxKind.Identifier) {
70
70
  // Figure out if it is renderModule
@@ -73,20 +73,20 @@ function replaceServerBootstrap(shouldTransform, getEntryModule, getTypeChecker)
73
73
  return;
74
74
  }
75
75
  const renderModuleIdentifier = identifierExpr;
76
- const idPlatformServer = ts.createUniqueName('__NgCli_bootstrap_');
77
- const idNgFactory = ts.createUniqueName('__NgCli_bootstrap_');
76
+ const idPlatformServer = ts.factory.createUniqueName('__NgCli_bootstrap_');
77
+ const idNgFactory = ts.factory.createUniqueName('__NgCli_bootstrap_');
78
78
  ops.push(
79
79
  // Replace the entry module import.
80
- ...insert_import_1.insertStarImport(sourceFile, idNgFactory, factoryModulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.createPropertyAccess(idNgFactory, ts.createIdentifier(factoryClassName))),
80
+ ...insert_import_1.insertStarImport(sourceFile, idNgFactory, factoryModulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.factory.createPropertyAccessExpression(idNgFactory, ts.factory.createIdentifier(factoryClassName))),
81
81
  // Replace the renderModule import.
82
- ...insert_import_1.insertStarImport(sourceFile, idPlatformServer, '@angular/platform-server'), new interfaces_1.ReplaceNodeOperation(sourceFile, renderModuleIdentifier, ts.createPropertyAccess(idPlatformServer, 'renderModuleFactory')));
82
+ ...insert_import_1.insertStarImport(sourceFile, idPlatformServer, '@angular/platform-server'), new interfaces_1.ReplaceNodeOperation(sourceFile, renderModuleIdentifier, ts.factory.createPropertyAccessExpression(idPlatformServer, 'renderModuleFactory')));
83
83
  }
84
84
  }
85
85
  else if (entryModuleIdentifier.parent.kind === ts.SyntaxKind.PropertyAssignment) {
86
86
  // This is for things that accept a module as a property in a config object
87
87
  // .ie the express engine
88
- const idNgFactory = ts.createUniqueName('__NgCli_bootstrap_');
89
- ops.push(...insert_import_1.insertStarImport(sourceFile, idNgFactory, factoryModulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.createPropertyAccess(idNgFactory, ts.createIdentifier(factoryClassName))));
88
+ const idNgFactory = ts.factory.createUniqueName('__NgCli_bootstrap_');
89
+ ops.push(...insert_import_1.insertStarImport(sourceFile, idNgFactory, factoryModulePath), new interfaces_1.ReplaceNodeOperation(sourceFile, entryModuleIdentifier, ts.factory.createPropertyAccessExpression(idNgFactory, ts.factory.createIdentifier(factoryClassName))));
90
90
  }
91
91
  });
92
92
  return ops;