Skip to content

Commit e9fcbb8

Browse files
alan-agius4thePunderWoman
authored andcommitted
fix(compiler): remove TypeScript from linker (angular#61618)
This commit removes the direct dependency on TypeScript within the linker, addressing a performance overhead that was adding between 500ms to 1s to compilation times for applications. The primary cause of this overhead was the linker's direct reliance on TypeScript's which was caused by importing from barrel files. While convenient, barrel files are detrimental to code splitting and code motion. They force the bundling of all exported modules, even if only a subset is actually used. By removing the usage of this barrel file and restructuring the imports to be more granular, we can avoid unnecessary TypeScript imports. Furthermore, TypeScript has now been changed to an optional peer dependency as using only the linker does not require TypeScript. PR Close angular#61618
1 parent 82327f2 commit e9fcbb8

File tree

18 files changed

+67
-23
lines changed

18 files changed

+67
-23
lines changed

.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# This file should be checked into version control along with the pnpm-lock.yaml file.
44
.npmrc=-1406867100
55
package.json=-1316846371
6-
packages/compiler-cli/package.json=1094415146
6+
packages/compiler-cli/package.json=-1344632265
77
packages/compiler/package.json=1190056499
88
pnpm-lock.yaml=1584116426
99
pnpm-workspace.yaml=353334404

.bazelignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ integration/ng_elements/node_modules
2424
integration/ng_update/node_modules
2525
integration/ng_update_migrations/node_modules
2626
integration/ng-add-localize/node_modules
27+
integration/no_ts_linker/node_modules
2728
integration/nodenext_resolution/node_modules
2829
integration/platform-server/node_modules
2930
integration/platform-server-zoneless/node_modules

integration/no_ts_linker/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
load("//integration:index.bzl", "ng_integration_test")
2+
3+
ng_integration_test(
4+
name = "test",
5+
)

integration/no_ts_linker/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "angular-integration",
3+
"description": "Assert that the linker has no dependency on TypeScript.",
4+
"version": "0.0.0",
5+
"license": "MIT",
6+
"type": "module",
7+
"dependencies": {
8+
"@angular/compiler": "file:../../dist/packages-dist/compiler",
9+
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
10+
"@angular/core": "file:../../dist/packages-dist/core",
11+
"rxjs": "file:../../node_modules/rxjs"
12+
},
13+
"scripts": {
14+
"test": "node ./test.mjs"
15+
}
16+
}

integration/no_ts_linker/test.mjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import assert from 'node:assert';
2+
3+
(async () => {
4+
// Verify that TypeScript is not installed.
5+
await assert.rejects(
6+
() => import('typescript'),
7+
({code, message}) => {
8+
assert.strictEqual(code, 'ERR_MODULE_NOT_FOUND');
9+
assert.match(message, new RegExp(`Cannot find package 'typescript'`));
10+
11+
return true;
12+
},
13+
);
14+
15+
// This validates that the linker has no dependency on TypeScript.
16+
await import('@angular/compiler-cli/linker');
17+
await import('@angular/compiler-cli/linker/babel');
18+
})();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
SourceMapRange,
1717
TemplateLiteral,
1818
VariableDeclarationType,
19-
} from '../../../../src/ngtsc/translator';
19+
} from '../../../../src/ngtsc/translator/src/api/ast_factory';
2020

2121
/**
2222
* A Babel flavored implementation of the AstFactory.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@
77
*/
88
import {ConfigAPI, PluginObj} from '@babel/core';
99

10-
import {NodeJSFileSystem} from '../../../src/ngtsc/file_system';
1110
import {ConsoleLogger, LogLevel} from '../../../src/ngtsc/logging';
1211
import {LinkerOptions} from '../../src/file_linker/linker_options';
1312

1413
import {createEs2015LinkerPlugin} from './es2015_linker_plugin';
14+
import {NodeJSFileSystem} from '../../../src/ngtsc/file_system/src/node_js_file_system';
1515

1616
/**
1717
* This is the Babel plugin definition that is provided as a default export from the package, such

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88
import {LinkerOptions} from '../..';
9-
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
9+
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system/src/types';
1010
import {Logger} from '../../../src/ngtsc/logging';
1111

1212
export interface LinkerPluginOptions extends Partial<LinkerOptions> {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
*/
88
import {R3PartialDeclaration} from '@angular/compiler';
99

10-
import {AbsoluteFsPath} from '../../../src/ngtsc/file_system';
1110
import {AstObject} from '../ast/ast_value';
1211

1312
import {DeclarationScope} from './declaration_scope';
1413
import {EmitScope} from './emit_scopes/emit_scope';
1514
import {LocalEmitScope} from './emit_scopes/local_emit_scope';
1615
import {LinkerEnvironment} from './linker_environment';
1716
import {createLinkerMap, PartialLinkerSelector} from './partial_linkers/partial_linker_selector';
17+
import {AbsoluteFsPath} from '../../../src/ngtsc/file_system/src/types';
1818

1919
export const NO_STATEMENTS: Readonly<any[]> = [] as const;
2020

packages/compiler-cli/linker/src/file_linker/get_source_file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {AbsoluteFsPath} from '../../../src/ngtsc/file_system';
9+
import {AbsoluteFsPath} from '../../../src/ngtsc/file_system/src/types';
1010
import {SourceFile, SourceFileLoader} from '../../../src/ngtsc/sourcemaps';
1111

1212
/**

packages/compiler-cli/linker/src/file_linker/linker_environment.ts

Lines changed: 1 addition & 1 deletion
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.dev/license
77
*/
8-
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system';
8+
import {ReadonlyFileSystem} from '../../../src/ngtsc/file_system/src/types';
99
import {Logger} from '../../../src/ngtsc/logging';
1010
import {SourceFileLoader} from '../../../src/ngtsc/sourcemaps';
1111
import {AstFactory} from '../../../src/ngtsc/translator';

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import {
3333
} from '@angular/compiler';
3434
import semver from 'semver';
3535

36-
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system';
3736
import {Range} from '../../ast/ast_host';
3837
import {AstObject, AstValue} from '../../ast/ast_value';
3938
import {FatalLinkerError} from '../../fatal_linker_error';
@@ -42,6 +41,7 @@ import {GetSourceFileFn} from '../get_source_file';
4241
import {toR3DirectiveMeta} from './partial_directive_linker_1';
4342
import {LinkedDefinition, PartialLinker} from './partial_linker';
4443
import {extractForwardRef, PLACEHOLDER_VERSION} from './util';
44+
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system/src/types';
4545

4646
function makeDirectiveMetadata<TExpression>(
4747
directiveExpr: AstObject<R3DeclareDirectiveDependencyMetadata, TExpression>,

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ import {
2626
R3QueryMetadata,
2727
} from '@angular/compiler';
2828

29-
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system';
3029
import {Range} from '../../ast/ast_host';
3130
import {AstObject, AstValue} from '../../ast/ast_value';
3231
import {FatalLinkerError} from '../../fatal_linker_error';
3332

3433
import {LinkedDefinition, PartialLinker} from './partial_linker';
3534
import {extractForwardRef, getDefaultStandaloneValue, wrapReference} from './util';
35+
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system/src/types';
3636

3737
/**
3838
* A `PartialLinker` that is designed to process `ɵɵngDeclareDirective()` call expressions.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88
import semver from 'semver';
99

10-
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system';
1110
import {Logger} from '../../../../src/ngtsc/logging';
1211
import {createGetSourceFile} from '../get_source_file';
1312
import {LinkerEnvironment} from '../linker_environment';
@@ -23,6 +22,7 @@ import {PartialLinker} from './partial_linker';
2322
import {PartialNgModuleLinkerVersion1} from './partial_ng_module_linker_1';
2423
import {PartialPipeLinkerVersion1} from './partial_pipe_linker_1';
2524
import {PLACEHOLDER_VERSION} from './util';
25+
import {AbsoluteFsPath} from '../../../../src/ngtsc/file_system/src/types';
2626

2727
export const ɵɵngDeclareDirective = 'ɵɵngDeclareDirective';
2828
export const ɵɵngDeclareClassMetadata = 'ɵɵngDeclareClassMetadata';

packages/compiler-cli/linker/src/file_linker/translator.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88
import * as o from '@angular/compiler';
9-
109
import {
11-
AstFactory,
12-
Context,
1310
ExpressionTranslatorVisitor,
14-
ImportGenerator,
1511
TranslatorOptions,
16-
} from '../../../src/ngtsc/translator';
12+
} from '../../../src/ngtsc/translator/src/translator';
13+
import {Context} from '../../../src/ngtsc/translator/src/context';
14+
import {ImportGenerator} from '../../../src/ngtsc/translator/src/api/import_generator';
15+
import {AstFactory} from '../../../src/ngtsc/translator/src/api/ast_factory';
1716

1817
/**
1918
* Generic translator helper class, which exposes methods for translating expressions and

packages/compiler-cli/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@
5555
"@angular/compiler": "0.0.0-PLACEHOLDER",
5656
"typescript": ">=5.8 <5.9"
5757
},
58+
"peerDependenciesMeta": {
59+
"typescript": {
60+
"optional": true
61+
}
62+
},
5863
"devDependencies": {
5964
"@angular/compiler": "workspace:*"
6065
},

packages/compiler-cli/src/ngtsc/translator/src/translator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ import {
1919
import {ImportGenerator} from './api/import_generator';
2020
import {Context} from './context';
2121

22-
const UNARY_OPERATORS = new Map<o.UnaryOperator, UnaryOperator>([
22+
const UNARY_OPERATORS = /* @__PURE__ */ new Map<o.UnaryOperator, UnaryOperator>([
2323
[o.UnaryOperator.Minus, '-'],
2424
[o.UnaryOperator.Plus, '+'],
2525
]);
2626

27-
const BINARY_OPERATORS = new Map<o.BinaryOperator, BinaryOperator>([
27+
const BINARY_OPERATORS = /* @__PURE__ */ new Map<o.BinaryOperator, BinaryOperator>([
2828
[o.BinaryOperator.And, '&&'],
2929
[o.BinaryOperator.Bigger, '>'],
3030
[o.BinaryOperator.BiggerEquals, '>='],

packages/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ enum PureAnnotation {
3434
TERSER = '@__PURE__',
3535
}
3636

37-
const UNARY_OPERATORS: Record<UnaryOperator, ts.PrefixUnaryOperator> = {
37+
const UNARY_OPERATORS: Record<UnaryOperator, ts.PrefixUnaryOperator> = /* @__PURE__ */ (() => ({
3838
'+': ts.SyntaxKind.PlusToken,
3939
'-': ts.SyntaxKind.MinusToken,
4040
'!': ts.SyntaxKind.ExclamationToken,
41-
};
41+
}))();
4242

43-
const BINARY_OPERATORS: Record<BinaryOperator, ts.BinaryOperator> = {
43+
const BINARY_OPERATORS: Record<BinaryOperator, ts.BinaryOperator> = /* @__PURE__ */ (() => ({
4444
'&&': ts.SyntaxKind.AmpersandAmpersandToken,
4545
'>': ts.SyntaxKind.GreaterThanToken,
4646
'>=': ts.SyntaxKind.GreaterThanEqualsToken,
@@ -61,13 +61,13 @@ const BINARY_OPERATORS: Record<BinaryOperator, ts.BinaryOperator> = {
6161
'+': ts.SyntaxKind.PlusToken,
6262
'??': ts.SyntaxKind.QuestionQuestionToken,
6363
'in': ts.SyntaxKind.InKeyword,
64-
};
64+
}))();
6565

66-
const VAR_TYPES: Record<VariableDeclarationType, ts.NodeFlags> = {
66+
const VAR_TYPES: Record<VariableDeclarationType, ts.NodeFlags> = /* @__PURE__ */ (() => ({
6767
'const': ts.NodeFlags.Const,
6868
'let': ts.NodeFlags.Let,
6969
'var': ts.NodeFlags.None,
70-
};
70+
}))();
7171

7272
/**
7373
* A TypeScript flavoured implementation of the AstFactory.

0 commit comments

Comments
 (0)