iT邦幫忙

0

[紀錄] Angular+Nest新專案建立,踩坑分享

*資料夾結構*

― [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 是一對一的情況:

  1. 到 ./backend/src/main.ts ,
    提供 Angular build完以後的靜態檔案,如下:
...
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.useStaticAssets(join(__dirname, '../../frontend/dist/frontend'));
...
  1. 用 nest cli 產生 middleware,如下(參1):
$ nest g mi frontend
  1. 到 ./backend/src/frontend.middleware.ts(參2),
...
  use(req: any, res: any, next: () => void) {
     res.sendFile(path.resolve('../frontend/dist/frontend/index.html'))
  }
...
  1. 到 ./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
        },
      );
  }
}
  1. 用 VS Code(免費)開 檢視 > 終端機(Terminal),
    開始專案的開發。
// terminal for Nest
$ cd backend
$ npm run start:dev

// 新增 Terminal window
// terminal for Angular
$ cd frontend
$ ng build --watch

如果 Angular與 Nest 是多對一的情況:

  1. 到 ./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'});
...
  1. (同上):

  2. 到 ./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'))
  }
...
  1. (同上)

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 },
  ]},
];
...
  1. 用 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)
專案剛開始,
日後踩坑了還記得的話再回來補,
有任何問題或是說錯的地方,
歡迎大神們多多指教。


特別感謝:
CK大大: https://www.facebook.com/CKNotepad/
(提供思路解決多 client對一 server )

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


尚未有邦友留言

立即登入留言