Skip to content

Commit ebb827f

Browse files
authored
feat(webpack): support tsconfig.app.json when present (#10221)
1 parent 6059984 commit ebb827f

File tree

4 files changed

+154
-52
lines changed

4 files changed

+154
-52
lines changed

packages/webpack5/__tests__/configuration/base.spec.ts

Lines changed: 134 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,84 @@ describe('base configuration', () => {
2222
});
2323
}
2424

25+
it('supports tsconfig.app.json if exists', () => {
26+
const fsSpy = jest.spyOn(fs, 'existsSync');
27+
fsSpy.withImplementation(
28+
(path) => {
29+
return path.toString().endsWith('tsconfig.app.json');
30+
},
31+
() => {
32+
init({
33+
ios: true,
34+
});
35+
const config = base(new Config());
36+
37+
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.app.json');
38+
expect(fsSpy).not.toHaveBeenCalledWith('__jest__/tsconfig.json');
39+
40+
let configFiles = [];
41+
42+
config.module
43+
.rule('ts')
44+
.use('ts-loader')
45+
.tap((options) => {
46+
configFiles.push(options.configFile);
47+
return options;
48+
});
49+
50+
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
51+
configFiles.push(args.at(0).typescript.configFile);
52+
return args;
53+
});
54+
55+
expect(configFiles.length).toBe(2);
56+
expect(configFiles).toEqual([
57+
'__jest__/tsconfig.app.json', // ts-loader
58+
'__jest__/tsconfig.app.json', // fork-ts-checker
59+
]);
60+
}
61+
);
62+
});
63+
64+
it('falls back to tsconfig.json if no tsconfig.app.json exists', () => {
65+
const fsSpy = jest.spyOn(fs, 'existsSync');
66+
fsSpy.withImplementation(
67+
(path) => {
68+
return path.toString().endsWith('tsconfig.json');
69+
},
70+
() => {
71+
init({
72+
ios: true,
73+
});
74+
const config = base(new Config());
75+
76+
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.app.json');
77+
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.json');
78+
79+
let configFiles = [];
80+
81+
config.module
82+
.rule('ts')
83+
.use('ts-loader')
84+
.tap((options) => {
85+
configFiles.push(options.configFile);
86+
return options;
87+
});
88+
89+
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
90+
configFiles.push(args.at(0).typescript.configFile);
91+
return args;
92+
});
93+
94+
expect(configFiles.length).toBe(2);
95+
expect(configFiles).toEqual([
96+
'__jest__/tsconfig.json', // ts-loader
97+
'__jest__/tsconfig.json', // fork-ts-checker
98+
]);
99+
}
100+
);
101+
});
102+
25103
it('support env.watchNodeModules', () => {
26104
init({
27105
ios: true,
@@ -32,60 +110,73 @@ describe('base configuration', () => {
32110

33111
it('supports dotenv', () => {
34112
const fsSpy = jest.spyOn(fs, 'existsSync');
35-
fsSpy.mockReturnValue(true);
36-
37-
init({
38-
ios: true,
39-
});
40-
const config = base(new Config());
41-
42-
expect(config.plugin('DotEnvPlugin')).toBeDefined();
43-
config.plugin('DotEnvPlugin').tap((args) => {
44-
expect(args[0].path).toEqual('__jest__/.env');
45-
return args;
46-
});
113+
fsSpy.withImplementation(
114+
(path) => {
115+
return path.toString().endsWith('__jest__/.env');
116+
},
117+
() => {
118+
init({
119+
ios: true,
120+
});
121+
const config = base(new Config());
122+
123+
expect(config.plugin('DotEnvPlugin')).toBeDefined();
124+
config.plugin('DotEnvPlugin').tap((args) => {
125+
expect(args[0].path).toEqual('__jest__/.env');
126+
return args;
127+
});
128+
}
129+
);
47130

48131
fsSpy.mockRestore();
49132
});
50133

51134
it('supports env specific dotenv', () => {
52135
const fsSpy = jest.spyOn(fs, 'existsSync');
53-
fsSpy.mockReturnValue(true);
54-
55-
init({
56-
ios: true,
57-
env: 'prod',
58-
});
59-
const config = base(new Config());
60-
61-
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
62-
expect(fsSpy).toHaveBeenCalledTimes(1);
63-
expect(config.plugin('DotEnvPlugin')).toBeDefined();
64-
config.plugin('DotEnvPlugin').tap((args) => {
65-
expect(args[0].path).toEqual('__jest__/.env.prod');
66-
return args;
67-
});
136+
fsSpy.withImplementation(
137+
(path) => {
138+
return path.toString().endsWith('__jest__/.env.prod');
139+
},
140+
() => {
141+
init({
142+
ios: true,
143+
env: 'prod',
144+
});
145+
const config = base(new Config());
146+
147+
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
148+
expect(config.plugin('DotEnvPlugin')).toBeDefined();
149+
config.plugin('DotEnvPlugin').tap((args) => {
150+
expect(args[0].path).toEqual('__jest__/.env.prod');
151+
return args;
152+
});
153+
}
154+
);
68155
fsSpy.mockRestore();
69156
});
70157

71158
it('falls back to default .env', () => {
72159
const fsSpy = jest.spyOn(fs, 'existsSync');
73-
fsSpy.mockReturnValueOnce(false).mockReturnValueOnce(true);
74-
75-
init({
76-
ios: true,
77-
env: 'prod',
78-
});
79-
const config = base(new Config());
80-
81-
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
82-
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env');
83-
expect(fsSpy).toHaveBeenCalledTimes(2);
84-
expect(config.plugin('DotEnvPlugin')).toBeDefined();
85-
config.plugin('DotEnvPlugin').tap((args) => {
86-
expect(args[0].path).toEqual('__jest__/.env');
87-
return args;
88-
});
160+
fsSpy.withImplementation(
161+
(path) => {
162+
return path.toString().endsWith('__jest__/.env');
163+
},
164+
() => {
165+
init({
166+
ios: true,
167+
env: 'prod',
168+
});
169+
const config = base(new Config());
170+
171+
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
172+
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env');
173+
expect(config.plugin('DotEnvPlugin')).toBeDefined();
174+
config.plugin('DotEnvPlugin').tap((args) => {
175+
expect(args[0].path).toEqual('__jest__/.env');
176+
return args;
177+
});
178+
}
179+
);
89180
fsSpy.mockRestore();
90181
});
91182

packages/webpack5/src/configuration/angular.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { existsSync } from 'fs';
44

55
import { getTypescript, readTsConfig } from '../helpers/typescript';
66
import { getDependencyPath } from '../helpers/dependencies';
7-
import { getProjectFilePath } from '../helpers/project';
7+
import { getProjectTSConfigPath } from '../helpers/project';
88
import { env as _env, IWebpackEnv } from '../index';
99
import { warnOnce } from '../helpers/log';
1010
import {
@@ -18,12 +18,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
1818
base(config, env);
1919

2020
const platform = getPlatformName();
21-
22-
const tsConfigPath = [
23-
getProjectFilePath('tsconfig.app.json'),
24-
getProjectFilePath('tsconfig.json'),
25-
].find((path) => existsSync(path));
26-
21+
const tsConfigPath = getProjectTSConfigPath();
2722
const disableAOT = !!env.disableAOT;
2823

2924
// remove default ts rule

packages/webpack5/src/configuration/base.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
1515
import { applyFileReplacements } from '../helpers/fileReplacements';
1616
import { addCopyRule, applyCopyRules } from '../helpers/copyRules';
1717
import { WatchStatePlugin } from '../plugins/WatchStatePlugin';
18-
import { getProjectFilePath } from '../helpers/project';
18+
import { getProjectFilePath, getProjectTSConfigPath } from '../helpers/project';
1919
import { hasDependency } from '../helpers/dependencies';
2020
import { applyDotEnvPlugin } from '../helpers/dotEnv';
2121
import { env as _env, IWebpackEnv } from '../index';
@@ -234,6 +234,13 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
234234
.use('nativescript-worker-loader')
235235
.loader('nativescript-worker-loader');
236236

237+
const tsConfigPath = getProjectTSConfigPath();
238+
const configFile = tsConfigPath
239+
? {
240+
configFile: tsConfigPath,
241+
}
242+
: undefined;
243+
237244
// set up ts support
238245
config.module
239246
.rule('ts')
@@ -243,7 +250,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
243250
.options({
244251
// todo: perhaps we can provide a default tsconfig
245252
// and use that if the project doesn't have one?
246-
// configFile: '',
253+
...configFile,
247254
transpileOnly: true,
248255
allowTsInNodeModules: true,
249256
compilerOptions: {
@@ -266,6 +273,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
266273
async: !!env.watch,
267274
typescript: {
268275
memoryLimit: 4096,
276+
...configFile,
269277
},
270278
},
271279
]);

packages/webpack5/src/helpers/project.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { existsSync } from 'fs';
12
import { resolve } from 'path';
23

34
export function getProjectRootPath(): string {
@@ -30,6 +31,13 @@ export function getProjectFilePath(filePath: string): string {
3031
return resolve(getProjectRootPath(), filePath);
3132
}
3233

34+
export function getProjectTSConfigPath(): string | undefined {
35+
return [
36+
getProjectFilePath('tsconfig.app.json'),
37+
getProjectFilePath('tsconfig.json'),
38+
].find((path) => existsSync(path));
39+
}
40+
3341
// unused helper, but keeping it here as we may need it
3442
// todo: remove if unused for next few releases
3543
// function findFile(fileName, currentDir): string | null {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy