Monorepo с `rootDirs` создает нежелательные каталоги, такие как` src` в `outDir` - PullRequest
1 голос
/ 28 марта 2020

Я планирую монорепозиционный машинописный фрагмент, как показано ниже:

/ (root)
+--backend/
|  +-src/
|  \-tsconfig.json
+--shared/
|  \-src/
\--frontend/
   \-src/

tsconfig.json определяется как показано ниже:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "baseUrl": "./src",
    "paths": {
      "shared": [
        "../../shared/src"
      ]
    },
    "rootDirs": [
      "./src",
      "../shared/src"
    ],
    "esModuleInterop": true
  }
}

Когда я выполняю tsc в backend it дает мне, как показано ниже:

/ (root)
+-backend/
  +-dist/
  | +-backend/
  | | +-src/
  | \-shared/
  |   \-src/
  +-src/
  \-tsconfig.json

В приведенном выше, dist содержит backend и shared НО каждый из них содержит src под ним. Я хотел, чтобы backend и shared в dist содержали скомпилированные JS файлы без src:

/ (root)
+-backend/
  +-dist/
  | +-backend/
  | \-shared/
  +-src/
  \-tsconfig.json

Возможно ли это? И как мне это сделать?

1 Ответ

0 голосов
/ 30 апреля 2020

диагноз

  • Typescript использует rootDir (не rootDirs) для определения структуры каталогов вывода (см. этот комментарий от начальника Typescript ).
  • Когда вы установите несколько rootDirs, tsc найдет родительский каталог, общий для всех из них, и обработает , что a rootDir. Вот почему вы получаете структуру outDir, которую вы получаете.

рецепт: Структурирование вашего монорепо как отдельных подпроектов Typescript

A Проект Typescript определяется файлом tsconfig, самодостаточен и эффективно ограничен его rootDir. Это очень хорошая вещь, так как она соответствует принципам инкапсуляции .

Вы можете иметь несколько проектов (например, основной и набор библиотек) каждый в своем собственном каталоге с помощью их собственный tsconfig, со своими rootDir. Зависимости между ними управляются в файлах tsconfig с использованием Typescript Project References .

К сожалению, люди Typescript выбрали термин «проекты», поскольку интуитивно он относится ко всему шебангу, но «модули» и «пакеты» уже были заняты. Но если вы думаете о них как о подпроектах , и это будет иметь гораздо больше смысла.

Но я рекомендую вам структурировать репо следующим образом:

.
├── dist
└── src
    ├── tsconfig.json
    ├── shared
    │   ├── index.ts
    │   └── tsconfig.json
    ├── backend
    │   ├── index.ts
    │   └── tsconfig.json
    └── frontend
        ├── index.ts
        └── tsconfig.json 

Чтобы при компиляции кода вы получили:

.
├── dist
│   ├── shared
│   ├── backend
│   └── frontend
└── src

Пример tsconfigs

  • src/tsconfig.json

    Даже если у вас нет кода на root, этот tsconfig может быть там, где все общие настройки go (остальные наследуют от него), и он позволит просто tsc --build src построить весь проект (и с --force, чтобы построить его с нуля).

    {
      "compilerOptions": {
        "rootDir": ".",
        "outDir": "../dist/",
      },
      "files": [],
      "references": [
        { "path": "./shared" },
        { "path": "./backend" },
        { "path": "./frontend" }
      ]
    }
    
    • src/shared/tsconfig.json

      shared не будет импортировать другие проекты, так как не имеет ссылок. Все, что он импортирует, ограничено его каталогом и зависимостями, перечисленными в package.json. Я полагаю, что вы могли бы даже ограничить последнее, задав ему свой собственный package.json.

      {
        "compilerOptions": {
          "rootDir": ".",
          "outDir": "../../dist/shared",
          "composite": true
        }
      }
      
    • src/backend/tsconfig.json

      backend может импортировать shared из-за объявленной ссылки.

      {
        "compilerOptions": {
          "rootDir": ".",
          "outDir": "../../dist/backend",
          "composite": true
        },
        "references": [
          { "path": "../shared" }
        ]
      }
      
    • src/frontend/tsconfig.json

      внешний интерфейс может импортировать общий И внешний интерфейс из-за объявленных ссылок.

      {
        "compilerOptions": {
          "rootDir": ".",
          "outDir": "../../dist/frontend",
          "composite": true
        },
        "references": [
          { "path": "../shared" },
          { "path": "../backend" }
        ]
      }
      

Пример команд сборки

tsc --build src создаст все дерево sr c

tsc --build src/backend создаст бэкэнд И разделяемый (если есть были изменения с момента последней сборки.

...