我在 Nx monorepo 中使用 Angular 和 PHP(Yii 框架),两者都可以正常工作。不知道 Lerna 和 Turborepo 是如何工作的,但是 Nx 允许运行 CLI 命令,我将它用于 PHP 部分。我的 monorepo 看起来有点如下:
- apps // <- folder holding my projects
--- project-1
--- project-2
------ web // <- Main frontend app (Angular/JS)
------ electron // <- other JS apps like mobile, capacitor, extension, ...
------ api // <- PHP api overridden config files
- libs
--- web // <- shared JS stuff, most people call it 'shared' folder instead
------ ui // <- my shared design system
--- electron
--- project-2 // <- specific project overrides and locally shared stuff
------ services
------ data-access
------ ui
--------- button // <- overriding a component from my design system to only apply in project-2
------ api // <- PHP api but only holding overridden files
--- php
------ api // <- shared PHP api code
------ auth // <- another shared PHP app
------ shell // <- another shared PHP app
- dist // <- is where NX will will put all generated code from all apps/libs
主要思想是,我编写的每个代码都放在 libs 文件夹和生成的 Nx 库中。所以它有一个名字(比如php-api)可以从任何地方链接它,还有一个project.json 文件保存Nx 配置。
这是我的共享代码。为任何需要它的项目编写一次。
libs/project-2 将保存 project-2 特定代码。仅在该应用页面内共享的内容以及我从上一个共享层覆盖的内容,例如上面的按钮示例。
apps 中的代码尽可能小,主要是布局和配置。这几乎就是大多数 Nx 文档/教程所建议的(对于 JS)。我对 PHP 也这样做:
- 我已将所有 Yii api 代码放入
libs/php/api
-
project-2 应用程序特有的所有内容(如模型、控制器等)文件夹和/或文件都包含在
libs/project-2/api 中
- 主配置文件(如 .env)进入
apps/project-2/api
- 每个 lib 文件夹都需要一个
project.json 文件来定义它:
{
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "library",
"sourceRoot": "libs/php/api",
"tags": ["scope:php", "type:api"]
}
-
在我的例子中,使用 Angular,在根级别有一个 angular.js 文件,我在其中声明了每个 PHP 库名称以便 Nx 检测到它,我只是添加了 2 行:"php-api": "libs/php/api" 和 "project-2-api": "libs/project-2/api",
-
在apps/project-2/api文件夹内,我添加了一个project.json文件,内容如下:
{
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"sourceRoot": "apps/project-2/api",
"prefix": "nx",
"targets": {
"build": {
"executor": "nx:run-commands",
"options": {
"commands": [
"mkdir -p dist/apps/project-2",
"cp -R libs/php/api dist/apps/project-2",
"cp -R libs/project-2/api dist/apps/project-2",
"cp -R apps/project-2/api dist/apps/project-2"
],
"parallel": false
}
},
"serve": {
"executor": "nx:run-commands",
"dependsOn": ["build"],
"options": {
"commands": ["php -S localhost:8081 -t dist/apps/project-2/api/web"]
}
}
},
"implicitDependencies": ["php-api"]
}
这定义了 build 和 serve 脚本,所以我可以使用 Nx cli 来运行它们,第一个只是将 PHP 文件复制到 dist 文件夹(尊重我的覆盖层次结构),而第二个使用 PHP 的内置服务器为最终文件夹提供服务:
> nx run project-2-api:build
> nx run project-2-api:serve
所以主要的想法是,我的大部分代码只编写一次,在需要时覆盖,一个单一的设计系统我只覆盖它的 CSS 以获得新应用程序的不同外观。我对 PHP 也这样做,即使不直接支持,我也只是使用 nx:run-commands 执行器来执行移动文件、实时构建或部署等操作。