跳转到内容

TypeScript 项目

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

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

  1. 安装 Nx Console VSCode Plugin 如果您尚未安装
  2. 在VSCode中打开Nx控制台
  3. 点击 Generate (UI) 在"Common Nx Commands"部分
  4. 搜索 @aws/nx-plugin - ts#project
  5. 填写必需参数
    • 点击 Generate
    参数类型默认值描述
    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';

    项目的入口点是src/index.ts。您可以在此处添加需要被其他项目导入的导出:

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

    工作区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.jsontargetDefaults.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 中关闭 lint 规则:

    biome.json
    {
    "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 文件如下:

    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 中),您可以通过以下方式运行:

    Terminal window
    pnpm nx build <project-name>

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

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

    构建输出可以在工作区根目录的 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

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

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

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

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

    这会在构建期间完全跳过lint目标。