feat(webpack): support tsconfig.app.json when present (#10221)

This commit is contained in:
Igor Randjelovic
2023-03-28 16:17:51 +02:00
committed by GitHub
parent 6059984555
commit ebb827fb8e
4 changed files with 151 additions and 49 deletions

View File

@ -22,6 +22,84 @@ describe('base configuration', () => {
});
}
it('supports tsconfig.app.json if exists', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('tsconfig.app.json');
},
() => {
init({
ios: true,
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.app.json');
expect(fsSpy).not.toHaveBeenCalledWith('__jest__/tsconfig.json');
let configFiles = [];
config.module
.rule('ts')
.use('ts-loader')
.tap((options) => {
configFiles.push(options.configFile);
return options;
});
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
configFiles.push(args.at(0).typescript.configFile);
return args;
});
expect(configFiles.length).toBe(2);
expect(configFiles).toEqual([
'__jest__/tsconfig.app.json', // ts-loader
'__jest__/tsconfig.app.json', // fork-ts-checker
]);
}
);
});
it('falls back to tsconfig.json if no tsconfig.app.json exists', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('tsconfig.json');
},
() => {
init({
ios: true,
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.app.json');
expect(fsSpy).toHaveBeenCalledWith('__jest__/tsconfig.json');
let configFiles = [];
config.module
.rule('ts')
.use('ts-loader')
.tap((options) => {
configFiles.push(options.configFile);
return options;
});
config.plugin('ForkTsCheckerWebpackPlugin').tap((args) => {
configFiles.push(args.at(0).typescript.configFile);
return args;
});
expect(configFiles.length).toBe(2);
expect(configFiles).toEqual([
'__jest__/tsconfig.json', // ts-loader
'__jest__/tsconfig.json', // fork-ts-checker
]);
}
);
});
it('support env.watchNodeModules', () => {
init({
ios: true,
@ -32,60 +110,73 @@ describe('base configuration', () => {
it('supports dotenv', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.mockReturnValue(true);
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('__jest__/.env');
},
() => {
init({
ios: true,
});
const config = base(new Config());
init({
ios: true,
});
const config = base(new Config());
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
}
);
fsSpy.mockRestore();
});
it('supports env specific dotenv', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.mockReturnValue(true);
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('__jest__/.env.prod');
},
() => {
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(fsSpy).toHaveBeenCalledTimes(1);
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env.prod');
return args;
});
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env.prod');
return args;
});
}
);
fsSpy.mockRestore();
});
it('falls back to default .env', () => {
const fsSpy = jest.spyOn(fs, 'existsSync');
fsSpy.mockReturnValueOnce(false).mockReturnValueOnce(true);
fsSpy.withImplementation(
(path) => {
return path.toString().endsWith('__jest__/.env');
},
() => {
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
init({
ios: true,
env: 'prod',
});
const config = base(new Config());
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env');
expect(fsSpy).toHaveBeenCalledTimes(2);
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env.prod');
expect(fsSpy).toHaveBeenCalledWith('__jest__/.env');
expect(config.plugin('DotEnvPlugin')).toBeDefined();
config.plugin('DotEnvPlugin').tap((args) => {
expect(args[0].path).toEqual('__jest__/.env');
return args;
});
}
);
fsSpy.mockRestore();
});

View File

@ -4,7 +4,7 @@ import { existsSync } from 'fs';
import { getTypescript, readTsConfig } from '../helpers/typescript';
import { getDependencyPath } from '../helpers/dependencies';
import { getProjectFilePath } from '../helpers/project';
import { getProjectTSConfigPath } from '../helpers/project';
import { env as _env, IWebpackEnv } from '../index';
import { warnOnce } from '../helpers/log';
import {
@ -18,12 +18,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
base(config, env);
const platform = getPlatformName();
const tsConfigPath = [
getProjectFilePath('tsconfig.app.json'),
getProjectFilePath('tsconfig.json'),
].find((path) => existsSync(path));
const tsConfigPath = getProjectTSConfigPath();
const disableAOT = !!env.disableAOT;
// remove default ts rule

View File

@ -15,7 +15,7 @@ import { PlatformSuffixPlugin } from '../plugins/PlatformSuffixPlugin';
import { applyFileReplacements } from '../helpers/fileReplacements';
import { addCopyRule, applyCopyRules } from '../helpers/copyRules';
import { WatchStatePlugin } from '../plugins/WatchStatePlugin';
import { getProjectFilePath } from '../helpers/project';
import { getProjectFilePath, getProjectTSConfigPath } from '../helpers/project';
import { hasDependency } from '../helpers/dependencies';
import { applyDotEnvPlugin } from '../helpers/dotEnv';
import { env as _env, IWebpackEnv } from '../index';
@ -234,6 +234,13 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
.use('nativescript-worker-loader')
.loader('nativescript-worker-loader');
const tsConfigPath = getProjectTSConfigPath();
const configFile = tsConfigPath
? {
configFile: tsConfigPath,
}
: undefined;
// set up ts support
config.module
.rule('ts')
@ -243,7 +250,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
.options({
// todo: perhaps we can provide a default tsconfig
// and use that if the project doesn't have one?
// configFile: '',
...configFile,
transpileOnly: true,
allowTsInNodeModules: true,
compilerOptions: {
@ -266,6 +273,7 @@ export default function (config: Config, env: IWebpackEnv = _env): Config {
async: !!env.watch,
typescript: {
memoryLimit: 4096,
...configFile,
},
},
]);

View File

@ -1,3 +1,4 @@
import { existsSync } from 'fs';
import { resolve } from 'path';
export function getProjectRootPath(): string {
@ -30,6 +31,13 @@ export function getProjectFilePath(filePath: string): string {
return resolve(getProjectRootPath(), filePath);
}
export function getProjectTSConfigPath(): string | undefined {
return [
getProjectFilePath('tsconfig.app.json'),
getProjectFilePath('tsconfig.json'),
].find((path) => existsSync(path));
}
// unused helper, but keeping it here as we may need it
// todo: remove if unused for next few releases
// function findFile(fileName, currentDir): string | null {