Skip to content

Commit 402599e

Browse files
authored
fix(scripts-tasks): make generate-api work in deterministic way (#28215)
* fix(scripts-tasks): disable api-extractor custom path aliases usage which causes invalid api.md and .d.ts rollup generation * chore: add generate-api task definition to lage config * feat(react-conformance): migrate package to v9 setup in order to be able to run generate-api task without build
1 parent 676dc58 commit 402599e

16 files changed

+243
-61
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "BREAKING CHANGE: migrate package to v9 setup in order to be able to run generate-api task without build",
4+
"packageName": "@fluentui/react-conformance",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

lage.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module.exports = {
99
lint: ['build'],
1010
clean: [],
1111
test: ['build'],
12+
'generate-api': ['^generate-api'],
1213
'test-ssr': [],
1314
'type-check': ['build'],
1415
'code-style': [],

packages/react-conformance/.npmignore

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1+
.storybook/
2+
.vscode/
3+
bundle-size/
4+
config/
5+
coverage/
6+
docs/
7+
etc/
8+
node_modules/
9+
src/
10+
stories/
11+
dist/types/
12+
temp/
13+
__fixtures__
14+
__mocks__
15+
__tests__
16+
117
*.api.json
2-
*.config.js
318
*.log
4-
*.nuspec
19+
*.spec.*
20+
*.cy.*
521
*.test.*
622
*.yml
23+
24+
# config files
25+
*config.*
26+
*rc.*
727
.editorconfig
8-
.eslintrc*
9-
.eslintcache
10-
.gitattributes
11-
.gitignore
12-
.vscode
13-
coverage
14-
dist/storybook
15-
dist/*.stats.html
16-
dist/*.stats.json
17-
dist/demo
18-
fabric-test*
19-
gulpfile.js
20-
images
21-
index.html
22-
jsconfig.json
23-
node_modules
24-
results
25-
src/**/*
26-
!src/**/examples/*.tsx
27-
!src/**/docs/**/*.md
28-
!src/**/*.types.ts
29-
temp
30-
tsconfig.json
31-
tsd.json
32-
tslint.json
33-
typings
34-
visualtests
28+
.eslint*
29+
.git*
30+
.prettierignore
31+
.swcrc
32+
33+
# exclude gitignore patterns explicitly
34+
!lib
35+
!lib-commonjs
36+
!lib-amd
37+
!dist/*.d.ts

packages/react-conformance/.swcrc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"$schema": "https://json.schemastore.org/swcrc",
3+
"exclude": [
4+
"/testing",
5+
"/**/*.cy.ts",
6+
"/**/*.cy.tsx",
7+
"/**/*.spec.ts",
8+
"/**/*.spec.tsx",
9+
"/**/*.test.ts",
10+
"/**/*.test.tsx"
11+
],
12+
"jsc": {
13+
"parser": {
14+
"syntax": "typescript",
15+
"tsx": true,
16+
"decorators": false,
17+
"dynamicImport": false
18+
},
19+
"externalHelpers": true,
20+
"transform": {
21+
"react": {
22+
"runtime": "classic",
23+
"useSpread": true
24+
}
25+
},
26+
"target": "es2019"
27+
},
28+
"minify": false,
29+
"sourceMaps": true
30+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
3+
"extends": "@fluentui/scripts-api-extractor/api-extractor.common.v-next.json",
4+
"mainEntryPointFilePath": "<projectFolder>/../../dist/out-tsc/types/packages/<unscopedPackageName>/src/index.d.ts"
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/** Jest test setup file. */
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
## API Report File for "@fluentui/react-conformance"
2+
3+
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4+
5+
```ts
6+
7+
import { ComponentDoc } from 'react-docgen-typescript';
8+
import * as React_2 from 'react';
9+
import { render } from '@testing-library/react';
10+
import * as ts from 'typescript';
11+
12+
// @public (undocumented)
13+
export type ConformanceTest<TProps = {}> = (componentInfo: ComponentDoc, testInfo: IsConformantOptions<TProps>, tsProgram: ts.Program) => void;
14+
15+
// @public (undocumented)
16+
export function isConformant<TProps = {}>(...testInfo: Partial<IsConformantOptions<TProps>>[]): void;
17+
18+
// @public (undocumented)
19+
export interface IsConformantOptions<TProps = {}> {
20+
Component: React_2.ComponentType<TProps>;
21+
componentPath: string;
22+
disabledTests?: string[];
23+
displayName: string;
24+
elementRefName?: string;
25+
extraTests?: TestObject<TProps>;
26+
getTargetElement?: (renderResult: ReturnType<typeof render>, attr: keyof React_2.AllHTMLAttributes<HTMLElement> | 'ref' | `data-${string}`) => HTMLElement;
27+
isInternal?: boolean;
28+
primarySlot?: keyof TProps | 'root';
29+
renderOptions?: Parameters<typeof render>[1];
30+
requiredProps?: Partial<TProps>;
31+
testOptions?: TestOptions;
32+
tsConfig?: Partial<{
33+
configName: string;
34+
configDir: string;
35+
}>;
36+
// @deprecated (undocumented)
37+
tsconfigDir?: string;
38+
useDefaultExport?: boolean;
39+
}
40+
41+
// @public (undocumented)
42+
export interface TestObject<TProps = {}> {
43+
// (undocumented)
44+
[key: string]: ConformanceTest<TProps>;
45+
}
46+
47+
// @public
48+
export interface TestOptions {
49+
// (undocumented)
50+
'component-has-static-classname'?: {
51+
prefix?: string;
52+
};
53+
// (undocumented)
54+
'consistent-callback-args'?: {
55+
ignoreProps?: string[];
56+
};
57+
// (undocumented)
58+
'consistent-callback-names'?: {
59+
ignoreProps?: string[];
60+
};
61+
// (undocumented)
62+
'has-static-classnames'?: {
63+
props: {
64+
[key: string]: string | {};
65+
};
66+
expectedClassNames?: {
67+
[key: string]: string;
68+
};
69+
getPortalElement?: (renderResult: ReturnType<typeof render>) => HTMLElement;
70+
}[];
71+
}
72+
73+
// (No @packageDocumentation comment for this package)
74+
75+
```
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
1-
const { createV8Config: createConfig } = require('@fluentui/scripts-jest');
1+
// @ts-check
22

3-
const config = createConfig({});
4-
5-
module.exports = config;
3+
/**
4+
* @type {import('@jest/types').Config.InitialOptions}
5+
*/
6+
module.exports = {
7+
displayName: 'react-conformance',
8+
preset: '../../jest.preset.js',
9+
globals: {
10+
'ts-jest': {
11+
tsconfig: '<rootDir>/tsconfig.spec.json',
12+
isolatedModules: true,
13+
},
14+
},
15+
transform: {
16+
'^.+\\.tsx?$': 'ts-jest',
17+
},
18+
coverageDirectory: './coverage',
19+
setupFilesAfterEnv: ['./config/tests.js'],
20+
};

packages/react-conformance/just.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import { preset, task } from '@fluentui/scripts-tasks';
22

33
preset();
44

5-
task('build', 'build:node-lib').cached!();
5+
task('build', 'build:react-components').cached?.();

packages/react-conformance/package.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"version": "0.16.3",
44
"description": "Customizable conformance testing utility for Fluent UI React components.",
55
"main": "lib-commonjs/index.js",
6-
"typings": "lib-commonjs/index.d.ts",
6+
"typings": "dist/index.d.ts",
77
"repository": {
88
"type": "git",
99
"url": "https://github.com/microsoft/fluentui"
@@ -15,7 +15,9 @@
1515
"code-style": "just-scripts code-style",
1616
"just": "just-scripts",
1717
"test": "just-scripts test",
18-
"lint": "just-scripts lint"
18+
"lint": "just-scripts lint",
19+
"generate-api": "just-scripts generate-api",
20+
"type-check": "just-scripts type-check"
1921
},
2022
"devDependencies": {
2123
"@fluentui/eslint-plugin": "*",
@@ -37,5 +39,13 @@
3739
"react": ">=16.8.0 <19.0.0",
3840
"react-dom": ">=16.8.0 <19.0.0",
3941
"typescript": "^4.3.0"
42+
},
43+
"exports": {
44+
".": {
45+
"types": "./dist/index.d.ts",
46+
"node": "./lib-commonjs/index.js",
47+
"require": "./lib-commonjs/index.js"
48+
},
49+
"./package.json": "./package.json"
4050
}
4151
}
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
{
2+
"extends": "../../tsconfig.base.json",
23
"compilerOptions": {
3-
"baseUrl": ".",
4-
"outDir": "lib",
5-
"target": "es6",
6-
"module": "commonjs",
4+
"target": "ES2019",
5+
"noEmit": true,
76
"jsx": "react",
8-
"declaration": true,
9-
"sourceMap": true,
10-
"experimentalDecorators": true,
7+
"isolatedModules": true,
118
"importHelpers": true,
12-
"noUnusedLocals": true,
13-
"forceConsistentCasingInFileNames": true,
14-
"strict": true,
15-
"moduleResolution": "node",
169
"preserveConstEnums": true,
17-
"isolatedModules": true,
18-
"lib": ["es2017", "dom"],
19-
"types": ["jest", "node"]
10+
"noUnusedLocals": true
2011
},
21-
"include": ["src"]
12+
"include": [],
13+
"files": [],
14+
"references": [
15+
{
16+
"path": "./tsconfig.lib.json"
17+
},
18+
{
19+
"path": "./tsconfig.spec.json"
20+
}
21+
]
2222
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"noEmit": false,
5+
"lib": ["DOM", "ES2019"],
6+
"declaration": true,
7+
"declarationDir": "../../dist/out-tsc/types",
8+
"outDir": "../../dist/out-tsc",
9+
"inlineSources": true,
10+
"types": ["static-assets", "environment", "jest", "node"],
11+
"module": "CommonJS"
12+
},
13+
"exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"],
14+
"include": ["./src/**/*.ts", "./src/**/*.tsx"]
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"module": "CommonJS",
5+
"outDir": "dist",
6+
"types": ["jest", "node"]
7+
},
8+
"include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx", "**/*.d.ts"]
9+
}

scripts/tasks/src/utils.spec.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,13 @@ describe(`utils`, () => {
4343
definitionsRootPath: 'dist/for/types',
4444
});
4545

46-
expect(actual.overrideTsconfig.compilerOptions).toEqual(expect.objectContaining({ paths: undefined }));
46+
expect(actual.overrideTsconfig.compilerOptions).toEqual(
47+
expect.objectContaining({ paths: undefined, baseUrl: '.' }),
48+
);
4749
});
4850

49-
it(`should override path aliases to emitted declaration files instead of source files`, () => {
51+
// This is not used unless api-extractor resolves resolving workspace d.ts packages - see https://github.com/microsoft/rushstack/pull/3321, https://github.com/microsoft/rushstack/pull/3339
52+
it.skip(`should override path aliases to emitted declaration files instead of source files`, () => {
5053
const actual = setup({
5154
definitionsRootPath: 'dist/for/types',
5255
pathAliasesTsConfigPath: path.join(workspaceRoot, 'tsconfig.base.json'),

scripts/tasks/src/utils.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ function enableAllowSyntheticDefaultImports(options: { pkgJson: PackageJson }) {
108108
return shouldEnable ? { allowSyntheticDefaultImports: true } : null;
109109
}
110110

111+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
112+
// @ts-ignore - 💡 NOTE: this is not used unless api-extractor resolves resolving workspace d.ts packages - see https://github.com/microsoft/rushstack/pull/3321, https://github.com/microsoft/rushstack/pull/3339
111113
function createNormalizedTsPaths(options: { definitionsRootPath: string; pathAliasesTsConfigPath: string }) {
112114
type PathAliases = Record<string, string[]>;
113115
const { definitionsRootPath, pathAliasesTsConfigPath } = options;
@@ -132,14 +134,16 @@ export function getTsPathAliasesApiExtractorConfig(options: {
132134
definitionsRootPath: string;
133135
pathAliasesTsConfigPath?: string;
134136
}) {
135-
const { packageJson, tsConfig, pathAliasesTsConfigPath, definitionsRootPath } = options;
137+
const { packageJson, tsConfig /* , pathAliasesTsConfigPath, definitionsRootPath */ } = options;
136138
/**
137139
* Because api-extractor ran into race conditions when executing via lage (https://github.com/microsoft/fluentui/issues/25766),
138140
* 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
141+
*
142+
* 💡 NOTE: this is not used unless api-extractor resolves resolving workspace d.ts packages - see https://github.com/microsoft/rushstack/pull/3321, https://github.com/microsoft/rushstack/pull/3339
139143
*/
140-
const normalizedPaths = pathAliasesTsConfigPath
141-
? createNormalizedTsPaths({ definitionsRootPath, pathAliasesTsConfigPath })
142-
: undefined;
144+
// const normalizedPaths = pathAliasesTsConfigPath
145+
// ? createNormalizedTsPaths({ definitionsRootPath, pathAliasesTsConfigPath })
146+
// : undefined;
143147

144148
/**
145149
* Customized TSConfig that uses `tsconfig.lib.json` as base with some required overrides:
@@ -166,10 +170,13 @@ export function getTsPathAliasesApiExtractorConfig(options: {
166170
*/
167171
skipLibCheck: false,
168172
/**
169-
* just-scripts provides invalid types for tsconfig, thus `paths` cannot be set to dictionary,nor null or `{}`
173+
* api-extractor introduced a "feature" which is actually a bug and makes using path aliases impossible
174+
* - with this api extractor change user is forced to rely on yarn/npm "workspace" symlinks in order to determine that inner workspace package should not be bundled in type definition rollup/api.md
175+
* - see https://github.com/microsoft/rushstack/pull/3321, https://github.com/microsoft/rushstack/pull/3339
176+
*
170177
*/
171-
// @ts-expect-error - just-scripts provides invalid types
172-
paths: normalizedPaths,
178+
paths: undefined,
179+
baseUrl: '.',
173180
},
174181
};
175182

0 commit comments

Comments
 (0)