TypeScript 项目
TypeScript项目生成器可用于创建配置了最佳实践的现代化TypeScript库或应用,包括ECMAScript Modules (ESM)、TypeScript项目引用、用于运行测试的Vitest以及用于代码检查和格式化的Biome。
生成TypeScript项目
Section titled “生成TypeScript项目”您可以通过两种方式生成新的TypeScript项目:
- 安装 Nx Console VSCode Plugin 如果您尚未安装
- 在VSCode中打开Nx控制台
- 点击
Generate (UI)在"Common Nx Commands"部分 - 搜索
@aws/nx-plugin - ts#project - 填写必需参数
- 点击
Generate
pnpm nx g @aws/nx-plugin:ts#projectyarn nx g @aws/nx-plugin:ts#projectnpx nx g @aws/nx-plugin:ts#projectbunx nx g @aws/nx-plugin:ts#project| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| name 必需 | string | - | TypeScript 项目名称 |
| directory | string | packages | 库所放置的父目录。 |
| subDirectory | string | - | 库所放置的子目录。默认情况下,这是库的名称。 |
| preferInstallDependencies | boolean | true | 是否在生成器运行后优先安装依赖项。设置为 false 可在批量运行多个生成器时延迟安装(如果后续生成器需要计算 Nx 项目图,仍会运行安装);在最后统一安装一次。 |
生成器将在<directory>/<name>目录下创建以下项目结构:
文件夹src TypeScript 源代码
- index.ts
- package.json 定义项目包名和依赖的项目清单
- project.json 项目配置和构建目标
- tsconfig.json 此项目的基础 TypeScript 配置(继承工作区根目录的 tsconfig.base.json)
- tsconfig.lib.json 库的 TypeScript 配置(运行时或打包源码)
- tsconfig.spec.json 测试的 TypeScript 配置
- vitest.config.mts Vitest 配置
您还会发现工作区根目录的以下文件发生了变化:
- nx.json Nx 配置已更新以为您的项目配置 @nx/js/typescript 插件
- tsconfig.base.json 为您的项目设置了 TypeScript 别名,以便工作区中的其他项目可以导入它
- tsconfig.json 为您的项目添加了 TypeScript 项目引用
编写TypeScript源码
Section titled “编写TypeScript源码”在src目录中添加TypeScript代码。
ESM导入语法
Section titled “ESM导入语法”由于TypeScript项目是ES模块,请确保使用正确的ESM语法编写导入语句,显式指定文件扩展名:
import { sayHello } from './hello.js';为其他TypeScript项目导出
Section titled “为其他TypeScript项目导出”项目的入口点是src/index.ts。您可以在此处添加需要被其他项目导入的导出:
export { sayHello } from './hello.js';export * from './algorithms/index.js';在其他项目中导入库代码
Section titled “在其他项目中导入库代码”工作区tsconfig.base.json中配置了TypeScript别名,允许从其他TypeScript项目引用您的项目:
import { sayHello } from '@my-scope/my-library';首次在工作区中导入新项目时,IDE可能会显示类似以下错误:
导入错误
File '/path/to/my/workspace/packages/my-library/src/index.ts' is not under 'rootDir' '/path/to/my/workspace/packages/my-consumer'. 'rootDir' is expected to contain all source files. File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6059)File '/path/to/my/workspace/packages/my-library/src/index.ts' is not listed within the file list of project '/path/to/my/workspace/packages/my-consumer/tsconfig.lib.json'. Projects must list all files or use an 'include' pattern. File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6307)这是因为尚未设置项目引用,并且导入的项目尚未在您项目的 package.json 中声明为工作区依赖。
您的工作区配置了同步生成器,可以为您管理这两者,因此您无需手动配置它们。只需运行以下命令,Nx 将添加所需的配置:
pnpm nx syncyarn nx syncnpx nx syncbunx nx sync NX The workspace is out of sync
[@nx/js:typescript-sync]: Some TypeScript configuration files are missing project references to the projects they depend on, contain stale project references, or have duplicate project references.[@aws/nx-plugin:ts#sync]: Local project dependencies are out of sync. The following workspace dependencies will be declared:packages/my-other-project/package.json:- @my-scope/my-library: workspace:*
Syncing the workspace...The workspace was synced successfully!Nx 的 TypeScript 同步生成器添加项目引用,而插件的 ts#sync 生成器在您项目的 package.json 中声明导入的项目(在包管理器支持工作区协议的情况下为 workspace:*,在 npm 和 yarn classic 上为 *),以便包管理器在安装时链接本地项目。此后 IDE 错误应消失,即可正常使用库。
保持路径别名同步
Section titled “保持路径别名同步”如果您在项目的 tsconfig.json 中添加自定义的 compilerOptions.paths 条目,TypeScript 将停止继承 tsconfig.base.json 中定义的工作区别名。隐藏的 ts#sync 生成器会在 compile 目标之前运行(在 nx.json 中配置),将任何缺失的基础别名复制到已声明 paths 的 tsconfig.json、tsconfig.lib.json 和 tsconfig.app.json 文件中。要禁用此功能,请从 nx.json 的 targetDefaults.compile.syncGenerators 中移除 @aws/nx-plugin:ts#sync。
每个 TypeScript 项目在其自己的 package.json 中声明其第三方运行时依赖。跨项目共享的构建和测试工具在根 package.json 中定义。
要向项目添加运行时依赖,请将其安装到该项目中:
pnpm add some-npm-package --filter my-libraryyarn workspace @my-scope/my-library add some-npm-packagenpm install --legacy-peer-deps some-npm-package -w packages/my-librarybun add some-npm-package --cwd packages/my-library您也可以在项目目录中运行包管理器的普通 add/install 命令。
要添加共享的开发工具,请将其安装到工作区根目录:
pnpm add -Dw some-dev-toolyarn add -D some-dev-toolnpm install --legacy-peer-deps -D some-dev-toolbun add -D some-dev-tool对于支持目录的包管理器(pnpm、yarn 和 bun),生成器会在目录中记录每个版本,并使用 catalog: 协议引用它(例如 "zod": "catalog:"),因此无论哪个项目声明依赖,目录都是版本的唯一真实来源。这有助于您遵循单一版本策略,避免类型冲突和部署包中的多个包副本。
当您自己添加新依赖时,也要将其保留在目录中:
工作区设置了 catalogMode: strict,因此 pnpm add 会在目录中记录版本并自动引用它——无需额外步骤。
pnpm add some-npm-package --filter my-libraryyarn 的 catalog: 协议只能引用现有的目录条目——无法创建新条目——因此请先记录版本。
-
在
.yarnrc.yml的catalog下添加版本:.yarnrc.yml catalog:some-npm-package: ^1.0.0 -
从项目中引用它:
Terminal window yarn workspace @my-scope/my-library add some-npm-package@catalog:
bun 的 catalog: 协议只能引用现有的目录条目——无法创建新条目——因此请先记录版本。
-
在根目录
package.json的catalog下添加版本:package.json {"catalog": {"some-npm-package": "^1.0.0"}} -
从项目中引用它:
Terminal window bun add some-npm-package@catalog: --cwd packages/my-library
选择退出目录
Section titled “选择退出目录”目录默认启用。要关闭它们,请使用 --catalog false 创建工作区:
pnpm create @aws/nx-workspace my-project --catalog falseyarn create @aws/nx-workspace my-project --catalog falsenpm create @aws/nx-workspace -- my-project --catalog falsebun create @aws/nx-workspace my-project --catalog false或随时在 aws-nx-plugin.config.mts 中设置:
export default { packageManager: { catalogs: false, },} satisfies AwsNxPluginConfig;禁用目录后,生成器会将依赖版本直接写入每个项目的 package.json,保持项目间版本一致是您的责任。
在根目录声明所有依赖
Section titled “在根目录声明所有依赖”如果您更喜欢仅在根目录 package.json 中声明所有依赖(不进行每个项目的依赖声明),请在工作区 biome.json 中关闭 lint 规则:
{ "linter": { "rules": { "correctness": { "noUndeclaredDependencies": "off" } } }}项目在构建时解析根目录安装的包,因此一切仍然可以构建——您放弃了每个项目清单作为每个项目依赖的准确记录(如果您以后发布项目或拆分仓库,这很重要)。
当您将 TypeScript 项目用作运行时代码(例如作为 AWS Lambda 函数的处理程序)时,建议使用 Rolldown 等工具来打包项目,因为这可以进行 tree-shaking 以确保仅包含项目实际引用的依赖。
您可以通过在 project.json 文件中添加如下目标来实现:
{ ... "targets": { ... "bundle": { "cache": true, "executor": "nx:run-commands", "outputs": ["{workspaceRoot}/dist/packages/my-library/bundle"], "options": { "command": "rolldown -c rolldown.config.ts" } }, },}并添加 rolldown.config.ts 文件如下:
import { defineConfig } from 'rolldown';
export default defineConfig([ { input: 'src/index.ts', output: { file: '../../dist/packages/my-library/bundle/index.js', format: 'cjs', inlineDynamicImports: true, }, },]);您的 TypeScript 项目配置了 build 目标(定义在 project.json 中),您可以通过以下方式运行:
pnpm nx build <project-name>yarn nx build <project-name>npx nx build <project-name>bunx nx build <project-name>其中 <project-name> 是项目的完全限定名称。
build 目标将编译、lint 和测试您的项目。
构建输出可以在工作区根目录的 dist 文件夹中找到,位于您的包和目标的目录中,例如 dist/packages/<my-library>/tsc
要构建工作区中所有项目,请运行:
pnpm nx run-many --target buildyarn nx run-many --target buildnpx nx run-many --target buildbunx nx run-many --target build或使用简写命令:
pnpm buildyarn buildnpm run buildbun buildVitest 已配置用于测试您的项目。
测试应写在 .spec.ts 或 .test.ts 文件中,与项目的 src 文件夹中的代码共置。
例如:
文件夹src
- hello.ts 库源代码
- hello.spec.ts hello.ts 的测试
Vitest 提供类似 Jest 的语法来定义测试,包括 describe、it、test 和 expect 等工具。
import { sayHello } from './hello.js';
describe('sayHello', () => {
it('should greet the caller', () => { expect(sayHello('Darth Vader')).toBe('Hello, Darth Vader!'); });
});有关如何编写测试以及模拟依赖等功能的更多详细信息,请参阅 Vitest 文档
测试将作为项目 build 目标的一部分运行,但您也可以通过运行 test 目标单独运行它们:
pnpm nx test <project-name>yarn nx test <project-name>npx nx test <project-name>bunx nx test <project-name>您可以使用 Vitest 的 -t 标志运行单个测试或测试套件。在 -- 分隔符之后传递它,以便 Nx 将其转发给 Vitest,而不是将其作为自己的 --target 选项使用:
pnpm nx test <project-name> -- -t 'sayHello'yarn nx test <project-name> -- -t 'sayHello'npx nx test <project-name> -- -t 'sayHello'bunx nx test <project-name> -- -t 'sayHello'TypeScript 项目使用 Biome 进行代码检查和格式化。Biome 在工作区根目录的 biome.json 文件中配置——对此文件的更改将应用于工作区中的所有 TypeScript 项目并确保一致性。
要调用检查器来检查您的项目,您可以运行 lint 目标。
pnpm nx lint <project-name>yarn nx lint <project-name>npx nx lint <project-name>bunx nx lint <project-name>修复 Lint 问题
Section titled “修复 Lint 问题”大多数代码检查或格式化问题可以通过使用 --configuration=fix 参数运行来自动修复。
pnpm nx lint <project-name> --configuration=fixyarn nx lint <project-name> --configuration=fixnpx nx lint <project-name> --configuration=fixbunx nx lint <project-name> --configuration=fix同样,如果您想修复工作区中所有包的所有 lint 问题,可以运行:
pnpm nx run-many --target lint --all --configuration=fixyarn nx run-many --target lint --all --configuration=fixnpx nx run-many --target lint --all --configuration=fixbunx nx run-many --target lint --all --configuration=fix跳过 Lint 问题
Section titled “跳过 Lint 问题”为了避免代码检查问题在开发过程中拖慢您的速度(特别是如果您的项目中有无法自动修复的问题),您可以使用 skip-lint 配置运行构建:
pnpm nx run-many --target build --configuration=skip-lintyarn nx run-many --target build --configuration=skip-lintnpx nx run-many --target build --configuration=skip-lintbunx nx run-many --target build --configuration=skip-lint这会在构建期间完全跳过lint目标。