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

chore(tsconfig): add configs directory and ts configuration #3497

Merged
merged 9 commits into from
Mar 3, 2023
Merged
8 changes: 8 additions & 0 deletions .changeset/long-tables-sit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@aws-amplify/ui-react-core": patch
"@aws-amplify/ui-react-native": patch
"@aws-amplify/ui-react": patch
"@aws-amplify/ui": patch
---

chore(tsconfig): add configs directory and ts configuration
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@mdx-js/react": "^2.1.0",
"@moxy/next-compile-node-modules": "^2.1.1",
"@xstate/inspect": "^0.4.1",
"aws-amplify": "^5.0.1",
"aws-amplify": "^5.0.16",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing skipLibCheck caused react-core to have linting failures from a type issue in @aws-amplify/storage@5.0.1 which was fixed in aws-amplify/amplify-js#10696.

Upgrading aws-amplify here as it is the version that gets hoisted in to the top level node_modules.

"classnames": "^2.3.1",
"countries-list": "^2.6.1",
"dotenv": "^16.0.0",
Expand Down
66 changes: 66 additions & 0 deletions packages/configs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Overview
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This readme is awesome!


Base Configuration files for platform (example `@aws-amplify/ui-vue`) and utility packages (example `@aws-amplify/ui-react-core`) in the Amplify UI monorepo.

## Package Types

There are currently 3 types of packages that Amplify UI supports:

- **Utility Packages:** Packages shared across all platforms

- `@aws-amplify/ui`

- **React Utility Packages:** Non-UI React utilites and hooks shared between React and React Native platform packages

- `@aws-amplify/ui-react-core`

- **Platform UI Packages:**
- `@aws-amplify/ui-angular`
- `@aws-amplify/ui-react`
- `@aws-amplify/ui-react-native`
- `@aws-amplify/ui-vue`

## Typescript

To prevent drift between the `compilerOptions` of the _tsconfig.json_ files in the Amplify UI monorepo as more packages are added, base Typescript `compilerOptions` configurations are stored within the [ts](./ts) directory. The **[Base Config](./ts/base.json)** is extended directly or indirectly in all platform and utility packages.

- Utility package _tsconfig.json_ files directly use the **[Base Config](./ts/base.json)**
- React UI/React Utility package _tsconfig.json_ files use the **[React Base Config](./ts/react.json)**, extends from the **Base Config**
- React Native UI package _tsconfig.json_ files use the **[React Native Base Config](./ts/react-native.json)**, extends from the **Base Config**

A basic visualization of the extension hierarchy:

```tree
base.json
├── react.json
└── react-native.json
```

### Strict Mode

All packages are in TS strict mode by default unless opted out at the package configuration level.

### Usage of _tsconfig.dist.json_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about naming this to _tsconfig.prod.json_ so that this is more explicit?

Copy link
Member Author

@calebpollman calebpollman Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not feeling super strongly (so basically feeling minimally strongly) about the name, but prefer tsconfig.dist.json because:

  • we already use it
  • it aligns with the dist output directory

Edit: also feel like "prod" is more aligned to application stages ¯\(ツ)


To allow type support and linting in _\_\_tests\_\__ and _\_\_mocks\_\__ directories during development, package level _tsconfig.json_ include all _.ts_ and _.tsx_ files. For builds, package level _tsconfig.dist.json_ files extend from their sibling _tsconfig.json_ file overriding the `excludes` value with the _\_\_tests\_\__ and _\_\_mocks\_\__ directories.

**Example:**

_react-core/tsconfig.json_

```json
{
"extends": "../configs/ts/react.json",
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"]
}
```

_react-core/tsconfig.dist.json_

```json
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "**/__mocks__", "**/__tests__"]
}
```
13 changes: 13 additions & 0 deletions packages/configs/ts/base.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"declaration": true,
"esModuleInterop": true,
"importHelpers": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"target": "es6"
}
}
8 changes: 8 additions & 0 deletions packages/configs/ts/react-native.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./base.json",
"compilerOptions": {
"jsx": "react-native",
"skipLibCheck": true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Native only requires skipLibCheck due its incompatible typing with @types/node, see DefinitelyTyped/DefinitelyTyped#15960 for further context

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too bad json doesn't support comments. But maybe we can include this info in the readme?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if we convert to .ts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zhamujun Can you extend .ts files in a tsconfig?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a discussion on it microsoft/TypeScript#25271

And there's a package to do it https://www.npmjs.com/package/tsconfig.js

Maybe not worth our time to convert and introduce another dependency

"target": "esnext"
}
}
6 changes: 6 additions & 0 deletions packages/configs/ts/react.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "./base.json",
"compilerOptions": {
"jsx": "react"
}
}
1 change: 0 additions & 1 deletion packages/react-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
"@types/jest": "^26.0.23",
"@types/react": "^17.0.2",
"@types/react-dom": "^17.0.13",
"@types/react-native": "^0.63.45",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing skipLibCheck in react-core exposed the incompatibility issue with @types/react-native and @types/node.

@types/react-native is unused in this package, and most likely will not be required in the future. If it is can turn back on skipLibCheck at that point

"@types/react-test-renderer": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.6.0",
Expand Down
30 changes: 18 additions & 12 deletions packages/react-core/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
// rollup.config.js
import { defineConfig } from 'rollup';
import typescript from '@rollup/plugin-typescript';
import externals from 'rollup-plugin-node-externals';

// common config settings
const input = ['src/index.ts'];
const sourceMap = false;
const tsconfig = 'tsconfig.dist.json';

const esmOutputDir = 'dist/esm';

const config = defineConfig([
// CJS config
{
input: ['src/index.ts'],
output: {
dir: 'dist',
format: 'cjs',
sourcemap: false,
},
input,
output: { dir: 'dist', format: 'cjs' },
plugins: [
externals({ include: /^@aws-amplify/ }),
typescript({ declarationDir: 'dist/types', sourceMap: false }),
typescript({ declarationDir: 'dist/types', sourceMap, tsconfig }),
],
},
// ESM config
{
input: ['src/index.ts'],
input,
output: {
dir: 'dist/esm',
dir: esmOutputDir,
format: 'es',
entryFileNames: '[name].mjs',
preserveModules: true,
preserveModulesRoot: 'src',
sourcemap: false,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the output.sourcemap option in all of the ESM and CJS rollup configs as they are extraneous. The setting of sourceMap to false in the typescript plugin options handles it

},
plugins: [
externals({ include: /^@aws-amplify/ }),
typescript({ outDir: 'dist/esm', declaration: false, sourceMap: false }),
typescript({
outDir: esmOutputDir,
declaration: false,
sourceMap,
tsconfig,
}),
],
},
]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
INVALID_OVERRIDES,
INVALID_SIGN_IN_OVERRIDES,
OVERRIDES,
} from '../__mock__/components';
} from '../__mocks__/components';

describe('isComponentRouteKey', () => {
it.each(COMPONENT_ROUTE_KEYS)('returns true for a %s value', (route) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { renderHook } from '@testing-library/react-hooks';

import { RenderNothing } from '../../../../components';
import { COMPONENT_ROUTE_KEYS } from '../../constants';
import { DEFAULTS } from '../../__mock__/components';
import { DEFAULTS } from '../../__mocks__/components';
import { mockUseAuthenticatorOutput } from '../../useAuthenticator/__mock__/useAuthenticator';
import { useAuthenticator } from '../../useAuthenticator';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '../../types';
import { UseAuthenticator } from '../../useAuthenticator/types';

import { DEFAULTS } from '../../__mock__/components';
import { DEFAULTS } from '../../__mocks__/components';
import {
mockMachineContext,
mockUseAuthenticatorOutput,
Expand Down
4 changes: 4 additions & 0 deletions packages/react-core/tsconfig.dist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "**/__mocks__", "**/__tests__"]
}
15 changes: 1 addition & 14 deletions packages/react-core/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"declaration": true,
"esModuleInterop": true,
"importHelpers": true,
"jsx": "react",
"module": "esnext",
"moduleResolution": "node",
"noImplicitAny": true,
"skipLibCheck": true,
"strict": true,
"target": "es6"
},
"extends": "../configs/ts/react.json",
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { StyleSheet, ViewStyle } from 'react-native';
import { StrictTheme } from 'src/theme';
import { StrictTheme } from '../../../theme';

import { ContainerStyles, InnerContainerStyles } from './types';

Expand Down
15 changes: 2 additions & 13 deletions packages/react-native/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
{
"extends": "../configs/ts/react-native.json",
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"declaration": true,
"esModuleInterop": true,
"importHelpers": true,
"jsx": "react-native",
"noImplicitAny": true,
"module": "esnext",
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "src",
"skipLibCheck": true,
"strict": true,
"target": "esnext"
"rootDir": "src"
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"]
Expand Down
2 changes: 1 addition & 1 deletion packages/react/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ module.exports = {
files: ['**/*.spec.*', '**/*.test.*'],
parser: '@typescript-eslint/parser',
parserOptions: {
project: ['./tsconfig.dev.json'],
project: ['./tsconfig.json'],
},
plugins: ['@typescript-eslint', 'jest'],
rules: {
Expand Down
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"dev": "tsup --watch",
"dev:build": "tsup",
"clean": "rimraf dist node_modules",
"lint": "tsc --noEmit --project tsconfig.dev.json && eslint src --ext .js,.ts,.tsx",
"lint": "tsc --noEmit && eslint src --ext .js,.ts,.tsx",
"test": "yarn test:unit && yarn test:esm",
"test:esm": "node --input-type=module --eval 'import \"@aws-amplify/ui-react\"'",
"test:watch": "yarn test:unit:watch",
Expand Down
21 changes: 14 additions & 7 deletions packages/react/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
// rollup.config.js
import { defineConfig } from 'rollup';
import typescript from '@rollup/plugin-typescript';
import { terser } from 'rollup-plugin-terser';
import styles from 'rollup-plugin-styles';
import externals from 'rollup-plugin-node-externals';

// common config settings
const input = ['src/index.ts', 'src/internal.ts'];
const sourceMap = false;
const tsconfig = 'tsconfig.dist.json';
Copy link
Contributor

@0618 0618 Mar 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: what do you think if we have a const commonConfigSettings = {...} object? Because it's hard to tell where the "common config settings" ends from the comment


const config = defineConfig([
// CJS config
{
input: ['src/index.tsx', 'src/internal.tsx'],
input,
output: {
dir: 'dist',
format: 'cjs',
sourcemap: false,
},
plugins: [
externals({ include: /^@aws-amplify/ }),
typescript({ declarationDir: 'dist/types', sourceMap: false }),
typescript({ declarationDir: 'dist/types', sourceMap, tsconfig }),
terser(),
],
},
// ESM config
{
input: ['src/index.tsx', 'src/internal.tsx'],
input,
output: {
dir: 'dist/esm',
format: 'es',
entryFileNames: '[name].mjs',
preserveModules: true,
preserveModulesRoot: 'src',
sourcemap: false,
},
plugins: [
externals({ include: /^@aws-amplify/ }),
typescript({ outDir: 'dist/esm', declaration: false, sourceMap: false }),
typescript({
outDir: 'dist/esm',
declaration: false,
sourceMap,
tsconfig,
}),
terser(),
],
},
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 0 additions & 4 deletions packages/react/tsconfig.dev.json

This file was deleted.

4 changes: 4 additions & 0 deletions packages/react/tsconfig.dist.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "**/__mocks__", "**/__tests__"]
}
17 changes: 5 additions & 12 deletions packages/react/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
{
"extends": "../configs/ts/react.json",
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"declaration": true,
"esModuleInterop": true,
"importHelpers": true,
"jsx": "react",
"module": "esnext",
"moduleResolution": "node",
"rootDir": "./src",
"noImplicitAny": false,
"skipLibCheck": true,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added skipLibCheck back as removing exposed a linting error caused by a type error in maplibre-gl-js-amplify:

$ yarn workspace @aws-amplify/ui-react lint
$ tsc --noEmit && eslint src --ext .js,.ts,.tsx
../../node_modules/maplibre-gl-js-amplify/lib/esm/AmplifyGeofenceControl/AmplifyMapDraw.d.ts:1:23 - error TS2688: Cannot find type definition file for 'mapbox__mapbox-gl-draw'.

1 /// <reference types="mapbox__mapbox-gl-draw" />
                        ~~~~~~~~~~~~~~~~~~~~~~


Found 1 error in ../../node_modules/maplibre-gl-js-amplify/lib/esm/AmplifyGeofenceControl/AmplifyMapDraw.d.ts:1

Will add a github issue there to address it and can remove the flag once it's fixed.

"target": "es6"
"strict": false
},
"exclude": ["node_modules", "src/**/*.test.ts", "src/**/*.test.tsx"],
"include": ["src/**/*.ts", "src/**/*.tsx"]
"include": ["src/**/*.ts", "src/**/*.tsx"],
"exclude": ["node_modules"]
calebpollman marked this conversation as resolved.
Show resolved Hide resolved
}
1 change: 1 addition & 0 deletions packages/ui/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
node: true,
},
extends: ['eslint:recommended'],
ignorePatterns: ['dist'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2020,
Expand Down
Loading