Я предлагаю использовать линтер для этой работы, не нужно настраивать шаг сборки или использовать Project References.
eslint-plugin-import
- довольно популярный плагин ESLint, совместимый с TS и можешь делать что хочешь. После настройки typcript-eslint (если это еще не сделано) вы можете поиграться с этими правилами:
Попробуем использовать следующую структуру проекта:
| .eslintrc.js
| package.json
| tsconfig.json
\---src
+---common
| common.ts
|
+---projectA
| a.ts
|
\---projectB
b.ts
.eslintr c. js:
module.exports = {
extends: ["plugin:import/typescript"],
parser: "@typescript-eslint/parser",
parserOptions: {
sourceType: "module",
project: "./tsconfig.json",
},
plugins: ["@typescript-eslint", "import"],
rules: {
"import/no-restricted-paths": [
"error",
{
basePath: "./src",
zones: [
// disallow import from projectB in common
{ target: "./common", from: "./projectB" },
// disallow import from projectB in projectA
{ target: "./projectA", from: "./projectB" },
],
},
],
"import/no-relative-parent-imports": "error",
},
};
Каждая зона состоит из target path и из path. Цель - это путь, по которому должен применяться ограниченный импорт. Путь from определяет папку, которую нельзя использовать при импорте.
Просмотр файла ./src/common/common.ts
:
import { a } from "../projectA/a"; // works
// Error: Unexpected path "../projectB/b" imported in restricted zone.
import { b } from "../projectB/b";
Правило import/no-relative-parent-imports
также жалуется на оба импорта, как для a.ts
:
Относительный импорт из родительских каталогов не разрешен. Пожалуйста, либо передайте то, что вы импортируете во время выполнения (внедрение зависимости), переместите common.ts
в тот же каталог, что и ../projectA/a
, или рассмотрите возможность создания ../projectA/a
пакета.
Третье правило import/no-internal-modules
не использовался, но я также перечислю его здесь, так как это может быть очень полезно для ограничения доступа к дочерним папкам / модулям и эмуляции (по крайней мере) какого-то внутреннего модификатора пакета в TS.