Skip to content

Commit 890ef83

Browse files
authored
fix(js): set the tsBuildInfoFile as output when it's not contained in the outDir (#28538)
1 parent fae8474 commit 890ef83

File tree

2 files changed

+310
-16
lines changed

2 files changed

+310
-16
lines changed

packages/js/src/plugins/typescript/plugin.spec.ts

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,137 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => {
15571557
}
15581558
`);
15591559
});
1560+
1561+
it('should set the "tsBuildInfoFile" option when outside of the "outDir"', async () => {
1562+
await applyFilesToTempFsAndContext(tempFs, context, {
1563+
'libs/my-lib/tsconfig.json': JSON.stringify({
1564+
compilerOptions: {
1565+
outDir: 'dist',
1566+
tsBuildInfoFile: 'my-lib.tsbuildinfo',
1567+
},
1568+
files: ['main.ts'],
1569+
}),
1570+
'libs/my-lib/package.json': `{}`,
1571+
});
1572+
1573+
expect(await invokeCreateNodesOnMatchingFiles(context, {}))
1574+
.toMatchInlineSnapshot(`
1575+
{
1576+
"projects": {
1577+
"libs/my-lib": {
1578+
"projectType": "library",
1579+
"targets": {
1580+
"typecheck": {
1581+
"cache": true,
1582+
"command": "tsc --build --emitDeclarationOnly --pretty --verbose",
1583+
"dependsOn": [
1584+
"^typecheck",
1585+
],
1586+
"inputs": [
1587+
"production",
1588+
"^production",
1589+
{
1590+
"externalDependencies": [
1591+
"typescript",
1592+
],
1593+
},
1594+
],
1595+
"metadata": {
1596+
"description": "Runs type-checking for the project.",
1597+
"help": {
1598+
"command": "npx tsc --build --help",
1599+
"example": {
1600+
"args": [
1601+
"--force",
1602+
],
1603+
},
1604+
},
1605+
"technologies": [
1606+
"typescript",
1607+
],
1608+
},
1609+
"options": {
1610+
"cwd": "libs/my-lib",
1611+
},
1612+
"outputs": [
1613+
"{projectRoot}/dist",
1614+
"{projectRoot}/my-lib.tsbuildinfo",
1615+
],
1616+
"syncGenerators": [
1617+
"@nx/js:typescript-sync",
1618+
],
1619+
},
1620+
},
1621+
},
1622+
},
1623+
}
1624+
`);
1625+
});
1626+
1627+
it('should not set the "tsBuildInfoFile" option when contained in the "outDir"', async () => {
1628+
await applyFilesToTempFsAndContext(tempFs, context, {
1629+
'libs/my-lib/tsconfig.json': JSON.stringify({
1630+
compilerOptions: {
1631+
outDir: 'dist',
1632+
tsBuildInfoFile: 'dist/my-lib.tsbuildinfo',
1633+
},
1634+
files: ['main.ts'],
1635+
}),
1636+
'libs/my-lib/package.json': `{}`,
1637+
});
1638+
1639+
expect(await invokeCreateNodesOnMatchingFiles(context, {}))
1640+
.toMatchInlineSnapshot(`
1641+
{
1642+
"projects": {
1643+
"libs/my-lib": {
1644+
"projectType": "library",
1645+
"targets": {
1646+
"typecheck": {
1647+
"cache": true,
1648+
"command": "tsc --build --emitDeclarationOnly --pretty --verbose",
1649+
"dependsOn": [
1650+
"^typecheck",
1651+
],
1652+
"inputs": [
1653+
"production",
1654+
"^production",
1655+
{
1656+
"externalDependencies": [
1657+
"typescript",
1658+
],
1659+
},
1660+
],
1661+
"metadata": {
1662+
"description": "Runs type-checking for the project.",
1663+
"help": {
1664+
"command": "npx tsc --build --help",
1665+
"example": {
1666+
"args": [
1667+
"--force",
1668+
],
1669+
},
1670+
},
1671+
"technologies": [
1672+
"typescript",
1673+
],
1674+
},
1675+
"options": {
1676+
"cwd": "libs/my-lib",
1677+
},
1678+
"outputs": [
1679+
"{projectRoot}/dist",
1680+
],
1681+
"syncGenerators": [
1682+
"@nx/js:typescript-sync",
1683+
],
1684+
},
1685+
},
1686+
},
1687+
},
1688+
}
1689+
`);
1690+
});
15601691
});
15611692
});
15621693

@@ -2937,6 +3068,147 @@ describe(`Plugin: ${PLUGIN_NAME}`, () => {
29373068
}
29383069
`);
29393070
});
3071+
3072+
it('should set the "tsBuildInfoFile" option when outside of the "outDir"', async () => {
3073+
await applyFilesToTempFsAndContext(tempFs, context, {
3074+
'libs/my-lib/tsconfig.lib.json': JSON.stringify({
3075+
compilerOptions: {
3076+
outDir: 'dist',
3077+
tsBuildInfoFile: 'my-lib.tsbuildinfo',
3078+
},
3079+
files: ['main.ts'],
3080+
}),
3081+
'libs/my-lib/tsconfig.json': `{}`,
3082+
'libs/my-lib/package.json': `{}`,
3083+
});
3084+
3085+
expect(
3086+
await invokeCreateNodesOnMatchingFiles(context, {
3087+
typecheck: false,
3088+
build: true,
3089+
})
3090+
).toMatchInlineSnapshot(`
3091+
{
3092+
"projects": {
3093+
"libs/my-lib": {
3094+
"projectType": "library",
3095+
"targets": {
3096+
"build": {
3097+
"cache": true,
3098+
"command": "tsc --build tsconfig.lib.json --pretty --verbose",
3099+
"dependsOn": [
3100+
"^build",
3101+
],
3102+
"inputs": [
3103+
"production",
3104+
"^production",
3105+
{
3106+
"externalDependencies": [
3107+
"typescript",
3108+
],
3109+
},
3110+
],
3111+
"metadata": {
3112+
"description": "Builds the project with \`tsc\`.",
3113+
"help": {
3114+
"command": "npx tsc --build --help",
3115+
"example": {
3116+
"args": [
3117+
"--force",
3118+
],
3119+
},
3120+
},
3121+
"technologies": [
3122+
"typescript",
3123+
],
3124+
},
3125+
"options": {
3126+
"cwd": "libs/my-lib",
3127+
},
3128+
"outputs": [
3129+
"{projectRoot}/dist",
3130+
"{projectRoot}/my-lib.tsbuildinfo",
3131+
],
3132+
"syncGenerators": [
3133+
"@nx/js:typescript-sync",
3134+
],
3135+
},
3136+
},
3137+
},
3138+
},
3139+
}
3140+
`);
3141+
});
3142+
3143+
it('should not set the "tsBuildInfoFile" option when contained in the "outDir"', async () => {
3144+
await applyFilesToTempFsAndContext(tempFs, context, {
3145+
'libs/my-lib/tsconfig.lib.json': JSON.stringify({
3146+
compilerOptions: {
3147+
outDir: 'dist',
3148+
tsBuildInfoFile: 'dist/my-lib.tsbuildinfo',
3149+
},
3150+
files: ['main.ts'],
3151+
}),
3152+
'libs/my-lib/tsconfig.json': `{}`,
3153+
'libs/my-lib/package.json': `{}`,
3154+
});
3155+
3156+
expect(
3157+
await invokeCreateNodesOnMatchingFiles(context, {
3158+
typecheck: false,
3159+
build: true,
3160+
})
3161+
).toMatchInlineSnapshot(`
3162+
{
3163+
"projects": {
3164+
"libs/my-lib": {
3165+
"projectType": "library",
3166+
"targets": {
3167+
"build": {
3168+
"cache": true,
3169+
"command": "tsc --build tsconfig.lib.json --pretty --verbose",
3170+
"dependsOn": [
3171+
"^build",
3172+
],
3173+
"inputs": [
3174+
"production",
3175+
"^production",
3176+
{
3177+
"externalDependencies": [
3178+
"typescript",
3179+
],
3180+
},
3181+
],
3182+
"metadata": {
3183+
"description": "Builds the project with \`tsc\`.",
3184+
"help": {
3185+
"command": "npx tsc --build --help",
3186+
"example": {
3187+
"args": [
3188+
"--force",
3189+
],
3190+
},
3191+
},
3192+
"technologies": [
3193+
"typescript",
3194+
],
3195+
},
3196+
"options": {
3197+
"cwd": "libs/my-lib",
3198+
},
3199+
"outputs": [
3200+
"{projectRoot}/dist",
3201+
],
3202+
"syncGenerators": [
3203+
"@nx/js:typescript-sync",
3204+
],
3205+
},
3206+
},
3207+
},
3208+
},
3209+
}
3210+
`);
3211+
});
29403212
});
29413213
});
29423214
});

packages/js/src/plugins/typescript/plugin.ts

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
import { getNamedInputs } from '@nx/devkit/src/utils/get-named-inputs';
2020
import { minimatch } from 'minimatch';
2121
import { existsSync, readdirSync, statSync } from 'node:fs';
22-
import { basename, dirname, join, normalize, relative } from 'node:path';
22+
import { basename, dirname, join, normalize, relative, sep } from 'node:path';
2323
import { hashArray, hashFile, hashObject } from 'nx/src/hasher/file-hasher';
2424
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
2525
import { getLockFileName } from 'nx/src/plugins/js/lock-file/lock-file';
@@ -456,21 +456,30 @@ function getOutputs(
456456
const outFileName = basename(config.options.outFile, '.js');
457457
const outFileDir = dirname(config.options.outFile);
458458
outputs.add(
459-
joinPathFragments(
460-
'{workspaceRoot}',
461-
relative(workspaceRoot, config.options.outFile)
462-
)
459+
pathToInputOrOutput(config.options.outFile, workspaceRoot, projectRoot)
463460
);
464461
// outFile is not be used with .cjs, .mjs, .jsx, so the list is simpler
465462
const outDir = relative(workspaceRoot, outFileDir);
466463
outputs.add(
467-
joinPathFragments('{workspaceRoot}', outDir, `${outFileName}.js.map`)
464+
pathToInputOrOutput(
465+
joinPathFragments(outDir, `${outFileName}.js.map`),
466+
workspaceRoot,
467+
projectRoot
468+
)
468469
);
469470
outputs.add(
470-
joinPathFragments('{workspaceRoot}', outDir, `${outFileName}.d.ts`)
471+
pathToInputOrOutput(
472+
joinPathFragments(outDir, `${outFileName}.d.ts`),
473+
workspaceRoot,
474+
projectRoot
475+
)
471476
);
472477
outputs.add(
473-
joinPathFragments('{workspaceRoot}', outDir, `${outFileName}.d.ts.map`)
478+
pathToInputOrOutput(
479+
joinPathFragments(outDir, `${outFileName}.d.ts.map`),
480+
workspaceRoot,
481+
projectRoot
482+
)
474483
);
475484
// https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
476485
outputs.add(
@@ -480,19 +489,32 @@ function getOutputs(
480489
workspaceRoot,
481490
projectRoot
482491
)
483-
: joinPathFragments(
484-
'{workspaceRoot}',
485-
outDir,
486-
`${outFileName}.tsbuildinfo`
492+
: pathToInputOrOutput(
493+
joinPathFragments(outDir, `${outFileName}.tsbuildinfo`),
494+
workspaceRoot,
495+
projectRoot
487496
)
488497
);
489498
} else if (config.options.outDir) {
490499
outputs.add(
491-
joinPathFragments(
492-
'{workspaceRoot}',
493-
relative(workspaceRoot, config.options.outDir)
494-
)
500+
pathToInputOrOutput(config.options.outDir, workspaceRoot, projectRoot)
495501
);
502+
503+
if (
504+
config.options.tsBuildInfoFile &&
505+
!normalize(config.options.tsBuildInfoFile).startsWith(
506+
`${normalize(config.options.outDir)}${sep}`
507+
)
508+
) {
509+
// https://www.typescriptlang.org/tsconfig#tsBuildInfoFile
510+
outputs.add(
511+
pathToInputOrOutput(
512+
config.options.tsBuildInfoFile,
513+
workspaceRoot,
514+
projectRoot
515+
)
516+
);
517+
}
496518
} else if (config.fileNames.length) {
497519
// tsc produce files in place when no outDir or outFile is set
498520
outputs.add(joinPathFragments('{projectRoot}', '**/*.js'));

0 commit comments

Comments
 (0)