GitHub Pages でメディアサイト？を公開するまで

## やったこと
GitHub Pages でメディアサイト？を公開した

## 前提
- デプロイ先はGitHub Pages
  - ただなので。
- 記事はマークダウンで書く
  - 他のサイトにもそのまま乗っけたいので。
- app.component.html styles.scss は最小限しか記載しない
  - 色々なスタイルのページをためしたいので。
- `ng new`したアプリをデプロイまでできてる。詳細は↓

https://qiita.com/magurouhiru/items/e820dbd2a6305b065449

## 1. 最初の想定
デプロイ先がGitHub Pages なのでDB とか使えない。
Angular ではpublic フォルダ（正確にはangular.json のprojects.yourprojectname.architect.build.options.assetsで記載の場所）
にあるファイルはそのままらしい。
なので、そこに.mdファイルを置いて都度読み取りに行けばいけるんじゃね？
じゃあ、普通にcomponent とservice 作ればOKじゃね？
強いて言えば.mdファイルをhtmlに埋め込むやり方が分からないけど、調べればいけるっしょ？

## 2. service 作成
普通に作ろうと思ったけど...そういえば.mdファイルの取得先URLはどうしよう？
ローカルとデプロイ先で変わるくない？

調べたらenvironment.tsなるものが過去にはあったらしい。
今はないけど`ng generate environments`でファイルができるのでそれを使えばOK。
やってみたらsrcフォルダの下にenvironmentsフォルダができて↓の2ファイルができてた。
- environment.development.ts
- environment.ts
あとangular.json も↓のように変わってた。
```aiignore
            "development": {
              "optimization": false,
              "extractLicenses": false,
              "sourceMap": true,
              "fileReplacements": [                                         ← New!
                {                                                           ← New!
                  "replace": "src/environments/environment.ts",             ← New!
                  "with": "src/environments/environment.development.ts"     ← New!
                }                                                           ← New!
              ]                                                             ← New!
            }
```
開発時とビルド時で勝手にファイルを変えてくれるのかな？

あとは普通に進めてたが、ちょっとつまずいたとこがあった。
HttpClient のオプションです。
最初は丸ごと定数にしてたが、コンパイルエラーが起きた。
```aiignore
  getArticle(articleName: string) {
    return this.#http
      .get(`${this.#articleRootUrl}${articleName}/${articleName}.md`, #options)
      .pipe(tap((x) => console.log(x)));
  }
```
そして定数じゃなく引数に直接記述したらうまくいった。
どうやら↓でさしてるとこの文字列ごとにgetメソッドが定義されてて、変数だとどのメソッドかコンパイラーが判別できなかったのかな？
```aiignore
  getArticle(articleName: string) {
    return this.#http
      .get(`${this.#articleRootUrl}${articleName}/${articleName}.md`, {
        headers: this.#headers,
        responseType: 'text',       ←ここ
      })
      .pipe(tap((x) => console.log(x)));
  }
```

## 3. component 作成
普通に作成。
だけど.mdファイルはそのままだとだめだった。（あたりまえ）
![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/ed3e7bcb-be7c-9351-42f4-b5b45c38a664.png)


なんかうまいこと埋め込めたり変換できたりしないかな？

調べてたら↓が出てきた。
https://qiita.com/tronicboy/items/56c44707226875bfc13b

pipeにするのは目から鱗だった。
けど最後のほうにサニタイズが必要とあり、MarkedのREADME.mdにも同様のことが書いてあった。
https://github.com/markedjs/marked

せっかくだからpipe作りたかったけど、ちょっと怖いからやめようと思った。
（そもそも静的サイトでXSSとかあるのかな？知識がないだけかも？）

もう少し調べたら↓が出てきた。
https://github.com/jfcere/ngx-markdown

こっちもREADME.mdを見る分にはリッチになった感じかな？
デフォルトでサニタイズしてくれるし、★が1.1kあるしこっちにしようと思った。
NullInjectionErrorがでたけど、↓みてapp.config.tsに追加したら直った。
（ここら辺まだよくわかってない。どこでいるいらない判断するのだろう？）
https://github.com/jfcere/ngx-markdown/issues/509#issue-2213418173

そして結果は...
うまくいきました!
![3-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/f0eaf39e-523f-2b86-6a0a-7fba33f49494.png)
そして試しに`<script>alert("hogehoge")</script>`を入れたらちゃんと消えてしかも警告が出てる。
安心。

あとは見た目とか整えるだけ。

## 4. style 作成
調べながらやっていたが、早速躓いた。
画像のサイズの変え方がわからない。
というのも、画像含む.md部分は`<div markdown [data]="articles[0].article"></div>`で出力している。
つまり、子コンポーネントであり、通常ならグローバルなstyles.scssファイルに記述するしかない。
PrimeNGならstyleclassに渡せばよいのだが似たようなものはないし...

調べたら↓を見つけた。本当にありがたい。
https://qiita.com/fcijpbgiec-ib/items/9d72e66eed12d519b0bb

どうやら`:host`と非推奨の`::ng-deep`を組み合わせれば子コンポーネントのスタイルを変更できるようだ。
あとは...正直いろいろ大変だったことがあった気がするが、力尽きたのでこの記事としてはいったんここまで。
（そのうちスタイルメインの記事を書く気持ちでいるのでその時ということで。）

## 5. デプロイ
さーデプロイしてここまでで区切るかー
前回GitHub Actions 作ったからpush だけでいいんだよなーらくちんだなー
なんか`ng test`失敗してるけどいったん置いといてマージして
これが今回のせいかです!
![5-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/a974c624-21c7-9a02-8ae8-2ab75486a774.png)


### またおまえかー
みたら記事が書いてあるファイルを読み込めなかったらしい。
なんでと思ったらenvironment.ts ファイル（本番環境用のやつ）が空だった。
それはそうなるよ...

気を取り直して...
これが今回のせいかです!!
![5-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/71868361-b2df-ec06-c384-0d7d9649fb41.png)


### 404だああ
というのは1/3嘘で、現状は3種類のURLが使えるがそのうち2つで404となった。
記事の一覧
https://magurouhiru.github.io/mysite/
https://magurouhiru.github.io/mysite/article/
記事の詳細
https://magurouhiru.github.io/mysite/article/001

このうち一番上はセーフで下2つは404だった。
理由はAngular がSPA だからです。
つまり...
サーバーはリクエストのURLに対応したファイルを返そうとする。
しかし、実際にはルートディレクトリにしかファイルがないため、ページ遷移したら「そんな場所にファイルなんてないよ」と404になる。
↓はローカルでビルドした中身で、確かにbrowser フォルダ内にしかindex.htmlがない。
```aiignore
└─mysite
    │  3rdpartylicenses.txt
    │
    └─browser
        │  favicon.ico
        │  index.html               ←ここにしかない。
        │  main-QGR4P3CI.js
        │  polyfills-SCHOHYNV.js
        │  styles-RWIYYJCX.css
        │
        ├─articles                  ←紛らわしいけど記事関連のファイルしかない
        │  ├─001
        │  └─test
        └─media                     ←？気が付いたらできてた。
```

したがって、Angular アプリを公開する場合、URLによらず毎回index.htmlを返すようにしないとだめということ。
（実は以前に同じ失敗をしたのは内緒）

対策は２種類あって、一つはHashLocationStrategyを使う、もう一つはサーバーの設定を変える。
今回後者はできない？と思うので、前者を使う。
↓公式のいうとおりに変えて、アンカータグも直して完了。
https://angular.dev/guide/routing/common-router-tasks#hashlocationstrategy


気を取り直して...
これが今回のせいかです!!!
![5-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/9f47ddba-21da-b591-5cf4-3a53cf744adc.png)

動きましたああ
もちろん一覧のページも動いてます。
![5-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/122918d1-3836-0cf9-19b8-14a14add861d.png)
めでたしめでたし

詳細見たい人はこちら
https://github.com/magurouhiru/mysite/releases/tag/v0.2.0
https://magurouhiru.github.io/mysite/

前回の記事はこちら

https://qiita.com/magurouhiru/items/e820dbd2a6305b065449