跳转到内容

TypeScript 项目

TypeScript 项目生成器可用于创建现代化的 TypeScript 库或应用程序,并配置了最佳实践,例如 ECMAScript 模块 (ESM)、TypeScript 项目引用、用于运行测试的 Vitest 以及用于代码检查和格式化的 Biome

您可以通过两种方式生成新的 TypeScript 项目:

Terminal window
pnpm nx g @aws/nx-plugin:ts#project
您还可以执行试运行以查看哪些文件会被更改
Terminal window
pnpm nx g @aws/nx-plugin:ts#project --dry-run
参数类型默认值描述
name 必需string-TypeScript 项目名称
directory stringpackages库所放置的父目录。
subDirectory string-库所放置的子目录。默认情况下,这是库的名称。
preferInstallDependencies booleantrue是否在生成器运行后优先安装依赖项。设置为 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 项目引用

src 目录中添加您的 TypeScript 代码。

由于您的 TypeScript 项目是 ES 模块,请确保使用正确的 ESM 语法编写导入语句,明确引用文件扩展名:

index.ts
import { sayHello } from './hello.js';

您的 TypeScript 项目的入口点是 src/index.ts。您可以在此处添加导出,以便其他项目能够导入:

src/index.ts
export { sayHello } from './hello.js';
export * from './algorithms/index.js';

您的项目的 TypeScript 别名在工作区的 tsconfig.base.json 中配置,这允许您从其他 TypeScript 项目引用您的 TypeScript 项目:

packages/my-other-project/src/index.ts
import { sayHello } from '@my-scope/my-library';

当您第一次在工作区中为新项目添加导入语句时,您可能会在 IDE 中看到类似以下的错误:

导入错误
Terminal window
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 将添加所需的配置:

Terminal window
pnpm nx sync
Terminal window
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 中的错误应该消失,您就可以使用您的库了。

如果您在项目的 tsconfig.json 中添加自定义 compilerOptions.paths 条目,TypeScript 将停止继承 tsconfig.base.json 中定义的工作区别名。隐藏的 ts#sync 生成器在 compile 目标之前运行(在 nx.json 中配置),将任何缺失的基础别名复制到已声明 pathstsconfig.jsontsconfig.lib.jsontsconfig.app.json 文件中。要选择退出,请从 nx.json 中的 targetDefaults.compile.syncGenerators 中删除 @aws/nx-plugin:ts#sync

每个 TypeScript 项目在其自己的 package.json 中声明其第三方运行时依赖项。跨项目共享的构建和测试工具在根 package.json 中定义。

要向项目添加运行时依赖项,请将其安装到该项目中:

Terminal window
pnpm add some-npm-package --filter my-library

您也可以从项目目录中运行包管理器的普通 add/install 命令。

要添加共享的开发工具,请将其安装在工作区根目录:

Terminal window
pnpm add -Dw some-dev-tool

对于支持目录的包管理器(pnpmyarnbun),生成器将每个版本记录在目录中,并使用 catalog: 协议引用它(例如 "zod": "catalog:"),因此无论哪个项目声明依赖项,目录都是版本的唯一真实来源。这有助于您遵循单一版本策略,避免类型冲突和部署包中的多个包副本。

当您自己添加新依赖项时,也要将其保留在目录中:

工作区设置了 catalogMode: strict,因此 pnpm add 会自动在目录中记录版本并引用它——无需额外步骤。

Terminal window
pnpm add some-npm-package --filter my-library

目录默认启用。要关闭它们,请使用 --catalog false 创建工作区:

Terminal window
pnpm create @aws/nx-workspace my-project --catalog false

或随时在 aws-nx-plugin.config.mts 中设置:

aws-nx-plugin.config.mts
export default {
packageManager: {
catalogs: false,
},
} satisfies AwsNxPluginConfig;

禁用目录后,生成器会将依赖项版本直接写入每个项目的 package.json,保持项目之间版本对齐是您的责任。

如果您更喜欢仅在根 package.json 中声明每个依赖项(没有每个项目的依赖项声明),请在工作区 biome.json 中关闭代码检查规则:

biome.json
{
"linter": {
"rules": {
"correctness": {
"noUndeclaredDependencies": "off"
}
}
}
}

项目在构建时解析根安装的包,因此一切仍然可以构建——您放弃了每个项目清单作为每个项目依赖项的准确记录(如果您以后发布项目或拆分仓库,这很重要)。

当您将 TypeScript 项目用作运行时代码(例如作为 AWS Lambda 函数的处理程序)时,建议您使用诸如 Rolldown 之类的工具来打包您的项目,因为这可以进行 tree-shake 以确保只包含您的项目实际引用的依赖项。

您可以通过向 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 文件:

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',
codeSplitting: false,
},
},
]);

您的 TypeScript 项目配置了 build 目标(在 project.json 中定义),您可以通过以下方式运行:

Terminal window
pnpm nx build <project-name>

其中 <project-name> 是您项目的完全限定名称。

build 目标将编译、检查和测试您的项目。

构建输出可以在工作区的根 dist 文件夹中找到,位于您的包和目标的目录中,例如 dist/packages/<my-library>/tsc

要构建工作区中的所有项目,请运行:

Terminal window
pnpm nx run-many --target build

或使用简写命令:

Terminal window
pnpm build

Vitest 已配置用于测试您的项目。

测试应该写在 .spec.ts.test.ts 文件中,与项目的 src 文件夹中的代码放在一起。

例如:

  • 文件夹src
    • hello.ts 库源代码
    • hello.spec.ts hello.ts 的测试

Vitest 提供类似 Jest 的语法来定义测试,包括 describeittestexpect 等实用工具。

hello.spec.ts
import { sayHello } from './hello.js';
describe('sayHello', () => {
it('should greet the caller', () => {
expect(sayHello('Darth Vader')).toBe('Hello, Darth Vader!');
});
});

有关如何编写测试以及模拟依赖项等功能的更多详细信息,请参阅 Vitest 文档

测试将作为项目的 build 目标的一部分运行,但您也可以通过运行 test 目标单独运行它们:

Terminal window
pnpm nx test <project-name>

您可以使用 Vitest 的 -t 标志运行单个测试或测试套件。在 -- 分隔符之后传递它,以便 Nx 将其转发给 Vitest,而不是将其作为自己的 --target 选项使用:

Terminal window
pnpm nx test <project-name> -- -t 'sayHello'

TypeScript 项目使用 Biome 进行代码检查和格式化。Biome 在工作区根目录的 biome.json 文件中配置——对此的更改适用于工作区中的所有 TypeScript 项目并确保一致性。

要调用代码检查器检查您的项目,您可以运行 lint 目标。

Terminal window
pnpm nx lint <project-name>

大多数代码检查或格式化问题可以通过使用 --configuration=fix 参数运行来自动修复。

Terminal window
pnpm nx lint <project-name> --configuration=fix

同样,如果您想修复工作区中所有包的所有代码检查问题,您可以运行:

Terminal window
pnpm nx run-many --target lint --all --configuration=fix

为了避免代码检查问题在开发过程中拖慢您的速度(特别是如果您的项目中有无法自动修复的问题),您可以使用 skip-lint 配置运行构建:

Terminal window
pnpm nx run-many --target build --configuration=skip-lint

这会在构建期间完全跳过代码检查目标。