Зависимости между Typescript проектами (в пределах одного репо)

У меня есть серия проектов Typescript (каждая из которых является реальной компиляционной целью, с ее собственным tsconfig.json). Они являются каталогами сестер в одном репозитории кода, например:

myrepo
--/common
--/project1
--/project2

Чтобы разделить код между project1 и project2, я разделил код с общим кодом на common. Я хотел бы разрешить project1 и project2 код для импорта классов из common, но не друг от друга (и common не сможет импортировать классы из двух других).

В идеале код в project1 может выглядеть следующим образом:

import {CommonClass} from 'common/commonclass';

Я нашел способ разрешить импорту работать правильно, поместив его в tsconfig.json из project1:

  "baseUrl":".",
  "paths":{
    "*":["*","../*"]
  }

Однако я еще не нашел способа ограничить, какой из других подпроектов может быть предметом import. Я попытался использовать rootDirs, надеясь, что он ограничит допустимые исходные файлы тем же способом, что и rootDir, но на самом деле этого не делает.

Как я могу настроить белый список того, какой код является импортируемым в каждом из моих проектов? Или есть только лучший способ создания подпроектов в Typescript, о котором я не знаю?

Ответ 1

Мне также пришлось иметь дело с подобной структурой и не мог найти идеальный способ сделать это.
Лучшее, что мне удалось найти, - это иметь каталог lib в project1 и project2, который содержит скомпилированный common вместе с файлами определения.

Я использовал gulp для сборки проекта common в разных каталогах projectX/lib:

gulp.task("common-project1", function () {
    var tsProject = ts.createProject("common/tsconfig.json");

    return tsProject.src("common/**/*.ts")
        .pipe(tsProject())
        .pipe(gulp.dest("project1/lib/common"));
});

Это не лучшее решение, потому что оно требует, чтобы вы запускали эту задачу gulp каждый раз, когда вы меняете источник common, но я обнаружил, что это происходит не так часто, как только common достаточно стабилен.

Ответ 2

Вы можете использовать опцию noResolve компилятора в tsconfig.json, см. Параметры компилятора.

Например: в вашем проекте2/tsconfig.json вы можете установить noResolve в значение true и указать все необходимые пути в include

// project2/tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noResolve": true
    },
    "include": [
        "../common/**/*",
        "**/*"
    ]
}

С приведенными выше настройками TypeScript предупредит вас о неправильном вводе ProjectUtil1:

// project2/ProjectUtil2.ts

import ProjectUtil1 from "../project1/ProjectUtil1";    // TypeScript error
import StringUtil from "../common/StringUtil";

export class ProjectUtil2 {

    static formatOutput(text: string) {
        return "Project 2: " + ProjectUtil1.formatOutput(text);
    }
}

export default ProjectUtil2;