@ngtools/webpack 9.0.0-rc.7 → 9.0.1

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": "9.0.0-rc.7",
3
+ "version": "9.0.1",
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,20 +25,19 @@
25
25
  },
26
26
  "homepage": "https://github.com/angular/angular-cli",
27
27
  "dependencies": {
28
- "@angular-devkit/core": "9.0.0-rc.7",
28
+ "@angular-devkit/core": "9.0.1",
29
29
  "enhanced-resolve": "4.1.1",
30
30
  "rxjs": "6.5.3",
31
31
  "webpack-sources": "1.4.3"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "@angular/compiler-cli": ">=9.0.0-beta < 10",
35
- "typescript": ">=3.6 < 3.7",
35
+ "typescript": ">=3.6 < 3.8",
36
36
  "webpack": "^4.0.0"
37
37
  },
38
38
  "engines": {
39
39
  "node": ">= 10.13.0",
40
40
  "npm": ">= 6.11.0",
41
- "pnpm": ">= 3.2.0",
42
41
  "yarn": ">= 1.13.0"
43
42
  },
44
43
  "husky": {
@@ -38,13 +38,13 @@ export declare class AngularCompilerPlugin {
38
38
  private _logger;
39
39
  private _mainFields;
40
40
  constructor(options: AngularCompilerPluginOptions);
41
- readonly options: AngularCompilerPluginOptions;
42
- readonly done: Promise<void> | null;
43
- readonly entryModule: {
41
+ get options(): AngularCompilerPluginOptions;
42
+ get done(): Promise<void> | null;
43
+ get entryModule(): {
44
44
  path: string;
45
45
  className: string;
46
46
  } | null;
47
- readonly typeChecker: ts.TypeChecker | null;
47
+ get typeChecker(): ts.TypeChecker | null;
48
48
  /** @deprecated From 8.0.2 */
49
49
  static isSupported(): boolean;
50
50
  private _setupOptions;
@@ -75,7 +75,7 @@ export declare class AngularCompilerPlugin {
75
75
  errorDependencies: string[];
76
76
  };
77
77
  getDependencies(fileName: string, includeResources?: boolean): string[];
78
- getResourceDependencies(fileName: string): string[];
78
+ getResourceDependencies(fileName: string): never[] | Set<string>;
79
79
  getTypeDependencies(fileName: string): string[];
80
80
  private _emit;
81
81
  private _validateLocale;
@@ -26,6 +26,7 @@ const resource_loader_1 = require("./resource_loader");
26
26
  const transformers_1 = require("./transformers");
27
27
  const ast_helpers_1 = require("./transformers/ast_helpers");
28
28
  const ctor_parameters_1 = require("./transformers/ctor-parameters");
29
+ const remove_ivy_jit_support_calls_1 = require("./transformers/remove-ivy-jit-support-calls");
29
30
  const type_checker_1 = require("./type_checker");
30
31
  const type_checker_messages_1 = require("./type_checker_messages");
31
32
  const utils_1 = require("./utils");
@@ -757,6 +758,14 @@ class AngularCompilerPlugin {
757
758
  // In Ivy they are removed in ngc directly.
758
759
  this._transformers.push(transformers_1.removeDecorators(isAppPath, getTypeChecker));
759
760
  }
761
+ else {
762
+ // Default for both options is to emit (undefined means true)
763
+ const removeClassMetadata = this._options.emitClassMetadata === false;
764
+ const removeNgModuleScope = this._options.emitNgModuleScope === false;
765
+ if (removeClassMetadata || removeNgModuleScope) {
766
+ this._transformers.push(remove_ivy_jit_support_calls_1.removeIvyJitSupportCalls(removeClassMetadata, removeNgModuleScope, getTypeChecker));
767
+ }
768
+ }
760
769
  // Import ngfactory in loadChildren import syntax
761
770
  if (this._useFactories) {
762
771
  // Only transform imports to use factories with View Engine.
@@ -931,12 +940,16 @@ class AngularCompilerPlugin {
931
940
  }
932
941
  })
933
942
  .filter(x => x);
934
- let resourceImports = [], resourceDependencies = [];
943
+ let resourceImports = [];
944
+ const resourceDependencies = [];
935
945
  if (includeResources) {
936
946
  resourceImports = transformers_1.findResources(sourceFile)
937
947
  .map(resourcePath => core_1.resolve(core_1.dirname(resolvedFileName), core_1.normalize(resourcePath)));
938
- resourceDependencies =
939
- this.getResourceDependencies(this._compilerHost.denormalizePath(resolvedFileName));
948
+ for (const resource of resourceImports) {
949
+ for (const dep of this.getResourceDependencies(this._compilerHost.denormalizePath(resource))) {
950
+ resourceDependencies.push(dep);
951
+ }
952
+ }
940
953
  }
941
954
  // These paths are meant to be used by the loader so we must denormalize them.
942
955
  const uniqueDependencies = new Set([
@@ -31,7 +31,7 @@ export declare class WebpackCompilerHost implements ts.CompilerHost {
31
31
  private _virtualFileExtensions;
32
32
  private _virtualStyleFileExtensions;
33
33
  constructor(_options: ts.CompilerOptions, basePath: string, host: virtualFs.Host, cacheSourceFiles: boolean, directTemplateLoading?: boolean, ngccProcessor?: NgccProcessor | undefined, moduleResolutionCache?: ts.ModuleResolutionCache | undefined);
34
- private readonly virtualFiles;
34
+ private get virtualFiles();
35
35
  reset(): void;
36
36
  denormalizePath(path: string): string;
37
37
  resolve(path: string): Path;
@@ -48,7 +48,7 @@ export declare class WebpackCompilerHost implements ts.CompilerHost {
48
48
  getDirectories(path: string): string[];
49
49
  getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: OnErrorFn): ts.SourceFile | undefined;
50
50
  getDefaultLibFileName(options: ts.CompilerOptions): string;
51
- readonly writeFile: (fileName: string, data: string, _writeByteOrderMark: boolean, onError?: ((message: string) => void) | undefined, _sourceFiles?: readonly ts.SourceFile[] | undefined) => void;
51
+ get writeFile(): (fileName: string, data: string, _writeByteOrderMark: boolean, onError?: ((message: string) => void) | undefined, _sourceFiles?: readonly ts.SourceFile[] | undefined) => void;
52
52
  getCurrentDirectory(): string;
53
53
  getCanonicalFileName(fileName: string): string;
54
54
  useCaseSensitiveFileNames(): boolean;
@@ -118,11 +118,11 @@ function reportDiagnostics(diagnostics, compilerHost, reportError, reportWarning
118
118
  }
119
119
  }
120
120
  if (tsErrors.length > 0) {
121
- const message = ts.formatDiagnosticsWithColorAndContext(tsErrors, compilerHost);
121
+ const message = compiler_cli_1.formatDiagnostics(tsErrors);
122
122
  reportError(message);
123
123
  }
124
124
  if (tsWarnings.length > 0) {
125
- const message = ts.formatDiagnosticsWithColorAndContext(tsWarnings, compilerHost);
125
+ const message = compiler_cli_1.formatDiagnostics(tsWarnings);
126
126
  reportWarning(message);
127
127
  }
128
128
  if (ngErrors.length > 0) {
@@ -43,6 +43,8 @@ export interface AngularCompilerPluginOptions {
43
43
  nameLazyFiles?: boolean;
44
44
  logger?: logging.Logger;
45
45
  directTemplateLoading?: boolean;
46
+ emitClassMetadata?: boolean;
47
+ emitNgModuleScope?: boolean;
46
48
  /**
47
49
  * When using the loadChildren string syntax, @ngtools/webpack must query @angular/compiler-cli
48
50
  * via a private API to know which lazy routes exist. This increases build and rebuild time.
package/src/loader.js CHANGED
@@ -83,8 +83,9 @@ function ngcLoader() {
83
83
  const ngStyleRe = /(?:\.shim)?\.ngstyle\.js$/;
84
84
  if (ngStyleRe.test(sourceFileName)) {
85
85
  const styleFile = sourceFileName.replace(ngStyleRe, '');
86
- const styleDependencies = plugin.getResourceDependencies(styleFile);
87
- styleDependencies.forEach(dep => this.addDependency(dep));
86
+ for (const dep of plugin.getResourceDependencies(styleFile)) {
87
+ this.addDependency(dep);
88
+ }
88
89
  }
89
90
  // Add type-only dependencies that should trigger a rebuild when they change.
90
91
  const typeDependencies = plugin.getTypeDependencies(sourceFileName);
package/src/refactor.d.ts CHANGED
@@ -13,8 +13,8 @@ export declare function resolve(filePath: string, _host: ts.CompilerHost, compil
13
13
  export declare class TypeScriptFileRefactor {
14
14
  private _fileName;
15
15
  private _sourceFile;
16
- readonly fileName: string;
17
- readonly sourceFile: ts.SourceFile;
16
+ get fileName(): string;
17
+ get sourceFile(): ts.SourceFile;
18
18
  constructor(fileName: string, _host: ts.CompilerHost, _program?: ts.Program, source?: string | null);
19
19
  /**
20
20
  * Find all nodes from the AST in the subtree of node of SyntaxKind kind.
@@ -7,8 +7,8 @@ export declare class WebpackResourceLoader {
7
7
  private _cachedEvaluatedSources;
8
8
  constructor();
9
9
  update(parentCompilation: any): void;
10
- getResourceDependencies(filePath: string): string[];
11
- getAffectedResources(file: string): string[];
10
+ getResourceDependencies(filePath: string): never[] | Set<string>;
11
+ getAffectedResources(file: string): never[] | Set<string>;
12
12
  private _compile;
13
13
  private _evaluate;
14
14
  get(filePath: string): Promise<string>;
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  const path = require("path");
14
14
  const vm = require("vm");
15
15
  const webpack_sources_1 = require("webpack-sources");
16
+ const utils_1 = require("./utils");
16
17
  const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
17
18
  const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
18
19
  const LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
@@ -103,14 +104,15 @@ class WebpackResourceLoader {
103
104
  }
104
105
  });
105
106
  // Save the dependencies for this resource.
106
- this._fileDependencies.set(filePath, childCompilation.fileDependencies);
107
+ this._fileDependencies.set(filePath, new Set(childCompilation.fileDependencies));
107
108
  for (const file of childCompilation.fileDependencies) {
108
- const entry = this._reverseDependencies.get(file);
109
+ const resolvedFile = utils_1.forwardSlashPath(file);
110
+ const entry = this._reverseDependencies.get(resolvedFile);
109
111
  if (entry) {
110
- entry.push(filePath);
112
+ entry.add(filePath);
111
113
  }
112
114
  else {
113
- this._reverseDependencies.set(file, [filePath]);
115
+ this._reverseDependencies.set(resolvedFile, new Set([filePath]));
114
116
  }
115
117
  }
116
118
  const compilationHash = childCompilation.fullHash;
@@ -1,10 +1,11 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google Inc. All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
1
8
  import * as ts from 'typescript';
2
- import { WebpackCompilerHost } from '../compiler_host';
3
9
  export declare function collectDeepNodes<T extends ts.Node>(node: ts.Node, kind: ts.SyntaxKind | ts.SyntaxKind[]): T[];
4
10
  export declare function getFirstNode(sourceFile: ts.SourceFile): ts.Node;
5
11
  export declare function getLastNode(sourceFile: ts.SourceFile): ts.Node | null;
6
- export declare function createTypescriptContext(content: string, additionalFiles?: Record<string, string>, useLibs?: boolean, importHelpers?: boolean): {
7
- compilerHost: WebpackCompilerHost;
8
- program: ts.Program;
9
- };
10
- export declare function transformTypescript(content: string | undefined, transformers: ts.TransformerFactory<ts.SourceFile>[], program?: ts.Program, compilerHost?: WebpackCompilerHost): string | undefined;
@@ -7,11 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  * Use of this source code is governed by an MIT-style license that can be
8
8
  * found in the LICENSE file at https://angular.io/license
9
9
  */
10
- const core_1 = require("@angular-devkit/core");
11
- const fs_1 = require("fs");
12
- const path_1 = require("path");
13
10
  const ts = require("typescript");
14
- const compiler_host_1 = require("../compiler_host");
15
11
  // Find all nodes from the AST in the subtree of node of SyntaxKind kind.
16
12
  function collectDeepNodes(node, kind) {
17
13
  const kinds = Array.isArray(kind) ? kind : [kind];
@@ -40,76 +36,3 @@ function getLastNode(sourceFile) {
40
36
  return null;
41
37
  }
42
38
  exports.getLastNode = getLastNode;
43
- // Test transform helpers.
44
- const basePath = '/project/src/';
45
- const fileName = basePath + 'test-file.ts';
46
- const tsLibFiles = loadTsLibFiles();
47
- function createTypescriptContext(content, additionalFiles, useLibs = false, importHelpers = true) {
48
- // Set compiler options.
49
- const compilerOptions = {
50
- noEmitOnError: useLibs,
51
- allowJs: true,
52
- newLine: ts.NewLineKind.LineFeed,
53
- moduleResolution: ts.ModuleResolutionKind.NodeJs,
54
- module: ts.ModuleKind.ESNext,
55
- target: ts.ScriptTarget.ESNext,
56
- skipLibCheck: true,
57
- sourceMap: false,
58
- importHelpers,
59
- };
60
- // Create compiler host.
61
- const compilerHost = new compiler_host_1.WebpackCompilerHost(compilerOptions, basePath, new core_1.virtualFs.SimpleMemoryHost(), false);
62
- // Add a dummy file to host content.
63
- compilerHost.writeFile(fileName, content, false);
64
- if (useLibs) {
65
- // Write the default libs.
66
- // These are needed for tests that use import(), because it relies on a Promise being there.
67
- const compilerLibFolder = path_1.dirname(compilerHost.getDefaultLibFileName(compilerOptions));
68
- for (const [k, v] of Object.entries(tsLibFiles)) {
69
- compilerHost.writeFile(path_1.join(compilerLibFolder, k), v, false);
70
- }
71
- }
72
- if (additionalFiles) {
73
- for (const key in additionalFiles) {
74
- compilerHost.writeFile(basePath + key, additionalFiles[key], false);
75
- }
76
- }
77
- // Create the TypeScript program.
78
- const program = ts.createProgram([fileName], compilerOptions, compilerHost);
79
- return { compilerHost, program };
80
- }
81
- exports.createTypescriptContext = createTypescriptContext;
82
- function transformTypescript(content, transformers, program, compilerHost) {
83
- // Use given context or create a new one.
84
- if (content !== undefined) {
85
- const typescriptContext = createTypescriptContext(content);
86
- if (!program) {
87
- program = typescriptContext.program;
88
- }
89
- if (!compilerHost) {
90
- compilerHost = typescriptContext.compilerHost;
91
- }
92
- }
93
- else if (!program || !compilerHost) {
94
- throw new Error('transformTypescript needs either `content` or a `program` and `compilerHost');
95
- }
96
- // Emit.
97
- const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, undefined, { before: transformers });
98
- // Throw error with diagnostics if emit wasn't successfull.
99
- if (emitSkipped) {
100
- throw new Error(ts.formatDiagnostics(diagnostics, compilerHost));
101
- }
102
- // Return the transpiled js.
103
- return compilerHost.readFile(fileName.replace(/\.tsx?$/, '.js'));
104
- }
105
- exports.transformTypescript = transformTypescript;
106
- function loadTsLibFiles() {
107
- const libFolderPath = path_1.dirname(require.resolve('typescript/lib/lib.d.ts'));
108
- const libFolderFiles = fs_1.readdirSync(libFolderPath);
109
- const libFileNames = libFolderFiles.filter(f => f.startsWith('lib.') && f.endsWith('.d.ts'));
110
- // Return a map of the lib names to their content.
111
- return libFileNames.reduce((map, f) => {
112
- map[f] = fs_1.readFileSync(path_1.join(libFolderPath, f), 'utf-8');
113
- return map;
114
- }, {});
115
- }
@@ -7,4 +7,4 @@
7
7
  */
8
8
  import * as ts from 'typescript';
9
9
  import { TransformOperation } from './interfaces';
10
- export declare function elideImports(sourceFile: ts.SourceFile, removedNodes: ts.Node[], getTypeChecker: () => ts.TypeChecker): TransformOperation[];
10
+ export declare function elideImports(sourceFile: ts.SourceFile, removedNodes: ts.Node[], getTypeChecker: () => ts.TypeChecker, compilerOptions: ts.CompilerOptions): TransformOperation[];
@@ -15,7 +15,7 @@ const interfaces_1 = require("./interfaces");
15
15
  // Doesn't use the `symbol.declarations` because that previous transforms might have removed nodes
16
16
  // but the type checker doesn't know.
17
17
  // See https://github.com/Microsoft/TypeScript/issues/17552 for more information.
18
- function elideImports(sourceFile, removedNodes, getTypeChecker) {
18
+ function elideImports(sourceFile, removedNodes, getTypeChecker, compilerOptions) {
19
19
  const ops = [];
20
20
  if (removedNodes.length === 0) {
21
21
  return [];
@@ -25,8 +25,9 @@ function elideImports(sourceFile, removedNodes, getTypeChecker) {
25
25
  const usedSymbols = new Set();
26
26
  const imports = [];
27
27
  ts.forEachChild(sourceFile, function visit(node) {
28
- // Skip type references and removed nodes. We consider both unused.
29
- if (node.kind == ts.SyntaxKind.TypeReference || removedNodes.includes(node)) {
28
+ var _a, _b, _c, _d;
29
+ // Skip removed nodes.
30
+ if (removedNodes.includes(node)) {
30
31
  return;
31
32
  }
32
33
  // Record import and skip
@@ -35,16 +36,48 @@ function elideImports(sourceFile, removedNodes, getTypeChecker) {
35
36
  return;
36
37
  }
37
38
  let symbol;
38
- switch (node.kind) {
39
- case ts.SyntaxKind.Identifier:
39
+ if (ts.isTypeReferenceNode(node)) {
40
+ if (!compilerOptions.emitDecoratorMetadata) {
41
+ // Skip and mark as unused if emitDecoratorMetadata is disabled.
42
+ return;
43
+ }
44
+ const parent = node.parent;
45
+ let isTypeReferenceForDecoratoredNode = false;
46
+ switch (parent.kind) {
47
+ case ts.SyntaxKind.GetAccessor:
48
+ case ts.SyntaxKind.PropertyDeclaration:
49
+ case ts.SyntaxKind.MethodDeclaration:
50
+ isTypeReferenceForDecoratoredNode = !!((_a = parent.decorators) === null || _a === void 0 ? void 0 : _a.length);
51
+ break;
52
+ case ts.SyntaxKind.Parameter:
53
+ // - A constructor parameter can be decorated or the class itself is decorated.
54
+ // - The parent of the parameter is decorated example a method declaration or a set accessor.
55
+ // In all cases we need the type reference not to be elided.
56
+ isTypeReferenceForDecoratoredNode = !!(((_b = parent.decorators) === null || _b === void 0 ? void 0 : _b.length) ||
57
+ (ts.isSetAccessor(parent.parent) && !!((_c = parent.parent.decorators) === null || _c === void 0 ? void 0 : _c.length)) ||
58
+ (ts.isConstructorDeclaration(parent.parent) && !!((_d = parent.parent.parent.decorators) === null || _d === void 0 ? void 0 : _d.length)));
59
+ break;
60
+ }
61
+ if (isTypeReferenceForDecoratoredNode) {
40
62
  symbol = typeChecker.getSymbolAtLocation(node);
41
- break;
42
- case ts.SyntaxKind.ExportSpecifier:
43
- symbol = typeChecker.getExportSpecifierLocalTargetSymbol(node);
44
- break;
45
- case ts.SyntaxKind.ShorthandPropertyAssignment:
46
- symbol = typeChecker.getShorthandAssignmentValueSymbol(node);
47
- break;
63
+ }
64
+ else {
65
+ // If type reference is not for Decorator skip and marked as unused.
66
+ return;
67
+ }
68
+ }
69
+ else {
70
+ switch (node.kind) {
71
+ case ts.SyntaxKind.Identifier:
72
+ symbol = typeChecker.getSymbolAtLocation(node);
73
+ break;
74
+ case ts.SyntaxKind.ExportSpecifier:
75
+ symbol = typeChecker.getExportSpecifierLocalTargetSymbol(node);
76
+ break;
77
+ case ts.SyntaxKind.ShorthandPropertyAssignment:
78
+ symbol = typeChecker.getShorthandAssignmentValueSymbol(node);
79
+ break;
80
+ }
48
81
  }
49
82
  if (symbol) {
50
83
  usedSymbols.add(symbol);
@@ -24,7 +24,7 @@ function makeTransform(standardTransform, getTypeChecker) {
24
24
  // replace_resources), but may not be true for new transforms.
25
25
  if (getTypeChecker && removeOps.length + replaceOps.length > 0) {
26
26
  const removedNodes = removeOps.concat(replaceOps).map(op => op.target);
27
- removeOps.push(...elide_imports_1.elideImports(sf, removedNodes, getTypeChecker));
27
+ removeOps.push(...elide_imports_1.elideImports(sf, removedNodes, getTypeChecker, context.getCompilerOptions()));
28
28
  }
29
29
  const visitor = node => {
30
30
  let modified = false;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @license
3
+ * Copyright Google Inc. All Rights Reserved.
4
+ *
5
+ * Use of this source code is governed by an MIT-style license that can be
6
+ * found in the LICENSE file at https://angular.io/license
7
+ */
8
+ import * as ts from 'typescript';
9
+ export declare function removeIvyJitSupportCalls(classMetadata: boolean, ngModuleScope: boolean, getTypeChecker: () => ts.TypeChecker): ts.TransformerFactory<ts.SourceFile>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * @license
5
+ * Copyright Google Inc. All Rights Reserved.
6
+ *
7
+ * Use of this source code is governed by an MIT-style license that can be
8
+ * found in the LICENSE file at https://angular.io/license
9
+ */
10
+ const ts = require("typescript");
11
+ const ast_helpers_1 = require("./ast_helpers");
12
+ const interfaces_1 = require("./interfaces");
13
+ const make_transform_1 = require("./make_transform");
14
+ function removeIvyJitSupportCalls(classMetadata, ngModuleScope, getTypeChecker) {
15
+ const standardTransform = function (sourceFile) {
16
+ const ops = [];
17
+ ast_helpers_1.collectDeepNodes(sourceFile, ts.SyntaxKind.ExpressionStatement)
18
+ .filter(statement => {
19
+ const innerStatement = getIifeStatement(statement);
20
+ if (!innerStatement) {
21
+ return false;
22
+ }
23
+ if (ngModuleScope && ts.isBinaryExpression(innerStatement.expression)) {
24
+ return isIvyPrivateCallExpression(innerStatement.expression.right, 'ɵɵsetNgModuleScope');
25
+ }
26
+ return (classMetadata &&
27
+ isIvyPrivateCallExpression(innerStatement.expression, 'ɵsetClassMetadata'));
28
+ })
29
+ .forEach(statement => ops.push(new interfaces_1.RemoveNodeOperation(sourceFile, statement)));
30
+ return ops;
31
+ };
32
+ return make_transform_1.makeTransform(standardTransform, getTypeChecker);
33
+ }
34
+ exports.removeIvyJitSupportCalls = removeIvyJitSupportCalls;
35
+ // Each Ivy private call expression is inside an IIFE
36
+ function getIifeStatement(exprStmt) {
37
+ const expression = exprStmt.expression;
38
+ if (!expression || !ts.isCallExpression(expression) || expression.arguments.length !== 0) {
39
+ return null;
40
+ }
41
+ const parenExpr = expression;
42
+ if (!ts.isParenthesizedExpression(parenExpr.expression)) {
43
+ return null;
44
+ }
45
+ const funExpr = parenExpr.expression.expression;
46
+ if (!ts.isFunctionExpression(funExpr)) {
47
+ return null;
48
+ }
49
+ const innerStmts = funExpr.body.statements;
50
+ if (innerStmts.length !== 1) {
51
+ return null;
52
+ }
53
+ const innerExprStmt = innerStmts[0];
54
+ if (!ts.isExpressionStatement(innerExprStmt)) {
55
+ return null;
56
+ }
57
+ return innerExprStmt;
58
+ }
59
+ function isIvyPrivateCallExpression(expression, name) {
60
+ // Now we're in the IIFE and have the inner expression statement. We can check if it matches
61
+ // a private Ivy call.
62
+ if (!ts.isCallExpression(expression)) {
63
+ return false;
64
+ }
65
+ const propAccExpr = expression.expression;
66
+ if (!ts.isPropertyAccessExpression(propAccExpr)) {
67
+ return false;
68
+ }
69
+ if (propAccExpr.name.text != name) {
70
+ return false;
71
+ }
72
+ return true;
73
+ }
@@ -0,0 +1,7 @@
1
+ import * as ts from 'typescript';
2
+ import { WebpackCompilerHost } from '../compiler_host';
3
+ export declare function createTypescriptContext(content: string, additionalFiles?: Record<string, string>, useLibs?: boolean, extraCompilerOptions?: ts.CompilerOptions): {
4
+ compilerHost: WebpackCompilerHost;
5
+ program: ts.Program;
6
+ };
7
+ export declare function transformTypescript(content: string | undefined, transformers: ts.TransformerFactory<ts.SourceFile>[], program?: ts.Program, compilerHost?: WebpackCompilerHost): string | undefined;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * @license
5
+ * Copyright Google Inc. All Rights Reserved.
6
+ *
7
+ * Use of this source code is governed by an MIT-style license that can be
8
+ * found in the LICENSE file at https://angular.io/license
9
+ */
10
+ const core_1 = require("@angular-devkit/core");
11
+ const fs_1 = require("fs");
12
+ const path_1 = require("path");
13
+ const ts = require("typescript");
14
+ const compiler_host_1 = require("../compiler_host");
15
+ // Test transform helpers.
16
+ const basePath = '/project/src/';
17
+ const fileName = basePath + 'test-file.ts';
18
+ const typeScriptLibFiles = loadTypeScriptLibFiles();
19
+ const tsLibFiles = loadTsLibFiles();
20
+ function createTypescriptContext(content, additionalFiles, useLibs = false, extraCompilerOptions = {}) {
21
+ // Set compiler options.
22
+ const compilerOptions = {
23
+ noEmitOnError: useLibs,
24
+ allowJs: true,
25
+ newLine: ts.NewLineKind.LineFeed,
26
+ moduleResolution: ts.ModuleResolutionKind.NodeJs,
27
+ module: ts.ModuleKind.ESNext,
28
+ target: ts.ScriptTarget.ESNext,
29
+ skipLibCheck: true,
30
+ sourceMap: false,
31
+ importHelpers: true,
32
+ experimentalDecorators: true,
33
+ ...extraCompilerOptions,
34
+ };
35
+ // Create compiler host.
36
+ const compilerHost = new compiler_host_1.WebpackCompilerHost(compilerOptions, basePath, new core_1.virtualFs.SimpleMemoryHost(), false);
37
+ // Add a dummy file to host content.
38
+ compilerHost.writeFile(fileName, content, false);
39
+ if (useLibs) {
40
+ // Write the default libs.
41
+ // These are needed for tests that use import(), because it relies on a Promise being there.
42
+ const compilerLibFolder = path_1.dirname(compilerHost.getDefaultLibFileName(compilerOptions));
43
+ for (const [k, v] of Object.entries(typeScriptLibFiles)) {
44
+ compilerHost.writeFile(path_1.join(compilerLibFolder, k), v, false);
45
+ }
46
+ }
47
+ if (compilerOptions.importHelpers) {
48
+ for (const [k, v] of Object.entries(tsLibFiles)) {
49
+ compilerHost.writeFile(k, v, false);
50
+ }
51
+ }
52
+ if (additionalFiles) {
53
+ for (const key in additionalFiles) {
54
+ compilerHost.writeFile(basePath + key, additionalFiles[key], false);
55
+ }
56
+ }
57
+ // Create the TypeScript program.
58
+ const program = ts.createProgram([fileName], compilerOptions, compilerHost);
59
+ return { compilerHost, program };
60
+ }
61
+ exports.createTypescriptContext = createTypescriptContext;
62
+ function transformTypescript(content, transformers, program, compilerHost) {
63
+ // Use given context or create a new one.
64
+ if (content !== undefined) {
65
+ const typescriptContext = createTypescriptContext(content);
66
+ if (!program) {
67
+ program = typescriptContext.program;
68
+ }
69
+ if (!compilerHost) {
70
+ compilerHost = typescriptContext.compilerHost;
71
+ }
72
+ }
73
+ else if (!program || !compilerHost) {
74
+ throw new Error('transformTypescript needs either `content` or a `program` and `compilerHost');
75
+ }
76
+ // Emit.
77
+ const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, undefined, { before: transformers });
78
+ // Throw error with diagnostics if emit wasn't successfull.
79
+ if (emitSkipped) {
80
+ throw new Error(ts.formatDiagnostics(diagnostics, compilerHost));
81
+ }
82
+ // Return the transpiled js.
83
+ return compilerHost.readFile(fileName.replace(/\.tsx?$/, '.js'));
84
+ }
85
+ exports.transformTypescript = transformTypescript;
86
+ function loadTypeScriptLibFiles() {
87
+ const libFolderPath = path_1.dirname(require.resolve('typescript/lib/lib.d.ts'));
88
+ const libFolderFiles = fs_1.readdirSync(libFolderPath);
89
+ const libFileNames = libFolderFiles.filter(f => f.startsWith('lib.') && f.endsWith('.d.ts'));
90
+ // Return a map of the lib names to their content.
91
+ const libs = {};
92
+ for (const f of libFileNames) {
93
+ libs[f] = fs_1.readFileSync(path_1.join(libFolderPath, f), 'utf-8');
94
+ }
95
+ return libs;
96
+ }
97
+ function loadTsLibFiles() {
98
+ const libFolderPath = path_1.dirname(require.resolve('tslib/package.json'));
99
+ const libFolderFiles = fs_1.readdirSync(libFolderPath);
100
+ // Return a map of the lib names to their content.
101
+ const libs = {};
102
+ for (const f of libFolderFiles) {
103
+ libs[path_1.join('node_modules/tslib', f)] = fs_1.readFileSync(path_1.join(libFolderPath, f), 'utf-8');
104
+ }
105
+ return libs;
106
+ }
@@ -13,7 +13,7 @@ import { InputFileSystem } from 'webpack';
13
13
  export declare class WebpackInputHost implements virtualFs.Host<Stats> {
14
14
  readonly inputFileSystem: InputFileSystem;
15
15
  constructor(inputFileSystem: InputFileSystem);
16
- readonly capabilities: virtualFs.HostCapabilities;
16
+ get capabilities(): virtualFs.HostCapabilities;
17
17
  write(_path: Path, _content: virtualFs.FileBufferLike): Observable<never>;
18
18
  delete(_path: Path): Observable<never>;
19
19
  rename(_from: Path, _to: Path): Observable<never>;