Skip to content

Commit b47078f

Browse files
committed
refactor(@ngtools/webpack): support optional baseUrl with tsconfig paths
The Webpack plugin now ensures a `baseUrl` is set when `paths` are present, using the `pathsBasePath` as a fallback. This makes the `baseUrl` property optional in `tsconfig.json` files when `paths` are used. This commit also refactors several tests to remove their reliance on a pre-existing `baseUrl`. The tests now programmatically add `paths` to the `tsconfig.json` to avoid brittle string replacements. The test project's base `tsconfig.json` has also been updated to remove the now optional `baseUrl`.
1 parent 73b9e37 commit b47078f

File tree

8 files changed

+56
-81
lines changed

8 files changed

+56
-81
lines changed

modules/testing/builder/projects/hello-world-app/tsconfig.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"compileOnSave": false,
33
"compilerOptions": {
4-
"baseUrl": "./",
54
"outDir": "./dist/out-tsc",
65
"sourceMap": true,
76
"declaration": false,

packages/angular/build/src/builders/application/tests/behavior/typescript-path-mapping_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
8181
await harness.modifyFile('tsconfig.json', (content) => {
8282
const tsconfig = JSON.parse(content);
8383
tsconfig.compilerOptions.paths = {
84-
'app-module': ['a.js'],
84+
'app-module': ['./a.js'],
8585
};
8686

8787
return JSON.stringify(tsconfig);

packages/angular/build/src/builders/application/tests/options/allowed-common-js-dependencies_spec.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,13 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
129129

130130
it('should not show warning in JIT for templateUrl and styleUrl when using paths', async () => {
131131
await harness.modifyFile('tsconfig.json', (content) => {
132-
return content.replace(
133-
/"baseUrl": ".\/",/,
134-
`
135-
"baseUrl": "./",
136-
"paths": {
137-
"@app/*": [
138-
"src/app/*"
139-
]
140-
},
141-
`,
142-
);
132+
const tsconfig = JSON.parse(content);
133+
tsconfig.compilerOptions ??= {};
134+
tsconfig.compilerOptions.paths = {
135+
'@app/*': ['./src/app/*'],
136+
};
137+
138+
return JSON.stringify(tsconfig, null, 2);
143139
});
144140

145141
await harness.modifyFile('src/app/app.module.ts', (content) =>

packages/angular/build/src/builders/karma/tests/options/code-coverage_spec.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,15 @@ describeKarmaBuilder(execute, KARMA_BUILDER_INFO, (harness, setupTarget) => {
8888
}
8989
`,
9090
});
91-
await harness.modifyFile('tsconfig.json', (content) =>
92-
content.replace(
93-
/"baseUrl": ".\/",/,
94-
`
95-
"baseUrl": "./",
96-
"paths": {
97-
"my-lib": [
98-
"./dist/my-lib"
99-
]
100-
},
101-
`,
102-
),
103-
);
91+
await harness.modifyFile('tsconfig.json', (content) => {
92+
const tsconfig = JSON.parse(content);
93+
tsconfig.compilerOptions ??= {};
94+
tsconfig.compilerOptions.paths = {
95+
'my-lib': ['./dist/my-lib'],
96+
};
97+
98+
return JSON.stringify(tsconfig, null, 2);
99+
});
104100

105101
harness.useTarget('test', {
106102
...BASE_OPTIONS,

packages/angular_devkit/build_angular/src/builders/browser/specs/tsconfig-paths_spec.ts

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import { Architect } from '@angular-devkit/architect';
10+
import { normalize, virtualFs } from '@angular-devkit/core';
1011
import { browserBuild, createArchitect, host } from '../../../testing/test-utils';
1112

1213
describe('Browser Builder tsconfig paths', () => {
@@ -21,18 +22,16 @@ describe('Browser Builder tsconfig paths', () => {
2122

2223
it('should resolve basic tsconfig paths', async () => {
2324
host.replaceInFile('src/app/app.module.ts', './app.component', '@root/app/app.component');
24-
host.replaceInFile(
25-
'tsconfig.json',
26-
/"baseUrl": ".\/",/,
27-
`
28-
"baseUrl": "./",
29-
"paths": {
30-
"@root/*": [
31-
"./src/*"
32-
]
33-
},
34-
`,
35-
);
25+
26+
const tsconfigPath = normalize('tsconfig.json');
27+
const tsconfig = JSON.parse(virtualFs.fileBufferToString(host.scopedSync().read(tsconfigPath)));
28+
tsconfig.compilerOptions ??= {};
29+
tsconfig.compilerOptions.paths = {
30+
'@root/*': ['./src/*'],
31+
};
32+
host
33+
.scopedSync()
34+
.write(tsconfigPath, virtualFs.stringToFileBuffer(JSON.stringify(tsconfig, null, 2)));
3635

3736
await browserBuild(architect, host, target);
3837
});
@@ -43,25 +42,17 @@ describe('Browser Builder tsconfig paths', () => {
4342
'src/app/shared/meaning.ts': 'export var meaning = 42;',
4443
'src/app/shared/index.ts': `export * from './meaning'`,
4544
});
46-
host.replaceInFile(
47-
'tsconfig.json',
48-
/"baseUrl": ".\/",/,
49-
`
50-
"baseUrl": "./",
51-
"paths": {
52-
"@shared": [
53-
"src/app/shared"
54-
],
55-
"@shared/*": [
56-
"src/app/shared/*"
57-
],
58-
"*": [
59-
"*",
60-
"src/app/shared/*"
61-
]
62-
},
63-
`,
64-
);
45+
const tsconfigPath = normalize('tsconfig.json');
46+
const tsconfig = JSON.parse(virtualFs.fileBufferToString(host.scopedSync().read(tsconfigPath)));
47+
tsconfig.compilerOptions ??= {};
48+
tsconfig.compilerOptions.paths = {
49+
'@shared': ['src/app/shared'],
50+
'@shared/*': ['src/app/shared/*'],
51+
'*': ['*', 'src/app/shared/*'],
52+
};
53+
host
54+
.scopedSync()
55+
.write(tsconfigPath, virtualFs.stringToFileBuffer(JSON.stringify(tsconfig, null, 2)));
6556
host.appendToFile(
6657
'src/app/app.component.ts',
6758
`

packages/angular_devkit/build_angular/src/builders/browser/tests/options/allowed-common-js-dependencies_spec.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,13 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
119119

120120
it('should not show warning in JIT for templateUrl and styleUrl when using paths', async () => {
121121
await harness.modifyFile('tsconfig.json', (content) => {
122-
return content.replace(
123-
/"baseUrl": ".\/",/,
124-
`
125-
"baseUrl": "./",
126-
"paths": {
127-
"@app/*": [
128-
"src/app/*"
129-
]
130-
},
131-
`,
132-
);
122+
const tsconfig = JSON.parse(content);
123+
tsconfig.compilerOptions ??= {};
124+
tsconfig.compilerOptions.paths = {
125+
'@app/*': ['src/app/*'],
126+
};
127+
128+
return JSON.stringify(tsconfig, null, 2);
133129
});
134130

135131
await harness.modifyFile('src/app/app.module.ts', (content) =>

packages/angular_devkit/build_angular/src/builders/karma/tests/options/code-coverage_spec.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,15 @@ describeKarmaBuilder(execute, KARMA_BUILDER_INFO, (harness, setupTarget) => {
8888
}
8989
`,
9090
});
91-
await harness.modifyFile('tsconfig.json', (content) =>
92-
content.replace(
93-
/"baseUrl": ".\/",/,
94-
`
95-
"baseUrl": "./",
96-
"paths": {
97-
"my-lib": [
98-
"./dist/my-lib"
99-
]
100-
},
101-
`,
102-
),
103-
);
91+
await harness.modifyFile('tsconfig.json', (content) => {
92+
const tsconfig = JSON.parse(content);
93+
tsconfig.compilerOptions ??= {};
94+
tsconfig.compilerOptions.paths = {
95+
'my-lib': ['./dist/my-lib'],
96+
};
97+
98+
return JSON.stringify(tsconfig, null, 2);
99+
});
104100

105101
harness.useTarget('test', {
106102
...BASE_OPTIONS,

packages/ngtools/webpack/src/ivy/plugin.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ export class AngularWebpackPlugin {
410410
this.pluginOptions.tsconfig,
411411
this.pluginOptions.compilerOptions,
412412
);
413+
compilerOptions.baseUrl ??= compilerOptions['pathsBasePath'];
413414
compilerOptions.composite = false;
414415
compilerOptions.noEmitOnError = false;
415416
compilerOptions.suppressOutputPathCheck = true;

0 commit comments

Comments
 (0)