假设我有这个 monorepo:
/apps
/apps/app1
/apps/app1/src (contains index.ts and many other files and subfolders here)
/apps/app1/tsconfig.json
/apps/app1/package.json
/apps/app2
/apps/app2/src (contains index.ts and many other files and subfolders here)
/apps/app2/tsconfig.json
/apps/app2/package.json
/common
/common/package1
/common/package1/src
/common/package1/src/utility1.ts
/common/package1/src/utility2.ts
/common/package1/tsconfig.json
/common/package1/package.json
/tsconfig.json
/package.json
我只需要 esm 就可以在其中工作。
如何让 tsx、tsc 或任何其他 ts 工具运行一个或多个使用“common/*/src”中内容的应用程序?基本上不需要将“common”中的内容构建到 dist 文件夹中。
因此,每次我对
/common
中的文件进行更改时,当我在监视模式下运行应用程序时,它们都会立即生效。
首先在
monorepo
的根文件夹中,尝试运行 npm init -y
创建一个 package.json
文件,并通过运行 TypeScript
将 ts-node
和 dev
安装为 npm install --save-dev typescript ts-node
依赖项,然后再次在根文件夹,创建一个包含以下内容的 tsconfig.json
文件:
{
"compilerOptions": {
"module": "es2020",
"resolveJsonModule": true,
"esModuleInterop": true,
"rootDir": ".",
"outDir": "./dist"
},
"include": [
"apps/*/src",
"common/*/src"
]
}
现在在每个应用程序的文件夹(
/apps/app1
和/apps/app2
)中,像这样更新tsconfig.json
:
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"jsx": "react-jsx"
},
"include": [
"src"
]
}
并在每个应用程序的文件夹(
/apps/app1
和/apps/app2
)中,更新package.json
,然后尝试运行npm start
以在每个应用程序的文件夹的监视模式下启动应用程序:
{
"scripts": {
"start": "ts-node src/index.ts"
}
}
最后,对
/common
中的文件所做的任何更改都会在运行应用程序时立即生效!
不幸的是,在 Windows 上没有对文件夹链接的简单支持,而无需手动输入一些命令。
在 Linux 上,我可以轻松地将其他存储库中的整个文件夹显示为当前存储库的一部分,而无需构建所有内容。这是唯一可以轻松工作的方法,因为所有类型的路径映射、别名等都无法正常工作。如果它们在网络上正常工作,那么您在单元测试中就会遇到问题,反之亦然。此外,路径映射也可能会破坏源映射,导致调试噩梦。
但是,一旦包裹变大,就不建议采用这种方法。
一个真正的问题是导入路径映射。所有路径都变得相对,移动它们成为问题。
如果要在多个应用程序之间共享,建议使用单独的包。原因是更改和单元测试可以被抽象出来以专注于组件开发。
单独的包将始终具有完全限定的模块路径与相对路径。这样可以轻松复制和管理多个包。
我不认为 monorepo 能解决所有问题。 monorepo 的目的是减少部署依赖性。 Mono 存储库应该有一个构建和部署脚本。依赖的 npm 包始终可以集成到单个构建/部署脚本的部署中。
组件应该存在于 monorepo 之外,随着代码库的增长,您将意识到组件将用于许多不同的 monorepo。例如,您正在为一个客户构建一个会计软件,整个会计应该是一个单一的存储库。以及另一个客户的社交网络。两者都将您的可重用组件作为来自某个注册表的依赖项。
现在为所有客户和所有项目制作一个单一的单一存储库并不是一个好的解决方案。