目前的 NestJS 项目文件夹结构
libs 中的
// main.js
async function bootstrap () {
const admin = await NestFactory.create(AdminModule)
const app = await NestFactory.create(AppModule)
await Promise.all([
admin.init(),
app.init(),
])
await Promise.all([
admin.listen(3000),
app.listen(3001),
])
}
发帖前也搜过这个需求,nestjs 的 github issue 也有类似的需求,但都被关闭了和不可用
// 需要改成这样
// main.ts
async function bootstrap () {
const server = express()
const appFactory = new NestFactoryStatic()
const app = await apiFactory.create(AppModule, new ExpressAdapter(server))
app.setGlobalPrefix('/app')
await app.init()
const adminFactory = new NestFactoryStatic()
const admin = await adminFactory.create(AdminModule, new ExpressAdapter(server))
admin.setGlobalPrefix('/admin')
await admin.init()
http.createServer(server).listen(3000)
}
我尝试过了,admin 会覆盖掉 app 的路由,失败
搜到一个nest-router,但最后 commit 是 12 个月前,我就没尝试
有没有 NestJS 大佬指教一下该怎么实现
nestjs 官方是不是不推荐这样弄?不然应该很容易实现的。
1
gzlock OP @Livid node.js 的分区主题会导致 markdown 代码区域的文字出现黑色背景哎
用“```ts”和“```typescript”开头都试过了,还是一样的效果 |
4
noe132 2020-06-25 09:05:44 +08:00
老哥你是不是误入歧途了。。
Controller 类的 decorator 可以设置 url prefix 的 https://docs.nestjs.com/controllers 建议把 nest 文档看一看 |
5
gzlock OP 我知道的,但我不能将 /app/* 下的所有接口都放在一个 controller 下吧
想把例如 /app/user/*相关的放在一个 module 里 那这个 module controller 的 path 是不是需要写绝对路径为 /app/user ? @noe132 |
6
noe132 2020-06-25 10:03:27 +08:00
|
7
B3C933r4qRb1HyrL 2020-06-25 10:23:05 +08:00
@gzlock
1. AppModule 通过 setGlobalPrefix('/app'),这样 AppModule 路由就是 /app 了 2.UserModule 里的 Controller 装饰器 @Controller('user') 3.AppModule 里 Import UserModule 这样 UserController 下的路由都是 /app/user/xx 了。 path 不需要写绝对路径。 不知道这样有没有解决你的问题。 |
8
B3C933r4qRb1HyrL 2020-06-25 10:28:26 +08:00
如果不希望 api 是 /app/api,/app/admin 开头的话,app.setGlobalPrefix('/'),然后 appmodule 里引入其他子模块。
比如 user module 里 @Controller('user'),那路径就是 host/user |
9
B3C933r4qRb1HyrL 2020-06-25 10:30:17 +08:00
|
10
FakerLeung 2020-06-25 10:30:23 +08:00
@gzlock #5
不用吧。 我现在的接口是 /app1/xxx/yyy /app2/xxx/yyy app1 和 app2 都是两个独立的 module 。 而且 app1 下又有 xxx,yyy,zzz 三个 module,这 3 个 module 也是独立出去的。只是每个 controller 又要再写一次 /app1/xxx 这样,感觉麻烦。 |
11
gzlock OP @FakerLeung #10
@cuvii #7 不使用 library 分开两种逻辑的话,admin 的 module 和 app 的 module 都挤在一个 src 文件夹里,会不会弄得 module 文件夹数量很庞大,也难以查找呢? |
12
B3C933r4qRb1HyrL 2020-06-25 16:35:43 +08:00
@gzlock 前面讲的可能有点乱,因为 nest.js 默认的 module 就是 app module 。
你实际上是可以直接创建一个新的 module,例如 main module 来作为容器 module 。 ``` const main = await NestFactory.create(MainModule); main.setGlobalPrefix('/'); ``` 然后 admin 的逻辑写在 admin module 里,app 的逻辑写在 app module 里,然后把这两个 module 导入到 main module 里就可以了。 至于你说的 module 文件夹数量庞大,我觉得这就看你自己怎么处理文件夹结构了,用 cli 生成的 module 是默认都在 src 下的,你可以根据业务逻辑把 module 放到对应的功能模块下去。 |
13
gzlock OP @FakerLeung #10
@cuvii #12 刚刚实践了一下 https://github.com/gzlock/nest_js 的确每个 controller 都需要写绝对路径😓,如果可以支持相对路径就真的完美了 不过也解决了需要开两个单独 application 的问题 |
14
FakerLeung 2020-06-25 17:46:33 +08:00
@gzlock #13
对的,确实需要写绝对路径,我也在想如何才能在一个顶部的 module 中,写好了 prefix,下面的所有 module 中的所有 controller 都能继承这个 prefix 。 |
15
B3C933r4qRb1HyrL 2020-06-25 17:52:40 +08:00
@gzlock 好吧,路由这块可能我的理解有问题,你可以看看 https://github.com/nestjsx/nest-router,不知道能不能解决你的问题,我个人感觉用 router 会更麻烦一点...
|
16
gzlock OP @FakerLeung #14 官方 issue 好像有讨论过这个问题,有人说因为 module 有可能被其他 module 引用所以 module 不适合放 path 参数
|
17
FakerLeung 2020-06-25 22:33:17 +08:00
@gzlock #16
谁说都有道理。 |
18
kid740246048 2020-06-26 08:55:48 +08:00 via Android
关注一波,我也觉得在 module 里面写死绝对路径不方便复用
|
19
rikka 2020-11-03 15:05:36 +08:00 2
遇到同样的问题,搜到这帖,然后自己看了看源码,解决如下
加个装饰器函数 //set-module-prefix.decorator.ts ```ts import { PATH_METADATA, MODULE_METADATA } from '@nestjs/common/constants' const { IMPORTS, CONTROLLERS } = MODULE_METADATA function resolveController (target, controllers = []) { controllers.push(...(Reflect.getMetadata(CONTROLLERS, target) ?? [])) const imports = Reflect.getMetadata(IMPORTS, target) if (imports) { imports.forEach(module => { resolveController(module, controllers) }) } return controllers } export function setModulePrefix (prefix:string) { return target => { resolveController(target).forEach(controller => { const path = Reflect.getMetadata(PATH_METADATA, controller) if (path) { Reflect.defineMetadata(PATH_METADATA, prefix + '/' + path, controller) } }) } } ```` 使用,这样就自动给 AdminModule 下的所有控制器加上`admin`这个前缀了 ```ts import { Module } from '@nestjs/common' import { AdminController } from './controllers/admin.controller' import { setModulePrefix } from '../decorators/set-module-prefix.decorator' @setModulePrefix('admin') @Module({ imports: [ ], controllers: [ AdminController, ], providers: [ ], }) export class AdminModule {} ``` |
20
cgyrock 2023-07-04 14:55:54 +08:00
管理端 admin 和 C 端 customer 分别创建一个应用,可以独立启动,然后创建一个 monoapp 应用,导入这两个应用的根模块。两个应用的跟模块使用动态模块,接收一个 context 参数作为统一前缀,用官方的 RouteModule 来为所有子模块添加统一前缀
monoapp: http://picbed.catfoodworks.com/WechatIMG522.jpeg admin: http://picbed.catfoodworks.com/WechatIMG523.jpeg |