Skip to content

Commit 8d7f109

Browse files
devversiondylhunn
authored andcommitted
refactor: make all imports compatible with ESM/CJS output. (angular#43431)
As outlined in the previous commit which enabled the `esModuleInterop` TypeScript compiler option, we need to update all namespace imports for `typescript` to default imports. This is needed to allow for TypeScript to be imported at runtime from an ES module. Similar changes are needed for modules like `semver` where the types incorrectly suggest named exports that will not exist at runtime when imported from ESM. This commit refactors all imports to match with the lint rule we have configured in the previous commit. See the previous commit for more details on why certain imports have been changed. A special case are the imports to `@babel/core` and `@babel/types`. For these a special interop is needed as both default imports, or named imports break the other module format. e.g default imports would work well for ESM, but it breaks for CJS. For CJS, the named imports would only work, but in ESM, only the default export exist. We work around this for now until the devmode is using ESM as well (which would be consistent with prodmode and gives us more valuable test results). More details on the interop can be found in the `babel_core.ts` files (two interops are needed for both localize/or the compiler-cli). PR Close angular#43431
1 parent d15a692 commit 8d7f109

File tree

471 files changed

+691
-583
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

471 files changed

+691
-583
lines changed

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
"@babel/preset-env": "7.10.2",
6262
"@babel/template": "7.8.6",
6363
"@babel/traverse": "7.8.6",
64-
"@babel/types": "7.8.6",
6564
"@bazel/concatjs": "4.3.0",
6665
"@bazel/esbuild": "4.3.0",
6766
"@bazel/jasmine": "4.3.0",

packages/bazel/src/ngc-wrapped/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {BazelOptions, CachedFileLoader, CompilerHost, constructManifest, debug,
1212
import * as fs from 'fs';
1313
import * as path from 'path';
1414
import * as tsickle from 'tsickle';
15-
import * as ts from 'typescript';
15+
import ts from 'typescript';
1616

1717
const EXT = /(\.ts|\.d\.ts|\.js|\.jsx|\.tsx)$/;
1818
const NGC_GEN_FILES = /^(.*?)\.(ngfactory|ngsummary|ngstyle|shim\.ngstyle)(.*)$/;

packages/bazel/test/ngc-wrapped/test_support.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {runOneBuild} from '@angular/bazel';
1010
import * as fs from 'fs';
1111
import * as path from 'path';
12-
import * as ts from 'typescript';
12+
import ts from 'typescript';
1313

1414
import {createTsConfig} from './tsconfig_template';
1515

packages/common/locales/generate-locales-tool/cldr-data.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import {runfiles} from '@bazel/runfiles';
1010
import {CldrStatic} from 'cldrjs';
11-
import {sync as globSync} from 'glob';
11+
import glob from 'glob';
1212

1313
// TypeScript doesn't allow us to import the default export without the `esModuleInterop`. We use
1414
// the NodeJS require function instead as specifying a custom tsconfig complicates the setup
@@ -141,7 +141,7 @@ export class CldrData {
141141
*/
142142
private _readCldrDataFromRepository(): object[] {
143143
const jsonFiles =
144-
CLDR_DATA_GLOBS.map(pattern => globSync(pattern, {cwd: this.cldrDataDir, absolute: true}))
144+
CLDR_DATA_GLOBS.map(pattern => glob.sync(pattern, {cwd: this.cldrDataDir, absolute: true}))
145145
.reduce((acc, dataFiles) => [...acc, ...dataFiles], []);
146146

147147
// Read the JSON for all determined CLDR json files.

packages/compiler-cli/BUILD.bazel

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ esbuild(
4242
"@angular/compiler",
4343
"typescript",
4444
"@babel/core",
45-
"@babel/types",
4645
"reflect-metadata",
4746
"minimist",
4847
"canonical-path",

packages/compiler-cli/linker/babel/BUILD.bazel

-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ ts_library(
1414
"//packages/compiler-cli/src/ngtsc/logging",
1515
"//packages/compiler-cli/src/ngtsc/translator",
1616
"@npm//@babel/core",
17-
"@npm//@babel/types",
1817
"@npm//@types/babel__core",
1918
"@npm//@types/babel__traverse",
2019
],

packages/compiler-cli/linker/babel/src/ast/babel_ast_factory.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import * as t from '@babel/types';
9-
108
import {assert} from '../../../../linker';
119
import {AstFactory, BinaryOperator, LeadingComment, ObjectLiteralProperty, SourceMapRange, TemplateLiteral, VariableDeclarationType} from '../../../../src/ngtsc/translator';
10+
import {types as t} from '../babel_core';
1211

1312
/**
1413
* A Babel flavored implementation of the AstFactory.

packages/compiler-cli/linker/babel/src/ast/babel_ast_host.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import * as t from '@babel/types';
10-
119
import {assert, AstHost, FatalLinkerError, Range} from '../../../../linker';
10+
import {types as t} from '../babel_core';
1211

1312
/**
1413
* This implementation of `AstHost` is able to get information from Babel AST nodes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC 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+
9+
/**
10+
* This is an interop file allowing for `@babel/core` to be imported in both CommonJS or
11+
* ES module files. The `@babel/core` package needs some special treatment because:
12+
*
13+
* Using a default import does not with CommonJS because the `@babel/core` package does not
14+
* expose a `default` export at runtime (because it sets the `_esModule` property that causes
15+
* TS to not create the necessary interop `default` export). On the other side, when loaded
16+
* as part of an ESM, NodeJS will make all of the exports available as default export.
17+
*
18+
* Using named import bindings (i.e. namespace import or actual named bindings) is not
19+
* working well for ESM because as said before, NodeJS will make all of the exports available
20+
* as the `default` export. Hence ESM that imports CJS, always should use the default import.
21+
*
22+
* There is no solution that would work for both CJS and ESM, so we need to use a custom interop
23+
* that switches between the named exports or the default exports depending on what is available.
24+
* This allows the code to run in both ESM (for production) and CJS (for development).
25+
*
26+
* TODO(devversion): remove this once devmode uses ESM as well.
27+
*/
28+
29+
// tslint:disable-next-line
30+
import * as _babelNamespace from '@babel/core';
31+
// tslint:disable-next-line
32+
import _babelDefault from '@babel/core';
33+
34+
const babel: typeof _babelNamespace = _babelDefault ?? _babelNamespace;
35+
36+
// We create an alias of the `types` namespace so that we can re-export the
37+
// types namespace. Preserving the namespace is important so that types
38+
// can still be referenced using a qualified name.
39+
import _typesNamespace = _babelNamespace.types;
40+
41+
// If the default export is available, we use its `types` runtime value
42+
// for the type namespace we re-export. This is a trick we use to preserve
43+
// the namespace types, while changing the runtime value of the namespace.
44+
// TS complains about us assigning to a namespace but this is legal at runtime.
45+
if (_babelDefault !== undefined) {
46+
// @ts-ignore
47+
_typesNamespace = _babelDefault.types;
48+
}
49+
50+
export import types = _typesNamespace;
51+
export type PluginObj = _babelNamespace.PluginObj;
52+
export type ConfigAPI = _babelNamespace.ConfigAPI;
53+
export type NodePath<T = _babelNamespace.Node> = _babelNamespace.NodePath<T>;
54+
55+
export const NodePath: typeof _babelNamespace.NodePath = babel.NodePath;
56+
export const transformSync: typeof _babelNamespace.transformSync = babel.transformSync;
57+
export const parse: typeof _babelNamespace.parse = babel.parse;

packages/compiler-cli/linker/babel/src/babel_declaration_scope.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import {NodePath, Scope} from '@babel/traverse';
9-
import * as t from '@babel/types';
109

1110
import {DeclarationScope} from '../../../linker';
1211

12+
import {types as t} from './babel_core';
13+
1314
export type ConstantScopePath = NodePath<t.Function|t.Program>;
1415

1516
/**

packages/compiler-cli/linker/babel/src/babel_plugin.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {ConfigAPI, PluginObj} from '@babel/core';
9-
108
import {NodeJSFileSystem} from '../../../src/ngtsc/file_system';
119
import {ConsoleLogger, LogLevel} from '../../../src/ngtsc/logging';
1210
import {LinkerOptions} from '../../src/file_linker/linker_options';
1311

12+
import {ConfigAPI, PluginObj} from './babel_core';
1413
import {createEs2015LinkerPlugin} from './es2015_linker_plugin';
1514

1615
/**

packages/compiler-cli/linker/babel/src/es2015_linker_plugin.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {PluginObj} from '@babel/core';
8+
99
import {NodePath} from '@babel/traverse';
10-
import * as t from '@babel/types';
1110

1211
import {FileLinker, isFatalLinkerError, LinkerEnvironment} from '../../../linker';
1312

1413
import {BabelAstFactory} from './ast/babel_ast_factory';
1514
import {BabelAstHost} from './ast/babel_ast_host';
15+
import {PluginObj, types as t} from './babel_core';
1616
import {BabelDeclarationScope, ConstantScopePath} from './babel_declaration_scope';
1717
import {LinkerPluginOptions} from './linker_plugin_options';
1818

packages/compiler-cli/linker/babel/test/BUILD.bazel

-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ ts_library(
1616
"//packages/compiler-cli/src/ngtsc/file_system/testing",
1717
"//packages/compiler-cli/src/ngtsc/logging/testing",
1818
"//packages/compiler-cli/src/ngtsc/translator",
19-
"@npm//@babel/core",
2019
"@npm//@babel/generator",
2120
"@npm//@babel/parser",
2221
"@npm//@babel/template",
2322
"@npm//@babel/traverse",
24-
"@npm//@babel/types",
2523
"@npm//@types/babel__core",
2624
"@npm//@types/babel__generator",
2725
"@npm//@types/babel__template",

packages/compiler-cli/linker/babel/test/ast/babel_ast_factory_spec.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@
77
*/
88
import {leadingComment} from '@angular/compiler';
99
import generate from '@babel/generator';
10-
import {expression, statement} from '@babel/template';
11-
import * as t from '@babel/types';
10+
import template from '@babel/template';
11+
import {types as t} from '../../src/babel_core';
1212

1313
import {BabelAstFactory} from '../../src/ast/babel_ast_factory';
1414

15+
// Exposes shothands for the `expression` and `statement`
16+
// methods exposed by `@babel/template`.
17+
const expression = template.expression;
18+
const statement = template.statement;
19+
1520
describe('BabelAstFactory', () => {
1621
let factory: BabelAstFactory;
1722
beforeEach(() => factory = new BabelAstFactory('/original.ts'));

packages/compiler-cli/linker/babel/test/ast/babel_ast_host_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import * as t from '@babel/types';
8+
import {types as t} from '../../src/babel_core';
99
import template from '@babel/template';
1010
import {parse} from '@babel/parser';
1111
import {BabelAstHost} from '../../src/ast/babel_ast_host';

packages/compiler-cli/linker/babel/test/babel_declaration_scope_spec.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8+
89
import {parse} from '@babel/parser';
910
import traverse, {NodePath} from '@babel/traverse';
10-
import * as t from '@babel/types';
11+
12+
import {types as t} from '../src/babel_core';
1113
import {BabelDeclarationScope} from '../src/babel_declaration_scope';
1214

1315
describe('BabelDeclarationScope', () => {

packages/compiler-cli/linker/babel/test/babel_plugin_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {transformSync} from '@babel/core';
8+
import {transformSync} from '../src/babel_core';
99

1010
describe('default babel plugin entry-point', () => {
1111
it('should work as a Babel plugin using the module specifier', () => {

packages/compiler-cli/linker/babel/test/es2015_linker_plugin_spec.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import * as o from '@angular/compiler/src/output/output_ast';
9-
import {NodePath, PluginObj, transformSync} from '@babel/core';
109
import generate from '@babel/generator';
11-
import * as t from '@babel/types';
1210

1311
import {FileLinker} from '../../../linker';
1412
import {MockFileSystemNative} from '../../../src/ngtsc/file_system/testing';
1513
import {MockLogger} from '../../../src/ngtsc/logging/testing';
1614
import {PartialDirectiveLinkerVersion1} from '../../src/file_linker/partial_linkers/partial_directive_linker_1';
15+
import {NodePath, PluginObj, transformSync, types as t} from '../src/babel_core';
1716
import {createEs2015LinkerPlugin} from '../src/es2015_linker_plugin';
1817

1918
describe('createEs2015LinkerPlugin()', () => {

packages/compiler-cli/linker/src/ast/typescript/typescript_ast_host.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import * as ts from 'typescript';
9+
import ts from 'typescript';
1010

1111
import {FatalLinkerError} from '../../fatal_linker_error';
1212
import {AstHost, Range} from '../ast_host';

packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_linker_selector.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {intersects, Range, SemVer} from 'semver';
8+
import semver from 'semver';
99

1010
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system';
1111
import {Logger} from '../../../../src/ngtsc/logging';
@@ -36,7 +36,7 @@ export const declarationFunctions = [
3636
];
3737

3838
export interface LinkerRange<TExpression> {
39-
range: Range;
39+
range: semver.Range;
4040
linker: PartialLinker<TExpression>;
4141
}
4242

@@ -151,7 +151,7 @@ export class PartialLinkerSelector<TExpression> {
151151

152152
const declarationRange = getRange('>=', minVersion);
153153
for (const {range: linkerRange, linker} of linkerRanges) {
154-
if (intersects(declarationRange, linkerRange)) {
154+
if (semver.intersects(declarationRange, linkerRange)) {
155155
return linker;
156156
}
157157
}
@@ -183,9 +183,9 @@ export class PartialLinkerSelector<TExpression> {
183183
* @param versionStr the version given in the partial declaration
184184
* @returns A semver range for the provided `version` and comparator.
185185
*/
186-
function getRange(comparator: '<='|'>=', versionStr: string): Range {
187-
const version = new SemVer(versionStr);
186+
function getRange(comparator: '<='|'>=', versionStr: string): semver.Range {
187+
const version = new semver.SemVer(versionStr);
188188
// Wipe out any prerelease versions
189189
version.prerelease = [];
190-
return new Range(`${comparator}${version.format()}`);
190+
return new semver.Range(`${comparator}${version.format()}`);
191191
}

packages/compiler-cli/linker/test/ast/ast_value_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88
import {WrappedNodeExpr} from '@angular/compiler';
99
import {TypeScriptAstFactory} from '@angular/compiler-cli/src/ngtsc/translator';
10-
import * as ts from 'typescript';
10+
import ts from 'typescript';
1111

1212
import {AstHost} from '../../src/ast/ast_host';
1313
import {AstObject, AstValue} from '../../src/ast/ast_value';

packages/compiler-cli/linker/test/ast/typescript/typescript_ast_host_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import * as ts from 'typescript';
8+
import ts from 'typescript';
99
import {TypeScriptAstHost} from '../../../src/ast/typescript/typescript_ast_host';
1010

1111
describe('TypeScriptAstHost', () => {

packages/compiler-cli/linker/test/file_linker/emit_scopes/emit_scope_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import * as o from '@angular/compiler/src/output/output_ast';
9-
import * as ts from 'typescript';
9+
import ts from 'typescript';
1010

1111
import {TypeScriptAstFactory} from '../../../../src/ngtsc/translator';
1212
import {EmitScope} from '../../../src/file_linker/emit_scopes/emit_scope';

packages/compiler-cli/linker/test/file_linker/emit_scopes/iief_emit_scope_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import * as o from '@angular/compiler/src/output/output_ast';
9-
import * as ts from 'typescript';
9+
import ts from 'typescript';
1010

1111
import {TypeScriptAstFactory} from '../../../../src/ngtsc/translator';
1212
import {IifeEmitScope} from '../../../src/file_linker/emit_scopes/iife_emit_scope';

packages/compiler-cli/linker/test/file_linker/file_linker_spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import * as o from '@angular/compiler/src/output/output_ast';
9-
import * as ts from 'typescript';
9+
import ts from 'typescript';
1010

1111
import {MockFileSystemNative} from '../../../src/ngtsc/file_system/testing';
1212
import {MockLogger} from '../../../src/ngtsc/logging/testing';

packages/compiler-cli/linker/test/file_linker/helpers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import * as ts from 'typescript';
8+
import ts from 'typescript';
99

1010
/**
1111
* A simple helper to render a TS Node as a string.

packages/compiler-cli/linker/test/file_linker/partial_linkers/partial_linker_selector_spec.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {Range} from 'semver';
8+
import semver from 'semver';
99

1010
import {MockLogger} from '../../../../src/ngtsc/logging/testing';
1111
import {PartialLinker} from '../../../src/file_linker/partial_linkers/partial_linker';
@@ -111,12 +111,12 @@ describe('PartialLinkerSelector', () => {
111111
function createSelector(unknownDeclarationVersionHandling: 'error'|'warn'|'ignore') {
112112
const linkerMap = new Map<string, LinkerRange<unknown>[]>();
113113
linkerMap.set('declareA', [
114-
{range: new Range('<=12.0.0'), linker: linkerA},
115-
{range: new Range('<=13.0.0'), linker: linkerA2}
114+
{range: new semver.Range('<=12.0.0'), linker: linkerA},
115+
{range: new semver.Range('<=13.0.0'), linker: linkerA2}
116116
]);
117117
linkerMap.set('declareB', [
118-
{range: new Range('<=12.0.0'), linker: linkerB},
119-
{range: new Range('<=12.1.0'), linker: linkerB2},
118+
{range: new semver.Range('<=12.0.0'), linker: linkerB},
119+
{range: new semver.Range('<=12.1.0'), linker: linkerB2},
120120
]);
121121
return new PartialLinkerSelector(linkerMap, logger, unknownDeclarationVersionHandling);
122122
}

0 commit comments

Comments
 (0)