fix(js): handle ${configDir} in tsconfig files when inferring tasks (#31098)
## Current Behavior
The `${configDir}` template variable in tsconfig files is incorrectly
handled when inferring tasks with the `@nx/js/typescript` plugin.
## Expected Behavior
The `${configDir}` template variable in tsconfig files should be
correctly handled when inferring tasks with the `@nx/js/typescript`
plugin.
## Related Issue(s)
Fixes #30883
This commit is contained in:
parent
30a7709d71
commit
e6a3d77db3
@ -796,6 +796,73 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should add the config file and the `include` and `exclude` patterns using the "${configDir}" template', async () => {
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.json': JSON.stringify({
|
||||
include: ['${configDir}/src/**/*.ts'],
|
||||
exclude: ['${configDir}/src/**/foo.ts'],
|
||||
// set this to keep outputs smaller
|
||||
compilerOptions: { outDir: 'dist' },
|
||||
}),
|
||||
'libs/my-lib/package.json': `{}`,
|
||||
});
|
||||
expect(await invokeCreateNodesOnMatchingFiles(context, {}))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"projects": {
|
||||
"libs/my-lib": {
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"typecheck": {
|
||||
"cache": true,
|
||||
"command": "tsc --build --emitDeclarationOnly",
|
||||
"dependsOn": [
|
||||
"^typecheck",
|
||||
],
|
||||
"inputs": [
|
||||
"{projectRoot}/package.json",
|
||||
"{projectRoot}/tsconfig.json",
|
||||
"{projectRoot}/src/**/*.ts",
|
||||
"!{projectRoot}/src/**/foo.ts",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Runs type-checking for the project.",
|
||||
"help": {
|
||||
"command": "npx tsc --build --help",
|
||||
"example": {
|
||||
"args": [
|
||||
"--force",
|
||||
],
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "libs/my-lib",
|
||||
},
|
||||
"outputs": [
|
||||
"{projectRoot}/dist/**/*.d.ts",
|
||||
"{projectRoot}/dist/tsconfig.tsbuildinfo",
|
||||
],
|
||||
"syncGenerators": [
|
||||
"@nx/js:typescript-sync",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should normalize and add directories in `include` with the ts extensions', async () => {
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.json': JSON.stringify({
|
||||
@ -2608,6 +2675,68 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should support the "${configDir}" template', async () => {
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.json': JSON.stringify({
|
||||
compilerOptions: { outDir: '${configDir}/dist' },
|
||||
files: ['main.ts'],
|
||||
}),
|
||||
'libs/my-lib/package.json': `{}`,
|
||||
});
|
||||
expect(await invokeCreateNodesOnMatchingFiles(context, {}))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"projects": {
|
||||
"libs/my-lib": {
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"typecheck": {
|
||||
"cache": true,
|
||||
"command": "tsc --build --emitDeclarationOnly",
|
||||
"dependsOn": [
|
||||
"^typecheck",
|
||||
],
|
||||
"inputs": [
|
||||
"production",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Runs type-checking for the project.",
|
||||
"help": {
|
||||
"command": "npx tsc --build --help",
|
||||
"example": {
|
||||
"args": [
|
||||
"--force",
|
||||
],
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "libs/my-lib",
|
||||
},
|
||||
"outputs": [
|
||||
"{projectRoot}/dist/**/*.d.ts",
|
||||
"{projectRoot}/dist/tsconfig.tsbuildinfo",
|
||||
],
|
||||
"syncGenerators": [
|
||||
"@nx/js:typescript-sync",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -3351,6 +3480,78 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should add the config file and the `include` and `exclude` patterns using the "${configDir}" template', async () => {
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.lib.json': JSON.stringify({
|
||||
compilerOptions: {
|
||||
outDir: 'dist',
|
||||
},
|
||||
include: ['${configDir}/src/**/*.ts'],
|
||||
exclude: ['${configDir}/src/**/*.spec.ts'],
|
||||
}),
|
||||
'libs/my-lib/tsconfig.json': `{}`,
|
||||
'libs/my-lib/package.json': `{"main": "./dist/index.js"}`,
|
||||
});
|
||||
expect(
|
||||
await invokeCreateNodesOnMatchingFiles(context, {
|
||||
typecheck: false,
|
||||
build: true,
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"projects": {
|
||||
"libs/my-lib": {
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"cache": true,
|
||||
"command": "tsc --build tsconfig.lib.json",
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
],
|
||||
"inputs": [
|
||||
"{projectRoot}/package.json",
|
||||
"{projectRoot}/tsconfig.lib.json",
|
||||
"{projectRoot}/src/**/*.ts",
|
||||
"!{projectRoot}/src/**/*.spec.ts",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Builds the project with \`tsc\`.",
|
||||
"help": {
|
||||
"command": "npx tsc --build --help",
|
||||
"example": {
|
||||
"args": [
|
||||
"--force",
|
||||
],
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "libs/my-lib",
|
||||
},
|
||||
"outputs": [
|
||||
"{projectRoot}/dist",
|
||||
],
|
||||
"syncGenerators": [
|
||||
"@nx/js:typescript-sync",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should normalize and add directories in `include` with the ts extensions', async () => {
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.lib.json': JSON.stringify({
|
||||
@ -4948,6 +5149,74 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should support the "${configDir}" template', async () => {
|
||||
await applyFilesToTempFsAndContext(tempFs, context, {
|
||||
'libs/my-lib/tsconfig.lib.json': JSON.stringify({
|
||||
compilerOptions: {
|
||||
outDir: '${configDir}/dist',
|
||||
},
|
||||
files: ['main.ts'],
|
||||
}),
|
||||
'libs/my-lib/tsconfig.json': `{}`,
|
||||
'libs/my-lib/package.json': `{"main": "./dist/index.js"}`,
|
||||
});
|
||||
expect(
|
||||
await invokeCreateNodesOnMatchingFiles(context, {
|
||||
typecheck: false,
|
||||
build: true,
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"projects": {
|
||||
"libs/my-lib": {
|
||||
"projectType": "library",
|
||||
"targets": {
|
||||
"build": {
|
||||
"cache": true,
|
||||
"command": "tsc --build tsconfig.lib.json",
|
||||
"dependsOn": [
|
||||
"^build",
|
||||
],
|
||||
"inputs": [
|
||||
"production",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Builds the project with \`tsc\`.",
|
||||
"help": {
|
||||
"command": "npx tsc --build --help",
|
||||
"example": {
|
||||
"args": [
|
||||
"--force",
|
||||
],
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"typescript",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "libs/my-lib",
|
||||
},
|
||||
"outputs": [
|
||||
"{projectRoot}/dist",
|
||||
],
|
||||
"syncGenerators": [
|
||||
"@nx/js:typescript-sync",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -344,7 +344,7 @@ async function getConfigFileHash(
|
||||
...(packageJson ? [hashObject(packageJson)] : []),
|
||||
// change this to bust the cache when making changes that would yield
|
||||
// different results for the same hash
|
||||
hashObject({ bust: 2 }),
|
||||
hashObject({ bust: 3 }),
|
||||
]);
|
||||
}
|
||||
|
||||
@ -636,11 +636,18 @@ function getInputs(
|
||||
return [input];
|
||||
};
|
||||
|
||||
const configDirTemplate = '${configDir}';
|
||||
const substituteConfigDir = (p: string) =>
|
||||
p.startsWith(configDirTemplate) ? p.replace(configDirTemplate, './') : p;
|
||||
|
||||
projectTsConfigFiles.forEach(([configPath, config]) => {
|
||||
configFiles.add(configPath);
|
||||
const offset = relative(absoluteProjectRoot, dirname(configPath));
|
||||
(config.raw?.include ?? []).forEach((p: string) => {
|
||||
const normalized = normalizeInput(join(offset, p), config);
|
||||
const normalized = normalizeInput(
|
||||
join(offset, substituteConfigDir(p)),
|
||||
config
|
||||
);
|
||||
normalized.forEach((input) => includePaths.add(input));
|
||||
});
|
||||
|
||||
@ -653,11 +660,14 @@ function getInputs(
|
||||
const otherFilesInclude: string[] = [];
|
||||
projectTsConfigFiles.forEach(([path, c]) => {
|
||||
if (path !== configPath) {
|
||||
otherFilesInclude.push(...(c.raw?.include ?? []));
|
||||
otherFilesInclude.push(
|
||||
...(c.raw?.include ?? []).map(substituteConfigDir)
|
||||
);
|
||||
}
|
||||
});
|
||||
const normalize = (p: string) => (p.startsWith('./') ? p.slice(2) : p);
|
||||
config.raw.exclude.forEach((excludePath: string) => {
|
||||
config.raw.exclude.forEach((e: string) => {
|
||||
const excludePath = substituteConfigDir(e);
|
||||
if (
|
||||
!otherFilesInclude.some(
|
||||
(includePath) =>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user