构建 TypeScript monorepo 项目时出现问题

Rem*_*ing 14 node.js typescript monorepo

我有一个相当简单的单声道存储库。它可以在 GitLab\n 上找到。这使用了纱线工作区、TypeScript、Jest、ts-jest\n和 ESLint 以及eslint-plugin-import.

\n\n

我正在尝试使用 TypeScript 正确构建项目包。以前我只是将 TypeScript 文件与 JavaScript 代码一起发布在同一目录中。

\n\n

我尝试构建项目可以在 GitLab 合并请求中找到\n此处

\n\n

现在存储库遵循以下布局:

\n\n
 |- example/\n |   |- index.ts\n |   |- package.json\n |   `- tsconfig.json\n |- packages/\n |   |- koas-core/\n |   |   |- src/\n |   |   |   `- index.ts\n |   |   |- package.json\n |   |   `- tsconfig.json\n |   |- koas-status-code/\n |   |   |- src/\n |   |   |   `- index.ts\n |   |   |- package.json\n |   |   `- tsconfig.json\n |   `- more similar workspaces\xe2\x80\xa6\n |- package.json\n |- tsconfig.json\n `- more configuration files\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

有些包相互依赖。我已成功进行 Jest 测试并eslint-plugin-import\n使用此设置,但我\xe2\x80\x99m 在构建项目时遇到问题。

\n\n

tsconfig.json看起来像这样:

\n\n
{\n  "compilerOptions": {\n    "baseUrl": ".",\n    "composite": true,\n    "declaration": true,\n    "module": "commonjs",\n    "noEmit": true,\n    "resolveJsonModule": true,\n    "target": "esnext",\n    "paths": {\n      "koas-*": ["packages/koas-*/src"]\n    }\n  },\n  "exclude": ["**/*.test.ts"]\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

工作区tsconfig.json文件如下所示:

\n\n
{\n  "extends": "../../tsconfig.json",\n  "compilerOptions": {\n    "rootDir": "src",\n    "outDir": "lib"\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

每个工作区都有一个prepack定义的脚本,package.json如下所示:

\n\n
{\n  "scripts": {\n    "prepack": "tsc --noEmit false"\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

main字段指的是lib.

\n\n

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

\n\n
$ tsc --noEmit false\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\nerror 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.\n\n\nFound 12 errors.\n
Run Code Online (Sandbox Code Playgroud)\n\n

我也尝试过tsconfig.json这个koas-status-code

\n\n
{\n  "extends": "../../tsconfig.json",\n  "include": ["src"],\n  "references": [{ "path": "../koas-core" }],\n  "compilerOptions": {\n    "outDir": "lib"\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这构建了工作区,但仍然给出以下错误:

\n\n
$ tsc --noEmit false\nsrc/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\'.\n\n1 import * as Koas from \'koas-core\';\n                        ~~~~~~~~~~~\n\n\nFound 1 error.\n
Run Code Online (Sandbox Code Playgroud)\n\n

我该如何解决?

\n

Rem*_*ing 13

我根据https://github.com/NiGhTTraX/lerna-ts找到了这个问题的解决方案。

\n

tsconfig.build.json该项目现在包含一个在项目根目录中调用的文件。该文件指定编译器选项,并且测试和构建文件应从构建过程中排除。

\n
{\n  "compilerOptions": {\n    "declaration": true,\n    "module": "commonjs",\n    "resolveJsonModule": true,\n    "target": "esnext"\n  },\n  "exclude": ["**/*.test.ts", "**/lib"]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
{\n  "extends": "./tsconfig.build.json",\n  "compilerOptions": {\n    "baseUrl": ".",\n    "noEmit": true,\n    "paths": {\n      "koas-*": ["packages/koas-*/src"]\n    }\n  },\n  "exclude": ["**/lib"]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
{\n  "extends": "../../tsconfig.build.json",\n  "include": ["src"],\n  "compilerOptions": {\n    "outDir": "lib"\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

每个工作区还包含一个tsconfig.json. 这可用于覆盖类型检查的编译器选项,例如,如果一个存储库将使用类型dom。这可以省略。

\n
{\n  "extends": "../../tsconfig.json"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

每个工作区都有以下scripts部分package.json。这会导致在构建包时编译 TypeScript。

\n
  // \xe2\x80\xa6\n  "scripts": {\n    "prepack": "tsc --project tsconfig.build.json"\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

有两个 CI 作业用于类型检查。一个运行是tsc为了确保类型检查在开发中使用这些类型的工具中仍然有效,另一个运行是确保构建包不会\xe2\x80\x99 中断。

\n
tsc:\n  script:\n    - yarn --frozen-lockfile\n    - yarn workspaces run tsc\n\npack:\n  script:\n    - yarn --frozen-lockfile\n    - yarn workspaces run pack\n    - find packages -name \'*.tgz\' -exec mv {} ./ +\n  artifacts:\n    name: packages\n    paths:\n      - \'*.tgz\'\n
Run Code Online (Sandbox Code Playgroud)\n