Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(scripts-tasks): make generate-api work in deterministic way #28215

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "BREAKING CHANGE: migrate package to v9 setup in order to be able to run generate-api task without build",
"packageName": "@fluentui/react-conformance",
"email": "martinhochel@microsoft.com",
"dependentChangeType": "patch"
}
1 change: 1 addition & 0 deletions lage.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module.exports = {
lint: ['build'],
clean: [],
test: ['build'],
'generate-api': ['^generate-api'],
'test-ssr': [],
'type-check': ['build'],
'code-style': [],
Expand Down
61 changes: 32 additions & 29 deletions packages/react-conformance/.npmignore
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
.storybook/
.vscode/
bundle-size/
config/
coverage/
docs/
etc/
node_modules/
src/
stories/
dist/types/
temp/
__fixtures__
__mocks__
__tests__

*.api.json
*.config.js
*.log
*.nuspec
*.spec.*
*.cy.*
*.test.*
*.yml

# config files
*config.*
*rc.*
.editorconfig
.eslintrc*
.eslintcache
.gitattributes
.gitignore
.vscode
coverage
dist/storybook
dist/*.stats.html
dist/*.stats.json
dist/demo
fabric-test*
gulpfile.js
images
index.html
jsconfig.json
node_modules
results
src/**/*
!src/**/examples/*.tsx
!src/**/docs/**/*.md
!src/**/*.types.ts
temp
tsconfig.json
tsd.json
tslint.json
typings
visualtests
.eslint*
.git*
.prettierignore
.swcrc

# exclude gitignore patterns explicitly
!lib
!lib-commonjs
!lib-amd
!dist/*.d.ts
30 changes: 30 additions & 0 deletions packages/react-conformance/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"$schema": "https://json.schemastore.org/swcrc",
"exclude": [
"/testing",
"/**/*.cy.ts",
"/**/*.cy.tsx",
"/**/*.spec.ts",
"/**/*.spec.tsx",
"/**/*.test.ts",
"/**/*.test.tsx"
],
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": true,
"decorators": false,
"dynamicImport": false
},
"externalHelpers": true,
"transform": {
"react": {
"runtime": "classic",
"useSpread": true
}
},
"target": "es2019"
},
"minify": false,
"sourceMaps": true
}
5 changes: 5 additions & 0 deletions packages/react-conformance/config/api-extractor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "@fluentui/scripts-api-extractor/api-extractor.common.v-next.json",
"mainEntryPointFilePath": "<projectFolder>/../../dist/out-tsc/types/packages/<unscopedPackageName>/src/index.d.ts"
}
1 change: 1 addition & 0 deletions packages/react-conformance/config/tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/** Jest test setup file. */
75 changes: 75 additions & 0 deletions packages/react-conformance/etc/react-conformance.api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
## API Report File for "@fluentui/react-conformance"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).

```ts

import { ComponentDoc } from 'react-docgen-typescript';
import * as React_2 from 'react';
import { render } from '@testing-library/react';
import * as ts from 'typescript';

// @public (undocumented)
export type ConformanceTest<TProps = {}> = (componentInfo: ComponentDoc, testInfo: IsConformantOptions<TProps>, tsProgram: ts.Program) => void;

// @public (undocumented)
export function isConformant<TProps = {}>(...testInfo: Partial<IsConformantOptions<TProps>>[]): void;

// @public (undocumented)
export interface IsConformantOptions<TProps = {}> {
Component: React_2.ComponentType<TProps>;
componentPath: string;
disabledTests?: string[];
displayName: string;
elementRefName?: string;
extraTests?: TestObject<TProps>;
getTargetElement?: (renderResult: ReturnType<typeof render>, attr: keyof React_2.AllHTMLAttributes<HTMLElement> | 'ref' | `data-${string}`) => HTMLElement;
isInternal?: boolean;
primarySlot?: keyof TProps | 'root';
renderOptions?: Parameters<typeof render>[1];
requiredProps?: Partial<TProps>;
testOptions?: TestOptions;
tsConfig?: Partial<{
configName: string;
configDir: string;
}>;
// @deprecated (undocumented)
tsconfigDir?: string;
useDefaultExport?: boolean;
}

// @public (undocumented)
export interface TestObject<TProps = {}> {
// (undocumented)
[key: string]: ConformanceTest<TProps>;
}

// @public
export interface TestOptions {
// (undocumented)
'component-has-static-classname'?: {
prefix?: string;
};
// (undocumented)
'consistent-callback-args'?: {
ignoreProps?: string[];
};
// (undocumented)
'consistent-callback-names'?: {
ignoreProps?: string[];
};
// (undocumented)
'has-static-classnames'?: {
props: {
[key: string]: string | {};
};
expectedClassNames?: {
[key: string]: string;
};
getPortalElement?: (renderResult: ReturnType<typeof render>) => HTMLElement;
}[];
}

// (No @packageDocumentation comment for this package)

```
27 changes: 24 additions & 3 deletions packages/react-conformance/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
const { createV8Config: createConfig } = require('@fluentui/scripts-jest');
// const { createV8Config: createConfig } = require('@fluentui/scripts-jest');

const config = createConfig({});
// const config = createConfig({});

module.exports = config;
// module.exports = config;

// @ts-check

/**
* @type {import('@jest/types').Config.InitialOptions}
*/
module.exports = {
displayName: 'react-conformance',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsconfig: '<rootDir>/tsconfig.spec.json',
isolatedModules: true,
},
},
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
coverageDirectory: './coverage',
setupFilesAfterEnv: ['./config/tests.js'],
};
2 changes: 1 addition & 1 deletion packages/react-conformance/just.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import { preset, task } from '@fluentui/scripts-tasks';

preset();

task('build', 'build:node-lib').cached!();
task('build', 'build:react-components').cached?.();
14 changes: 12 additions & 2 deletions packages/react-conformance/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.16.3",
"description": "Customizable conformance testing utility for Fluent UI React components.",
"main": "lib-commonjs/index.js",
"typings": "lib-commonjs/index.d.ts",
"typings": "dist/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/microsoft/fluentui"
Expand All @@ -15,7 +15,9 @@
"code-style": "just-scripts code-style",
"just": "just-scripts",
"test": "just-scripts test",
"lint": "just-scripts lint"
"lint": "just-scripts lint",
"generate-api": "just-scripts generate-api",
"type-check": "just-scripts type-check"
},
"devDependencies": {
"@fluentui/eslint-plugin": "*",
Expand All @@ -37,5 +39,13 @@
"react": ">=16.8.0 <19.0.0",
"react-dom": ">=16.8.0 <19.0.0",
"typescript": "^4.3.0"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"node": "./lib-commonjs/index.js",
"require": "./lib-commonjs/index.js"
},
"./package.json": "./package.json"
}
}
30 changes: 15 additions & 15 deletions packages/react-conformance/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "lib",
"target": "es6",
"module": "commonjs",
"target": "ES2019",
"noEmit": true,
"jsx": "react",
"declaration": true,
"sourceMap": true,
"experimentalDecorators": true,
"isolatedModules": true,
"importHelpers": true,
"noUnusedLocals": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"moduleResolution": "node",
"preserveConstEnums": true,
"isolatedModules": true,
"lib": ["es2017", "dom"],
"types": ["jest", "node"]
"noUnusedLocals": true
},
"include": ["src"]
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.lib.json"
},
{
"path": "./tsconfig.spec.json"
}
]
}
15 changes: 15 additions & 0 deletions packages/react-conformance/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"noEmit": false,
"lib": ["DOM", "ES2019"],
"declaration": true,
"declarationDir": "../../dist/out-tsc/types",
"outDir": "../../dist/out-tsc",
"inlineSources": true,
"types": ["static-assets", "environment", "jest", "node"],
"module": "CommonJS"
},
"exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx"],
"include": ["./src/**/*.ts", "./src/**/*.tsx"]
}
9 changes: 9 additions & 0 deletions packages/react-conformance/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS",
"outDir": "dist",
"types": ["jest", "node"]
},
"include": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.test.ts", "**/*.test.tsx", "**/*.d.ts"]
}
7 changes: 5 additions & 2 deletions scripts/tasks/src/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,13 @@ describe(`utils`, () => {
definitionsRootPath: 'dist/for/types',
});

expect(actual.overrideTsconfig.compilerOptions).toEqual(expect.objectContaining({ paths: undefined }));
expect(actual.overrideTsconfig.compilerOptions).toEqual(
expect.objectContaining({ paths: undefined, baseUrl: '.' }),
);
});

it(`should override path aliases to emitted declaration files instead of source files`, () => {
// 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
it.skip(`should override path aliases to emitted declaration files instead of source files`, () => {
const actual = setup({
definitionsRootPath: 'dist/for/types',
pathAliasesTsConfigPath: path.join(workspaceRoot, 'tsconfig.base.json'),
Expand Down
21 changes: 14 additions & 7 deletions scripts/tasks/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ function enableAllowSyntheticDefaultImports(options: { pkgJson: PackageJson }) {
return shouldEnable ? { allowSyntheticDefaultImports: true } : null;
}

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @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
function createNormalizedTsPaths(options: { definitionsRootPath: string; pathAliasesTsConfigPath: string }) {
type PathAliases = Record<string, string[]>;
const { definitionsRootPath, pathAliasesTsConfigPath } = options;
Expand All @@ -132,14 +134,16 @@ export function getTsPathAliasesApiExtractorConfig(options: {
definitionsRootPath: string;
pathAliasesTsConfigPath?: string;
}) {
const { packageJson, tsConfig, pathAliasesTsConfigPath, definitionsRootPath } = options;
const { packageJson, tsConfig /* , pathAliasesTsConfigPath, definitionsRootPath */ } = options;
/**
* Because api-extractor ran into race conditions when executing via lage (https://github.com/microsoft/fluentui/issues/25766),
* 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
*
* 💡 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
*/
const normalizedPaths = pathAliasesTsConfigPath
? createNormalizedTsPaths({ definitionsRootPath, pathAliasesTsConfigPath })
: undefined;
// const normalizedPaths = pathAliasesTsConfigPath
// ? createNormalizedTsPaths({ definitionsRootPath, pathAliasesTsConfigPath })
// : undefined;

/**
* Customized TSConfig that uses `tsconfig.lib.json` as base with some required overrides:
Expand All @@ -166,10 +170,13 @@ export function getTsPathAliasesApiExtractorConfig(options: {
*/
skipLibCheck: false,
/**
* just-scripts provides invalid types for tsconfig, thus `paths` cannot be set to dictionary,nor null or `{}`
* api-extractor introduced a "feature" which is actually a bug and makes using path aliases impossible
* - 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
* - see https://github.com/microsoft/rushstack/pull/3321, https://github.com/microsoft/rushstack/pull/3339
*
*/
// @ts-expect-error - just-scripts provides invalid types
paths: normalizedPaths,
paths: undefined,
baseUrl: '.',
},
};

Expand Down
Loading