构建TypeScript单体库项目的问题

14
我有一个相当简单的单库存储库,可以在GitLab上找到这里。它使用yarn工作区、TypeScript、Jest、ts-jest和ESLint与eslint-plugin-import
我正在尝试使用TypeScript正确构建项目包。以前,我只是将TypeScript文件与它们的JavaScript代码一起发布在同一个目录中。
我的构建项目的尝试在GitLab合并请求中可用这里 现在,仓库遵循以下布局:
 |- example/
 |   |- index.ts
 |   |- package.json
 |   `- tsconfig.json
 |- packages/
 |   |- koas-core/
 |   |   |- src/
 |   |   |   `- index.ts
 |   |   |- package.json
 |   |   `- tsconfig.json
 |   |- koas-status-code/
 |   |   |- src/
 |   |   |   `- index.ts
 |   |   |- package.json
 |   |   `- tsconfig.json
 |   `- more similar workspaces…
 |- package.json
 |- tsconfig.json
 `- more configuration files…

一些包彼此依赖。我已经成功地将Jest测试和eslint-plugin-import与此设置配合使用,但是我在构建项目时遇到了问题。

tsconfig.json的内容如下:

{
  "compilerOptions": {
    "baseUrl": ".",
    "composite": true,
    "declaration": true,
    "module": "commonjs",
    "noEmit": true,
    "resolveJsonModule": true,
    "target": "esnext",
    "paths": {
      "koas-*": ["packages/koas-*/src"]
    }
  },
  "exclude": ["**/*.test.ts"]
}

工作区的 tsconfig.json 文件如下所示:
{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "lib"
  }
}

每个工作区都在 `package.json` 中定义了一个名为 `prepack` 的脚本,如下所示:
{
  "scripts": {
    "prepack": "tsc --noEmit false"
  }
}

main字段是指向lib的。

如果我运行yarn workspace koas-status-code prepack,我会得到以下错误:

$ tsc --noEmit false
error TS6059: File 'koas/packages/koas-core/src/SchemaValidationError.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/SchemaValidationError.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createDefaultValidator.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createDefaultValidator.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createMatcher.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/createMatcher.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/index.ts' is not under 'rootDir' 'koas/packages/koas-status-code'. 'rootDir' is expected to contain all source files.

error TS6059: File 'koas/packages/koas-core/src/index.ts' is not under 'rootDir' 'koas/packages/koas-status-code/src'. 'rootDir' is expected to contain all source files.

error TS6307: File 'koas/packages/koas-core/src/SchemaValidationError.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.

error TS6307: File 'koas/packages/koas-core/src/createDefaultValidator.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.

error TS6307: File 'koas/packages/koas-core/src/createMatcher.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.

error TS6307: File 'koas/packages/koas-core/src/index.ts' is not listed within the file list of project 'koas/packages/koas-status-code/tsconfig.json'. Projects must list all files or use an 'include' pattern.


Found 12 errors.

我也尝试了这个tsconfig.json来使用koas-status-code:

{
  "extends": "../../tsconfig.json",
  "include": ["src"],
  "references": [{ "path": "../koas-core" }],
  "compilerOptions": {
    "outDir": "lib"
  }
}

这会构建工作区,但仍然会出现以下错误:
$ tsc --noEmit false
src/index.ts:1:23 - error TS6305: Output file '/home/remco/Projects/koas/packages/koas-core/lib/src/index.d.ts' has not been built from source file '/home/remco/Projects/koas/packages/koas-core/src/index.ts'.

1 import * as Koas from 'koas-core';
                        ~~~~~~~~~~~


Found 1 error.

我该如何修复这个问题?

1个回答

13

我已经找到了一个基于https://github.com/NiGhTTraX/lerna-ts的解决方案来解决这个问题。

该项目现在在项目根目录中包含一个名为tsconfig.build.json的文件。该文件指定编译器选项,并排除测试和构建文件以进行构建。

{
  "compilerOptions": {
    "declaration": true,
    "module": "commonjs",
    "resolveJsonModule": true,
    "target": "esnext"
  },
  "exclude": ["**/*.test.ts", "**/lib"]
}

根目录中的另一个文件是tsconfig.json。此文件用于构建过程之外的类型检查,例如由Jest和VSCode使用。此文件扩展了构建配置。它通过覆盖扩展的exclude配置来包含测试。它还包含noEmit: true,因为在开发时使用TypeScript的进程不应该发出任何内容。此外,它包含了编译器选项baseUrlpaths,这些选项需要在运行时解析TypeScript源文件。这是因为包的package.json文件中的main字段引用了包含输出文件的lib

{
  "extends": "./tsconfig.build.json",
  "compilerOptions": {
    "baseUrl": ".",
    "noEmit": true,
    "paths": {
      "koas-*": ["packages/koas-*/src"]
    }
  },
  "exclude": ["**/lib"]
}

每个工作区都包含一个tsconfig.build.json文件。这是必需的,因为它要求srcoutDir选项必须相对于tsconfig文件。它用于构建项目。重要的是这个文件不要命名为tsconfig.json

{
  "extends": "../../tsconfig.build.json",
  "include": ["src"],
  "compilerOptions": {
    "outDir": "lib"
  }
}

每个工作区也包含一个 tsconfig.json。这可以用于覆盖编译器选项以进行类型检查,例如,如果一个代码库将使用 dom typings,则可以省略此操作。

{
  "extends": "../../tsconfig.json"
}
每个工作区在package.json文件中都有以下scripts部分。这会导致在构建软件包时编译 TypeScript。
  // …
  "scripts": {
    "prepack": "tsc --project tsconfig.build.json"
  }

有两个CI作业用于类型检查。一个运行tsc来确保在开发中使用这些类型的工具仍然可以进行类型检查,另一个作业确保构建包不会出错。

tsc:
  script:
    - yarn --frozen-lockfile
    - yarn workspaces run tsc

pack:
  script:
    - yarn --frozen-lockfile
    - yarn workspaces run pack
    - find packages -name '*.tgz' -exec mv {} ./ +
  artifacts:
    name: packages
    paths:
      - '*.tgz'

感谢您认真地表达问题并记录答案!这个设置是否允许从父目录导入文件,超出了 "rootDir" 的范围?我无法弄清楚 TypeScript 在 Monorepo 中应该如何使用,其中 ModuleA 希望从 ../lib/Something 导入,除非您不使用 rootDiroutDir,并接受 .js.js.map 文件将随每个 .ts 文件一起出现,污染工作区。 - Dan Dascalescu
TypeScript 不允许你在根目录之外导入。如果你想在多个包之间使用代码,请为该代码创建一个独立的包,并将其添加为依赖项。 - Remco Haszing
是可能的,但是你的 rootDir 需要包含你正在导入的代码。唯一的缺点是 dist 中的代码结构有很多嵌套。 - RushPL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接