Angular の SSG, scullyを追加、運用する。

2021/05/06

Angular

Scully

既存のAngular プロジェクトに追加する

ng add @scullyio/init

いくつかのファイル、フォルダ、package.jsonの更新がされる

...
├── scully
│   ├── plugins
│   │   └── plugin.ts
│   └── tsconfig.json
├── scully.karaage-ng-site.config.ts
...
  ...
  "scripts": {
    ...
+    "scully": "npx scully --",
+    "scully:serve": "npx scully serve --"
  },
  "dependencies": {
+    "@scullyio/init": "^1.1.4",
+    "@scullyio/ng-lib": "^1.0.0",
+    "@scullyio/scully": "^1.0.0",
  },
  ...

とりあえず実行

ng build --prod
npm run scully

ビルドされた成果物からレンダリングを行い静的ファイルを生成するっぽい。ルーティングの設定などしていないのでトップのページしかレンダリングされたHTMLがないっぽい。

routingを追加

scully.<project-name>.config.ts を編集する。
extraRoutes の項目で追加したページはプリレンダリングされる。 また今回は動的な値じゃないのでゴリゴリして適当にやったけどAPI等から取得してレンダリングする方法もある。

Unhandled routes
Handled routes


import * as fs from 'fs'
let items:any[] = JSON.parse(fs.readFileSync("path/all.json",'utf8'));

export const config: ScullyConfig = {
  ...
  extraRoutes: items.map((v)=> "/article/" + v.path)
  ...
};

TransferStateService

https://scully.io/docs/Reference/ngLib/transfer-state-service/

scullyではレンダリングされた静的ファイルからSPAのアプリケーションが立ち上がる。
その際、レンダリングで使用したAPIなどのデータをアプリケーションに渡すことができる。

import { HttpClient } from '@angular/common/http';
import { TransferStateService } from '@scullyio/ng-lib';

@Injectable({
  ...
})
export class ... {

  constructor(
    private httpClient: HttpClient,
    private transferStateService:TransferStateService
  ) { }

  getURLDataToResponseTypeText(URL:string): Observable<string>{
    return this.transferStateService.useScullyTransferState(
      URL,
      this.httpClient.get(URL,{
        responseType: "text"
      })
    );
  };
}