index.html内のリソースパスを差し替えたい

解決したい事象

index.html内に直接 <link rel="stylesheet"> タグで呼び出している外部CSSがあります。
この外部CSSは開発CDNと本番CDNで開発・運用しており、環境別で切り替える必要があります。
(運用の都合上コンポーネント内に組み込むことができません)

そこでindex.htmlに記述されているリソースパスを ビルド、サーブする際に環境別で差し替える方法はありますか?

期待する挙動

・index.htmlに記載されているcssのリソースパスがビルドする環境別で差し替わる

ng build

<link rel="stylesheet" href="https://develop-cdn/custom-style.css">

ng build --prod

<link rel="stylesheet" href="https://production-cdn/custom-style.css">

環境

Angular 8
TypeScript 3.5.3

追記します。

考えられる実装方法としては、下記の2つがあると思います。

<方法1>
angular.json 内の “index” オプションを使う

"index" : {
 "input": "src/index.prod.html",
  "output": "index.html"
}

<方法2>
ejs, cheerio などhtmlをパース可能npmパッケージを別途用意してnpm script内で同時実行する

<方法1>がangular公式のオプション内で解決ができると思いますが、「ファイルの2重運用はできるだけ避けたい」&「差し替えしたい箇所は1行だけ」のため、少し冗長かなと思い、もっとスマートな方法をご存知でしたら教えていただきたいです。

これとかでしょうか。

2 Likes

index.htmlのファイル自体の差し替え以外の方法となると、ukyoさんが提案しているように ng build で動くCLIのbuilderを差し替えて、webpack configをカスタマイズする他ないですね。
個人的には、CLIのツールチェインとは別に考えて、src/index.html ではdevにしておいて ng build 後の dist/index.html に文字列置換をかけるのも一つの手かなと思います。

1 Like

@Masato-ymd

すでにお試しになったかもですが、stackoverflow でもいくつか見つけました〜。もしご参考になれば :pray:

main.ts で環境みて動的に書き換えれば?という回答

読み込むためのコンポーネント作ったら?という回答

ukyoさん、 lacolacoさん、 is2eiさん

ありがとうございました。頂いた手法をチーム内で検討したところ、 main.tsから動的に外部CSSを差し込む方法で対応しました。

import { environment } from './environments/environment'; // 

// 初回DOM生成時にCDNから CSS を読み込む
document.addEventListener('DOMContentLoaded', () => {
  // <head> 内に追記
  document.head.insertAdjacentHTML('beforeend', `<link rel="stylesheet" href="${environment.cssUrl}">`);
});
1 Like