*資料夾結構*
― [project name]
└ frontend
└ web
└ mobile(pwa)
└ backend
會這樣命名跟(推1)有關。
*技術選擇*
Angular + ngrx
Apollo
Nest.js + GraphQL
Rxjs
MongoDB
最放會放到 Google App Engine
原本想過用一個 Angular專案,
Web, Mobile用 Module 並 rouer + lazy loading
這樣能最大化共用 node_modules, ngrx …
但考慮到案子的發展與維護,
第一次嘗試以 兩個 Angular專案包一個Nest,
踩了坑來寫點紀錄。
如果 Angular與 Nest 是一對一的情況:
- 到 ./backend/src/main.ts ,
提供 Angular build完以後的靜態檔案,如下:
...
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '../../frontend/dist/frontend'));
...
- 用 nest cli 產生 middleware,如下(參1):
$ nest g mi frontend
- 到 ./backend/src/frontend.middleware.ts(參2),
...
use(req: any, res: any, next: () => void) {
res.sendFile(path.resolve('../frontend/dist/frontend/index.html'))
}
...
- 到 ./backend/src/app.module.ts註冊(參3),
...
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(FrontendMiddleware)
.forRoutes(
{
path: '/**', // For all routes
method: RequestMethod.ALL, // For all methods
},
);
}
}
- 用 VS Code(免費)開 檢視 > 終端機(Terminal),
開始專案的開發。
// terminal for Nest
$ cd backend
$ npm run start:dev
// 新增 Terminal window
// terminal for Angular
$ cd frontend
$ ng build --watch
如果 Angular與 Nest 是多對一的情況:
- 到 ./backend/src/main.ts ,
提供 Angular build完以後的靜態檔案,
這次要加個 prefix作為前綴,如下(參4):
...
const app = await NestFactory.create<NestExpressApplication>(AppModule);
app.useStaticAssets(join(__dirname, '../../frontend/web/dist/web'),{prefix:'/web'});
app.useStaticAssets(join(__dirname, '../../frontend/mobile/dist/mobile'),{prefix:'/mobile'});
...
-
(同上):
-
到 ./backend/src/frontend.middleware.ts,
根據 request的 url切換載入的專案切入點。
...
use(req: any, res: any, next: () => void) {
if (req['url'].includes('web'))
res.sendFile(path.resolve('../frontend/web/dist/web/index.html'))
else if (req['url'].includes('mobile'))
res.sendFile(path.resolve('../frontend/mobile/dist/mobile/index.html'))
}
...
- (同上)
5. 這步很重要!試了很久!
到 ./frontend/web/src/index.html,
及 ./frontend/mobile/src/index.html,
...
// 找到base tag
// 把"絕對路徑"改成"相對路徑"
// 把 href="/" 改成 href="./" 如下:
<base href="./">
...
這時要注意
在 Angular routes使用上有幾個要注意的點,
假設有個網址:http://localhost:3000/order/3
那在 app-routing.module.ts中原本應該如下:
...
const routes: Routes = [
{ path: 'order/:id', component: OrderComponent },
];
...
因為 index.html被改成相對路徑加上 nest用的 prefix,
所以我們把上面的程式碼稍微改一下,如下:
...
const routes: Routes = [
{ path: ':id', component: OrderComponent },
];
...
你可以這樣理解,
...
const routes: Routes = [
{ path: '', component: AppComponent, childern:[
{ path: ':id', component: OrderComponent },
]},
];
...
- 用 VS Code(免費)開 Terminal,
開始專案的開發。
// terminal for Nest
$ cd backend
$ npm run start:dev
// 新增 Terminal window
// 分割 Terminal window
// terminal for Angular
$ cd frontend/web
$ ng build --watch
$ cd frontend/mobile
$ ng build --watch
(2019/09/24)
專案剛開始,
日後踩坑了還記得的話再回來補,
有任何問題歡迎大神們多多指教。
VS Code插件推薦:
(1) Material Icon Theme:https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme
參考資料:
(1) nest cli: https://docs.nestjs.com/cli/usages
(2) nest middleware: https://docs.nestjs.com/middleware
(3) nest MVC: https://docs.nestjs.com/techniques/mvc
(4) mutiple static with Nest: https://stackoverflow.com/questions/54475802/setup-two-different-static-folders-with-nest
(5) redirect Angular routes in Nest: https://stackoverflow.com/questions/54838260/how-to-redirect-all-routes-to-index-html-angular-in-nest-js/54840961#54840961預先格式化文字