From d477ea7b6a134de1955fc12f15d749165cbefc91 Mon Sep 17 00:00:00 2001 From: Isaac Mann Date: Thu, 3 Oct 2024 20:39:25 -0400 Subject: [PATCH] docs(core): ts project references guide (#28281) Adds a TS project references guide --- docs/generated/manifests/menus.json | 8 + docs/generated/manifests/nx-api.json | 11 ++ docs/generated/packages-metadata.json | 11 ++ .../typescript-project-references.md | 141 ++++++++++++++++++ docs/map.json | 6 + .../js/typescript-project-references.md | 141 ++++++++++++++++++ docs/shared/reference/sitemap.md | 1 + 7 files changed, 319 insertions(+) create mode 100644 docs/generated/packages/js/documents/typescript-project-references.md create mode 100644 docs/shared/packages/js/typescript-project-references.md diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 975e104457..0b37c71ee4 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -8135,6 +8135,14 @@ "isExternal": false, "children": [], "disableCollapsible": false + }, + { + "name": "Configure TypeScript Project References in an Nx Workspace", + "path": "/nx-api/js/documents/typescript-project-references", + "id": "typescript-project-references", + "isExternal": false, + "children": [], + "disableCollapsible": false } ], "isExternal": false, diff --git a/docs/generated/manifests/nx-api.json b/docs/generated/manifests/nx-api.json index 0027579936..bc3518e8d1 100644 --- a/docs/generated/manifests/nx-api.json +++ b/docs/generated/manifests/nx-api.json @@ -1168,6 +1168,17 @@ "path": "/nx-api/js/documents/overview", "tags": [], "originalFilePath": "shared/packages/js/js-plugin" + }, + "/nx-api/js/documents/typescript-project-references": { + "id": "typescript-project-references", + "name": "Configure TypeScript Project References in an Nx Workspace", + "description": "The JS plugin for Nx contains executors and generators that provide the best experience for developing JavaScript and TypeScript projects. ", + "file": "generated/packages/js/documents/typescript-project-references", + "itemList": [], + "isExternal": false, + "path": "/nx-api/js/documents/typescript-project-references", + "tags": [], + "originalFilePath": "shared/packages/js/typescript-project-references" } }, "root": "/packages/js", diff --git a/docs/generated/packages-metadata.json b/docs/generated/packages-metadata.json index 4d47064750..55af024069 100644 --- a/docs/generated/packages-metadata.json +++ b/docs/generated/packages-metadata.json @@ -1152,6 +1152,17 @@ "path": "js/documents/overview", "tags": [], "originalFilePath": "shared/packages/js/js-plugin" + }, + { + "id": "typescript-project-references", + "name": "Configure TypeScript Project References in an Nx Workspace", + "description": "The JS plugin for Nx contains executors and generators that provide the best experience for developing JavaScript and TypeScript projects. ", + "file": "generated/packages/js/documents/typescript-project-references", + "itemList": [], + "isExternal": false, + "path": "js/documents/typescript-project-references", + "tags": [], + "originalFilePath": "shared/packages/js/typescript-project-references" } ], "executors": [ diff --git a/docs/generated/packages/js/documents/typescript-project-references.md b/docs/generated/packages/js/documents/typescript-project-references.md new file mode 100644 index 0000000000..a33f6e4fa0 --- /dev/null +++ b/docs/generated/packages/js/documents/typescript-project-references.md @@ -0,0 +1,141 @@ +# Configure TypeScript Project References in an Nx Workspace + +In Nx 20, the `@nx/js` plugin provides the ability to incrementally build projects in a monorepo using [TypeScript Project References](https://www.typescriptlang.org/docs/handbook/project-references.html). Nx also provides a `ts` preset for `create-nx-workspace` that configures project references and uses `workspaces` to link projects instead of [TypeScript compilerOptions Paths](https://www.typescriptlang.org/docs/handbook/modules/reference.html#paths). + +The TypeScript team recommends using project references when working in a monorepo, but until now the configuration settings were difficult to maintain. Each project is required to list its own project dependencies in the `references` property of the `tsconfig.json` file so that TypeScript can incrementally compile projects in the correct order. In a large monorepo, maintaining those settings manually is cost prohibitive. To solve this problem, the `@nx/js` plugin registers a [sync generator](/concepts/sync-generators) to automatically update the references based on Nx's project graph before any TypeScript `build` task is executed. + +## Create a New Nx Workspace Using Project References + +We anticipate that this style of compiling projects will eventually become the default, but currently it will only be enabled for repositories configured in a specific way. Existing workspaces will continue to function as usual and there is no migration path yet. You can generate a new repository with these settings by using the `--preset=ts` flag of the `create-nx-workspace` command. + +```shell +npx create-nx-workspace --preset=ts +``` + +{% callout type="note" title="Empty Workspace with Paths" %} +To generate an empty Nx workspace that links projects with the `compilerOptions.paths` property and does not use project references, use `create-nx-workspace --preset=apps` +{% /callout %} + +This will generate an empty repository that is configured to use TypeScript project references. To see the new functionality in action, create some TypeScript projects and make sure to use the `tsc` bundler option. + +```shell +nx g @nx/js:lib packages/cart --bundler=tsc +nx g @nx/js:lib packages/utils --bundler=tsc +``` + +These generators will detect that your repository is configured to use project references and update the configuration accordingly. If these generators were executed in an Nx repository that used `compilerOptions.paths`, they would update that setting instead. + +To make `cart` depend on `utils`, update `packages/cart/package.json` like this: + +```jsonc {% fileName="packages/cart/package.json" %} +{ + "dependencies": { + "utils": "*" + } +} +``` + +Now if you run `nx build cart` or directly run `nx sync`, the `packages/cart/tsconfig.json` file will have its references updated for you. + +## Project Reference Configuration Files + +Nx expects the following configuration settings to be in place in order to use TypeScript project references to build projects. Most of this configuration is set up and maintained for you automatically by Nx. + +Identify projects in the `workspaces` property in the root `package.json` file. + +```json {% fileName="package.json" %} +{ + "workspaces": ["packages/*"] +} +``` + +The root `tsconfig.base.json` should contain a `compilerOptions` property and no other properties. `compilerOptions.composite` and `compilerOptions.declaration` should be set to `true`. `compilerOptions.paths` should not be set. + +```jsonc {% fileName="tsconfig.base.json" %} +{ + "compilerOptions": { + // Required compiler options + "composite": true, + "declaration": true + // Other options... + } +} +``` + +The root `tsconfig.json` file should extend `tsconfig.base.json` and not include any files. It needs to have `references` for every project in the repository so that editor tooling works correctly. + +```jsonc {% fileName="tsconfig.json" %} +{ + "extends": "./tsconfig.base.json", + "files": [], // intentionally empty + "references": [ + // UPDATED BY PROJECT GENERATORS + // All projects in the repository + ] +} +``` + +Each project's `tsconfig.json` file should extend the `tsconfig.base.json` file and list `references` to the project's dependencies. + +```jsonc {% fileName="packages/cart/tsconfig.json" %} +{ + "extends": "../../tsconfig.base.json", + "files": [], // intentionally empty + "references": [ + // UPDATED BY NX SYNC + // All project dependencies + { + "path": "../utils" + }, + // This project's other tsconfig.*.json files + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} +``` + +Each project's `tsconfig.lib.json` file extends the project's `tsconfig.json` file and adds `references` to the `tsconfig.lib.json` files of project dependencies. + +```jsonc {% fileName="packages/cart/tsconfig.lib.json" %} +{ + "extends": "./tsconfig.json", + "compilerOptions": { + // Any overrides + }, + "include": ["src/**/*.ts"], + "exclude": [ + // exclude config and test files + ], + "references": [ + // UPDATED BY NX SYNC + // tsconfig.lib.json files for project dependencies + { + "path": "../utils/tsconfig.lib.json" + } + ] +} +``` + +The project's `tsconfig.spec.json` does not need to reference project dependencies. + +```jsonc {% fileName="packages/cart/tsconfig.spec.json" %} +{ + "extends": "./tsconfig.json", + "compilerOptions": { + // Any overrides + }, + "include": [ + // test files + ], + "references": [ + // tsconfig.lib.json for this project + { + "path": "./tsconfig.lib.json" + } + ] +} +``` diff --git a/docs/map.json b/docs/map.json index e05e190aa0..3e4416a8e9 100644 --- a/docs/map.json +++ b/docs/map.json @@ -2246,6 +2246,12 @@ "id": "overview", "path": "/nx-api/js", "file": "shared/packages/js/js-plugin" + }, + { + "name": "Configure TypeScript Project References in an Nx Workspace", + "id": "typescript-project-references", + "path": "/nx-api/js/typescript-project-references", + "file": "shared/packages/js/typescript-project-references" } ] }, diff --git a/docs/shared/packages/js/typescript-project-references.md b/docs/shared/packages/js/typescript-project-references.md new file mode 100644 index 0000000000..a33f6e4fa0 --- /dev/null +++ b/docs/shared/packages/js/typescript-project-references.md @@ -0,0 +1,141 @@ +# Configure TypeScript Project References in an Nx Workspace + +In Nx 20, the `@nx/js` plugin provides the ability to incrementally build projects in a monorepo using [TypeScript Project References](https://www.typescriptlang.org/docs/handbook/project-references.html). Nx also provides a `ts` preset for `create-nx-workspace` that configures project references and uses `workspaces` to link projects instead of [TypeScript compilerOptions Paths](https://www.typescriptlang.org/docs/handbook/modules/reference.html#paths). + +The TypeScript team recommends using project references when working in a monorepo, but until now the configuration settings were difficult to maintain. Each project is required to list its own project dependencies in the `references` property of the `tsconfig.json` file so that TypeScript can incrementally compile projects in the correct order. In a large monorepo, maintaining those settings manually is cost prohibitive. To solve this problem, the `@nx/js` plugin registers a [sync generator](/concepts/sync-generators) to automatically update the references based on Nx's project graph before any TypeScript `build` task is executed. + +## Create a New Nx Workspace Using Project References + +We anticipate that this style of compiling projects will eventually become the default, but currently it will only be enabled for repositories configured in a specific way. Existing workspaces will continue to function as usual and there is no migration path yet. You can generate a new repository with these settings by using the `--preset=ts` flag of the `create-nx-workspace` command. + +```shell +npx create-nx-workspace --preset=ts +``` + +{% callout type="note" title="Empty Workspace with Paths" %} +To generate an empty Nx workspace that links projects with the `compilerOptions.paths` property and does not use project references, use `create-nx-workspace --preset=apps` +{% /callout %} + +This will generate an empty repository that is configured to use TypeScript project references. To see the new functionality in action, create some TypeScript projects and make sure to use the `tsc` bundler option. + +```shell +nx g @nx/js:lib packages/cart --bundler=tsc +nx g @nx/js:lib packages/utils --bundler=tsc +``` + +These generators will detect that your repository is configured to use project references and update the configuration accordingly. If these generators were executed in an Nx repository that used `compilerOptions.paths`, they would update that setting instead. + +To make `cart` depend on `utils`, update `packages/cart/package.json` like this: + +```jsonc {% fileName="packages/cart/package.json" %} +{ + "dependencies": { + "utils": "*" + } +} +``` + +Now if you run `nx build cart` or directly run `nx sync`, the `packages/cart/tsconfig.json` file will have its references updated for you. + +## Project Reference Configuration Files + +Nx expects the following configuration settings to be in place in order to use TypeScript project references to build projects. Most of this configuration is set up and maintained for you automatically by Nx. + +Identify projects in the `workspaces` property in the root `package.json` file. + +```json {% fileName="package.json" %} +{ + "workspaces": ["packages/*"] +} +``` + +The root `tsconfig.base.json` should contain a `compilerOptions` property and no other properties. `compilerOptions.composite` and `compilerOptions.declaration` should be set to `true`. `compilerOptions.paths` should not be set. + +```jsonc {% fileName="tsconfig.base.json" %} +{ + "compilerOptions": { + // Required compiler options + "composite": true, + "declaration": true + // Other options... + } +} +``` + +The root `tsconfig.json` file should extend `tsconfig.base.json` and not include any files. It needs to have `references` for every project in the repository so that editor tooling works correctly. + +```jsonc {% fileName="tsconfig.json" %} +{ + "extends": "./tsconfig.base.json", + "files": [], // intentionally empty + "references": [ + // UPDATED BY PROJECT GENERATORS + // All projects in the repository + ] +} +``` + +Each project's `tsconfig.json` file should extend the `tsconfig.base.json` file and list `references` to the project's dependencies. + +```jsonc {% fileName="packages/cart/tsconfig.json" %} +{ + "extends": "../../tsconfig.base.json", + "files": [], // intentionally empty + "references": [ + // UPDATED BY NX SYNC + // All project dependencies + { + "path": "../utils" + }, + // This project's other tsconfig.*.json files + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} +``` + +Each project's `tsconfig.lib.json` file extends the project's `tsconfig.json` file and adds `references` to the `tsconfig.lib.json` files of project dependencies. + +```jsonc {% fileName="packages/cart/tsconfig.lib.json" %} +{ + "extends": "./tsconfig.json", + "compilerOptions": { + // Any overrides + }, + "include": ["src/**/*.ts"], + "exclude": [ + // exclude config and test files + ], + "references": [ + // UPDATED BY NX SYNC + // tsconfig.lib.json files for project dependencies + { + "path": "../utils/tsconfig.lib.json" + } + ] +} +``` + +The project's `tsconfig.spec.json` does not need to reference project dependencies. + +```jsonc {% fileName="packages/cart/tsconfig.spec.json" %} +{ + "extends": "./tsconfig.json", + "compilerOptions": { + // Any overrides + }, + "include": [ + // test files + ], + "references": [ + // tsconfig.lib.json for this project + { + "path": "./tsconfig.lib.json" + } + ] +} +``` diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 6ff4442395..48dd25b0d4 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -476,6 +476,7 @@ - [js](/nx-api/js) - [documents](/nx-api/js/documents) - [Overview](/nx-api/js/documents/overview) + - [Configure TypeScript Project References in an Nx Workspace](/nx-api/js/documents/typescript-project-references) - [executors](/nx-api/js/executors) - [tsc](/nx-api/js/executors/tsc) - [swc](/nx-api/js/executors/swc)