Skip to content

Commit a52ae93

Browse files
committed
feat(scripts-tasks): use path aliases for api-extractor only on local env
1 parent 08ccb46 commit a52ae93

3 files changed

Lines changed: 51 additions & 17 deletions

File tree

scripts/tasks/src/api-extractor.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as path from 'path';
22

33
import type { ExtractorMessageCategory, ExtractorResult } from '@microsoft/api-extractor';
4+
import { workspaceRoot } from '@nrwl/devkit';
45
import chalk from 'chalk';
56
import * as glob from 'glob';
67
import { ApiExtractorOptions, TaskFunction, apiExtractorVerifyTask, logger, series, task } from 'just-scripts';
@@ -56,12 +57,18 @@ export function apiExtractor(): TaskFunction {
5657
let configDebug: Parameters<NonNullable<ApiExtractorOptions['onConfigLoaded']>>[0] | null = null;
5758

5859
const args: ReturnType<typeof getJustArgv> & Partial<ApiExtractorCliRunCommandArgs> = getJustArgv();
59-
const { isUsingTsSolutionConfigs, packageJson, tsConfig, tsConfigPath } = getTsPathAliasesConfig();
60+
const { isUsingTsSolutionConfigs, packageJson, tsConfig } = getTsPathAliasesConfig();
6061

6162
if (configsToExecute.length === 0) {
6263
return noop;
6364
}
6465

66+
/**
67+
* overrides api-extractor default `true` to be `false` on local dev machine
68+
* Triggers if path aliases will be used or yarn workspaces (that needs to be build based on package dependency tree)
69+
*/
70+
const isLocalBuild = args.local ?? !process.env.TF_BUILD;
71+
6572
const tasks = configsToExecute.map(([configPath, configName]) => {
6673
const taskName = `api-extractor:${configName}`;
6774

@@ -73,7 +80,7 @@ export function apiExtractor(): TaskFunction {
7380
showDiagnostics: args.diagnostics,
7481
typescriptCompilerFolder: args['typescript-compiler-folder'],
7582
configJsonFilePath: args.config ?? configPath,
76-
localBuild: args.local ?? !process.env.TF_BUILD,
83+
localBuild: isLocalBuild,
7784
onConfigLoaded,
7885
messageCallback,
7986
onResult,
@@ -103,8 +110,8 @@ export function apiExtractor(): TaskFunction {
103110

104111
const compilerConfig = getTsPathAliasesApiExtractorConfig({
105112
tsConfig,
106-
tsConfigPath,
107113
packageJson,
114+
pathAliasesTsConfigPath: isLocalBuild ? path.join(workspaceRoot, 'tsconfig.base.json') : undefined,
108115
definitionsRootPath: 'dist/out-tsc/types',
109116
});
110117

scripts/tasks/src/utils.spec.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import * as path from 'path';
2+
3+
import { workspaceRoot } from '@nrwl/devkit';
4+
15
import { getTsPathAliasesApiExtractorConfig } from './utils';
26

37
type DeepPartial<T> = Partial<{ [P in keyof T]: DeepPartial<T[P]> }>;
@@ -12,7 +16,6 @@ describe(`utils`, () => {
1216
...options.tsConfig?.compilerOptions,
1317
},
1418
},
15-
tsConfigPath: 'tsconfig.lib.json',
1619
packageJson: {
1720
name: '@proj/one',
1821
version: '0.0.1',
@@ -21,6 +24,7 @@ describe(`utils`, () => {
2124
peerDependencies: { ...options.packageJson?.peerDependencies },
2225
},
2326
definitionsRootPath: options.definitionsRootPath ?? 'dist/types',
27+
pathAliasesTsConfigPath: options.pathAliasesTsConfigPath ?? undefined,
2428
};
2529

2630
return getTsPathAliasesApiExtractorConfig(defaults as Options);
@@ -34,8 +38,19 @@ describe(`utils`, () => {
3438
);
3539
});
3640

41+
it(`should not use path aliases to emitted declaration files`, () => {
42+
const actual = setup({
43+
definitionsRootPath: 'dist/for/types',
44+
});
45+
46+
expect(actual.overrideTsconfig.compilerOptions).toEqual(expect.objectContaining({ paths: undefined }));
47+
});
48+
3749
it(`should override path aliases to emitted declaration files instead of source files`, () => {
38-
const actual = setup({ definitionsRootPath: 'dist/for/types' });
50+
const actual = setup({
51+
definitionsRootPath: 'dist/for/types',
52+
pathAliasesTsConfigPath: path.join(workspaceRoot, 'tsconfig.base.json'),
53+
});
3954

4055
const newPaths = (actual.overrideTsconfig.compilerOptions.paths as unknown) as Record<string, string[]>;
4156

scripts/tasks/src/utils.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as fs from 'fs';
22
import * as path from 'path';
33

4-
import { stripJsonComments, workspaceRoot } from '@nrwl/devkit';
4+
import { stripJsonComments } from '@nrwl/devkit';
55
import * as jju from 'jju';
66
import type { TscTaskOptions } from 'just-scripts';
77

@@ -50,41 +50,53 @@ function enableAllowSyntheticDefaultImports(options: { pkgJson: PackageJson }) {
5050
return shouldEnable ? { allowSyntheticDefaultImports: true } : null;
5151
}
5252

53-
const rootTsConfig = JSON.parse(fs.readFileSync(path.join(workspaceRoot, 'tsconfig.base.json'), 'utf-8')) as TsConfig;
53+
function createNormalizedTsPaths(options: { definitionsRootPath: string; pathAliasesTsConfigPath: string }) {
54+
type PathAliases = Record<string, string[]>;
55+
const { definitionsRootPath, pathAliasesTsConfigPath } = options;
56+
const tsConfigRoot = JSON.parse(fs.readFileSync(pathAliasesTsConfigPath, 'utf-8')) as TsConfig;
57+
const paths = (tsConfigRoot.compilerOptions.paths as unknown) as undefined | PathAliases;
5458

55-
function createNormalizedTsPaths(options: { definitionsRootPath: string; rootTsConfig: TsConfig }) {
56-
const paths = (options.rootTsConfig.compilerOptions.paths as unknown) as Record<string, string[]>;
59+
if (!paths) {
60+
throw new Error(`Provided "${pathAliasesTsConfigPath}" has no compilerOptions.path defined`);
61+
}
5762

5863
const normalizedPaths = Object.entries(paths).reduce((acc, [pkgName, pathAliases]) => {
59-
acc[pkgName] = [path.join(options.definitionsRootPath, pathAliases[0].replace('index.ts', 'index.d.ts'))];
64+
acc[pkgName] = [path.join(definitionsRootPath, pathAliases[0].replace('index.ts', 'index.d.ts'))];
6065
return acc;
61-
}, {} as typeof paths);
66+
}, {} as PathAliases);
6267

6368
return normalizedPaths;
6469
}
6570

6671
export function getTsPathAliasesApiExtractorConfig(options: {
6772
tsConfig: TsConfig;
68-
tsConfigPath: string;
6973
packageJson: PackageJson;
7074
definitionsRootPath: string;
75+
pathAliasesTsConfigPath?: string;
7176
}) {
72-
const normalizedPaths = createNormalizedTsPaths({ definitionsRootPath: options.definitionsRootPath, rootTsConfig });
77+
const { packageJson, tsConfig, pathAliasesTsConfigPath, definitionsRootPath } = options;
78+
/**
79+
* Because api-extractor ran into race conditions when executing via lage (https://github.com/microsoft/fluentui/issues/25766),
80+
* we won't use path aliases on CI, rather serving api-extractor rolluped dts files cross package, that will be referenced via yarn workspace sym-links
81+
*/
82+
const normalizedPaths = pathAliasesTsConfigPath
83+
? createNormalizedTsPaths({ definitionsRootPath, pathAliasesTsConfigPath })
84+
: undefined;
7385

7486
/**
7587
* Customized TSConfig that uses `tsconfig.lib.json` as base with some required overrides:
7688
*
7789
* NOTES:
7890
* - `extends` is properly resolved via api-extractor which uses TS api
7991
* - `skipLibCheck` needs to be explicitly set to `false` so errors propagate to api-extractor
80-
* - `paths` is overriden to path mapping that points to generated declaration files. This also enables creation of dts rollup without a need of generating rollups for all dependencies 🫡
92+
* - `paths` if usePathAliases is enabled, we override it to path mapping that points to generated declaration files. This also enables creation of dts rollup without a need of generating rollups for all dependencies 🫡
8193
*
8294
*/
8395
const apiExtractorTsConfig: TsConfig = {
84-
...options.tsConfig,
96+
...tsConfig,
8597
compilerOptions: {
86-
...options.tsConfig.compilerOptions,
87-
...enableAllowSyntheticDefaultImports({ pkgJson: options.packageJson }),
98+
...tsConfig.compilerOptions,
99+
...enableAllowSyntheticDefaultImports({ pkgJson: packageJson }),
88100
/**
89101
* This option has no effect on type declarations '.d.ts' thus can be turned off. For more info see https://www.typescriptlang.org/tsconfig#non-module-files
90102
*

0 commit comments

Comments
 (0)