2020/01/25 GKE/k8s でscale to zero
調べたいこと
- ノードプールが0個にまでスケールダウンするか
- どれくらいの早さでスケールダウン可能と検知されるか
- 初期サイズ0でノードプールが作れるか
- リージョナルクラスタのとき、特定のゾーンだけでも0個にまでスケールダウンするか(ゾーンごとに不揃いになれるか)
- kube-systemのpodがあってもちゃんとスケールダウンできるか
実験用クラスタ
- バージョン v1.15.7-gke.2
- リージョナルクラスタ
- プリエンプティブ
- default-pool: n1-standard-1, autoscale(0~1), inititial: 1
- pool-1: n1-standard-2, autoscale(0~3), initial: 0
スケールの最小が0であれば初期サイズ0でクラスタ構築できた
スケールアウト確認
適当なJobを、サイズ0状態のノードプールでしか起動できないrequestを付けてデプロイ
https://cloud.google.com/kubernetes-engine/docs/how-to/jobs#creating_a_job
apiVersion: batch/v1 kind: Job metadata: # Unique key of the Job instance name: example-job spec: template: metadata: name: example-job spec: containers: - name: pi image: perl command: ["perl"] args: ["-Mbignum=bpi", "-wle", "print bpi(2000)"] resources: requests: memory: "1Gi" # Do not restart containers after they exit restartPolicy: Never
gke-standard-cluster-1-pool-2-5b0626e0-k4m2 Ready <none> 73s v1.15.7-gke.2
スケールアウトした
スケールダウン確認
10分立つとノードが消えた
What are the parameters to CA? github.com
scale-down-unneeded-time
パラメータがデフォルトで 10 minutes
GKEだと、組み込みのオートスケーラの設定は変えられない模様
(組み込みのオートスケーラをOFFにして自分でオートスケーラをセットアップする技があるっぽい・・・?)
kube-system podが走っているノードのスケールダウン
I have a couple of nodes with low utilization, but they are not scaled down. Why? github.com
What types of pods can prevent CA from removing a node? github.com
kube-system配下のpodは、DaemonSetやkube-proxyを除いて、デフォルトでは移動されずオートスケールダウンを阻害する模様
How to set PDBs to enable CA to move kube-system pods? github.com
PDBを明示的に付与すると移動させることができる
現状
kubectl describe no | grep -e Name: -e kube-system
Name: gke-standard-cluster-1-default-pool-4c3839c2-jlcv kube-system fluentd-gcp-v3.1.1-rnnpt 100m (10%) 1 (106%) 200Mi (7%) 500Mi (18%) 53m kube-system kube-dns-5dbbd9cc58-flsk8 260m (27%) 0 (0%) 110Mi (4%) 170Mi (6%) 53m kube-system kube-dns-autoscaler-6b7f784798-ppj8j 20m (2%) 0 (0%) 10Mi (0%) 0 (0%) 53m kube-system kube-proxy-gke-standard-cluster-1-default-pool-4c3839c2-jlcv 100m (10%) 0 (0%) 0 (0%) 0 (0%) 53m kube-system prometheus-to-sd-6j4vr 1m (0%) 3m (0%) 20Mi (0%) 20Mi (0%) 53m Name: gke-standard-cluster-1-default-pool-da57e6c7-pwzb kube-system fluentd-gcp-v3.1.1-v5kqs 100m (10%) 1 (106%) 200Mi (7%) 500Mi (18%) 53m kube-system heapster-664fdc77f4-9xjls 63m (6%) 63m (6%) 215840Ki (7%) 215840Ki (7%) 53m kube-system kube-dns-5dbbd9cc58-4nfr2 260m (27%) 0 (0%) 110Mi (4%) 170Mi (6%) 53m kube-system kube-proxy-gke-standard-cluster-1-default-pool-da57e6c7-pwzb 100m (10%) 0 (0%) 0 (0%) 0 (0%) 53m kube-system l7-default-backend-84c9fcfbb-ffgxf 10m (1%) 10m (1%) 20Mi (0%) 20Mi (0%) 53m kube-system prometheus-to-sd-94nvv 1m (0%) 3m (0%) 20Mi (0%) 20Mi (0%) 53m Name: gke-standard-cluster-1-default-pool-ea34b5f9-l0xq kube-system event-exporter-v0.3.0-74bf544f8b-jdzp6 0 (0%) 0 (0%) 0 (0%) 0 (0%) 53m kube-system fluentd-gcp-scaler-dd489f778-chg6d 0 (0%) 0 (0%) 0 (0%) 0 (0%) 53m kube-system fluentd-gcp-v3.1.1-fxnhq 100m (10%) 1 (106%) 200Mi (7%) 500Mi (18%) 53m kube-system kube-proxy-gke-standard-cluster-1-default-pool-ea34b5f9-l0xq 100m (10%) 0 (0%) 0 (0%) 0 (0%) 53m kube-system metrics-server-v0.3.3-6d96fcc55-jcr2l 48m (5%) 143m (15%) 105Mi (3%) 355Mi (13%) 53m kube-system prometheus-to-sd-8mc5s 1m (0%) 3m (0%) 20Mi (0%) 20Mi (0%) 53m kube-system stackdriver-metadata-agent-cluster-level-59f55f888f-5lsws 40m (4%) 0 (0%) 50Mi (1%) 0 (0%) 53m
DaemonSet
kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE fluentd-gcp-v3.1.1 3 3 3 3 3 beta.kubernetes.io/fluentd-ds-ready=true,beta.kubernetes.io/os=linux 99m metadata-proxy-v0.1 0 0 0 0 0 beta.kubernetes.io/metadata-proxy-ready=true,beta.kubernetes.io/os=linux 99m nvidia-gpu-device-plugin 0 0 0 0 0 <none> 99m prometheus-to-sd 3 3 3 3 3 beta.kubernetes.io/os=linux 99m
kube-dns-5dbbd9cc58-flsk8
とkube-dns-autoscaler-6b7f784798-ppj8j
が移動できれば gke-standard-cluster-1-default-pool-4c3839c2-jlcv
がスケールダウンできる
apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: kube-dns-pdb namespace: kube-system spec: maxUnavailable: 1 selector: matchLabels: k8s-app: kube-dns
apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: kube-dns-autoscaler-pdb namespace: kube-system spec: maxUnavailable: 1 selector: matchLabels: k8s-app: kube-dns-autoscaler
PDBを設定してみる
10分待ってもスケールダウンしない・・・
kubectl describe no gke-standard-cluster-1-default-pool-4c3839c2-jlcv
Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 481m (51%) 1003m (106%) memory 340Mi (12%) 690Mi (26%) ephemeral-storage 0 (0%) 0 (0%) attachable-volumes-gce-pd 0 0
よく見たらギリギリCPUのリクエストが51%だった・・・
手動でリソースをすこし寄せる
cordonしたうえで削除して無理やり別のノードへ配備させる
kubectl cordon gke-standard-cluster-1-default-pool-4c3839c2-jlcv
kubectl delete po -n kube-system kube-dns-5dbbd9cc58-jz78s
Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 221m (23%) 1003m (106%) memory 230Mi (8%) 520Mi (19%) ephemeral-storage 0 (0%) 0 (0%) attachable-volumes-gce-pd 0 0
10分後
kubectl get ev -w
0s Normal ScaleDown node/gke-standard-cluster-1-default-pool-4c3839c2-jlcv marked the node as toBeDeleted/unschedulable 0s Normal NodeNotReady node/gke-standard-cluster-1-default-pool-4c3839c2-jlcv Node gke-standard-cluster-1-default-pool-4c3839c2-jlcv status is now: NodeNotReady 0s Normal Deleting node gke-standard-cluster-1-default-pool-4c3839c2-jlcv because it does not exist in the cloud provider node/gke-standard-cluster-1-default-pool-4c3839c2-jlcv Node gke-standard-cluster-1-default-pool-4c3839c2-jlcv event: DeletingNode 0s Normal RemovingNode node/gke-standard-cluster-1-default-pool-4c3839c2-jlcv Node gke-standard-cluster-1-default-pool-4c3839c2-jlcv event: Removing Node gke-standard-cluster-1-default-pool-4c3839c2-jlcv from Controller
kubectl get no
NAME STATUS ROLES AGE VERSION gke-standard-cluster-1-default-pool-da57e6c7-pwzb Ready <none> 118m v1.15.7-gke.2 gke-standard-cluster-1-default-pool-ea34b5f9-l0xq Ready <none> 118m v1.15.7-gke.2
スケールダウンした
2020/01/21 slow_query / Cypress / @sentry/node
slow_query
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_LogAccess.Concepts.MySQL.html
If log_output = TABLE, you must specify an integer value with second resolution.
出力先を TABLE
にしていると秒単位の精度でしか long_query_time
が指定できない
log_output = FILE に変える
ログファイルはRDSの画面で見るよりCloudWatchで見たほうが楽
# Time: 2020-01-21T02:05:37.696600Z # User@Host: xxxxxx[xxxxx] @ [IP ADRESS] Id: dddddd # Query_time: 1.270852 Lock_time: 0.000000 Rows_sent: 0 Rows_examined: 0 SET timestamp=1579572337; COMMIT;
みたいなのが多い
これは何?
SET timestamp
はslow logに必ず現れるだけのもの
遅いのは COMMIT
アプリ側でtraceも入れないと特定できない?
Cypressでテストケース間でログイン状態が維持される
テストケース間でCookieはクリアされる仕様のはずなのに
ずっとopenなissueがある
おそらく原因判明
直前のテストの最後で呼び出されたAPIが、テスト終了してCookieクリアしたあとに呼び出し完了し、Cookieをセットしていた
修正して事象が発生しなくなるか様子見
@sentry/node
でError.stackTraceLimitがセットされない
@sentry/browser
では50に変更される
むかしの raven-node
ではInfinity
2020/01/18 git log --graph --format
gitコマンドでコミットツリー見る用のalias、author名も見えるように変えた
— yokomotod (@yokomotod) January 18, 2020
[alias]
- graph = log --graph --oneline --decorate
+ graph = log --graph --format='"%C(auto)%h%d %s by %an"' --decorate
←新 旧→ pic.twitter.com/lQUiOlgVQU
Squashマージが基本なレポジトリだと --date-order
の方が見通しがいい感
2020/01/13 CreateReactApp
CreateReactAppのテスト動かす
masterはCIコケてるので3.3.0タグで
git checkout -b 3.3.0 v3.3.0
yarn
yarn test
pass
create-react-app/test at master · facebook/create-react-app · GitHub
cd packages/react-scripts/ && yarn link; cd ../../test/ && ../node_modules/.bin/jest --watchAll
PASS fixtures/issue-5947-not-typescript/index.test.js PASS fixtures/mjs-support/index.test.js (53.148s) PASS fixtures/typescript-typecheck/index.test.js (49.245s) PASS fixtures/relative-paths/index.test.js (10.431s) FAIL fixtures/typescript-advanced/index.test.js (46.686s) ● builds in development expect(received).toBe(expected) // Object.is equality Expected: true Received: false 3 | test('builds in development', async () => { 4 | const { fulfilled } = await testSetup.scripts.start({ smoke: true }); > 5 | expect(fulfilled).toBe(true); | ^ 6 | }); 7 | test('builds in production', async () => { 8 | const { fulfilled } = await testSetup.scripts.build(); at Object.<anonymous> (fixtures/typescript-advanced/index.test.js:5:21) PASS fixtures/node_path/index.test.js (42.694s) PASS fixtures/boostrap-sass/index.test.js (10.628s) PASS fixtures/issue-5176-flow-class-properties/index.test.js (8.218s) FAIL fixtures/webpack-message-formatting/index.test.js (123.476s) ● helps when users tries to use sass expect(received).toMatchSnapshot() Snapshot name: `helps when users tries to use sass 1` - Snapshot + Received @@ -3,10 +3,22 @@ Failed to compile. ./src/AppSass.scss To import Sass files, you first need to install node-sass. Run `npm install node-sass` or `yarn add node-sass` inside your workspace. + Require stack: + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/sass-loader/dist/getDefaultSassImplementation.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/sass-loader/dist/getSassImplementation.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/sass-loader/dist/index.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/sass-loader/dist/cjs.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/loader-runner/lib/loadLoader.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/loader-runner/lib/LoaderRunner.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/webpack/lib/NormalModule.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/webpack/lib/NormalModuleFactory.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/webpack/lib/Compiler.js + - /home/yokomotod/workspace/yokomotod/create-react-app/node_modules/webpack/lib/webpack.js + - /home/yokomotod/workspace/yokomotod/create-react-app/packages/react-scripts/scripts/build.js ", "stdout": "", } 98 | 99 | const { stdout, stderr } = await testSetup.scripts.build(); > 100 | expect({ stdout, stderr }).toMatchSnapshot(); | ^ 101 | }); 102 | 103 | test('formats file not found error', async () => { at Object.<anonymous> (fixtures/webpack-message-formatting/index.test.js:100:30) › 1 snapshot failed. PASS fixtures/typescript/index.test.js (5.853s) PASS fixtures/builds-with-multiple-runtimes/index.test.js (36.341s) Snapshot Summary › 1 snapshot failed from 1 test suite. Inspect your code changes or press `u` to update them. Test Suites: 2 failed, 9 passed, 11 total Tests: 2 failed, 28 passed, 30 total Snapshots: 1 failed, 12 passed, 13 total Time: 142.977s
コケる・・・
$ grep -r "Require stack" ../node_modules/ ../node_modules/eslint/lib/shared/relative-module-resolver.js: error.message += `\nRequire stack:\n- ${relativeToPath}`;
エラーメッセージがeslintから出てきてるっぽい・・・? 根が深そう
yarn e2e:docker
こっちもコケる・・・
2020/01/14 Node.jsにAWS X-Ray入れるのを諦めた
AWS CloudWatch Logs Insightsをはじめてちゃんと使った。便利やん
— yokomotod (@yokomotod) January 13, 2020
エージェント入れたりとかまだなにもしてない、これからパフォーマンスやってくぞって状況でもとりあえず既存の生ログをパース&集計して様子見できるの助かる pic.twitter.com/IGx467Px8u
— yokomotod (@yokomotod) January 13, 2020
aws-cli、v2がプレビュー中なのか。キャッチアップ出来てなかったpreview厨の名折れ
brewにはまだ無い
rootには入れたくないのでホーム以下に入れる
Ubuntu、デフォルトで ~/.bin
や ~/.local/bin
にパスを通すことになってる
# set PATH so it includes user's private bin if it exists if [ -d "$HOME/bin" ] ; then PATH="$HOME/bin:$PATH" fi # set PATH so it includes user's private bin if it exists if [ -d "$HOME/.local/bin" ] ; then PATH="$HOME/.local/bin:$PATH" fi
~/.local
使って入れる
aws/install --install-dir ~/.local/aws-cli --bin-dir ~/.local/bin/
$ aws2 --version aws-cli/2.0.0dev3 Python/3.7.3 Linux/5.3.0-26-generic botocore/2.0.0dev2
AWS Instance-Connect、 インスタンス側はIAMの設定だけで、手元で mssh
インストールすれば使い始められるのは手軽
でも mssh
コマンドだとport forwardできない?
https://docs.aws.amazon.com/xray/latest/devguide/xray-daemon.html
プロファイルの指定は AWS_PROFILE
環境変数でできる
余裕で動かない
expressのミドルウェアで作られているはずのContextが消失していてエラーになる
NestJSのDIとかのせい?
v3.0alphaで cls を cls-hooked に変えたバージョンが出ている。8日前に
これなのか
https://komari.co.jp/blog/frontend/355/
DEBUG_CLS_HOOKED
を有効にしてるとクラッシュする。
async_hooks.currentId is not a function · Issue #52 · Jeff-Lewis/cls-hooked · GitHub
Node v9で currentIdがrenameされた
nestjsじゃなくてredisのせいだった
cls-redisというpatchがあるけど最新バージョンで動かない
PRが出てるけどマージされる気配がない
実際にどうするかはともかく、PR版を入れてためしたらredis問題は突破できた
が、TypeORMのあたりなのか、まだ死ぬ
さすがにもう厳しい(だいぶ前から気づいていた
NewRelicとかほかのツールをためそう
GCP IAM Explorerを公開した作業ログ
gcp-iam-explorer-263803.web.app
目標
- IAM Roleの一覧取得
- IAM Permissionの一覧取得
- Role×Permissionのマトリクスをいい感じに見れる
- RoleとRoleのdiffを取れる
- GAは簡単にいれとく
- OGPタグもちゃんとする
スコープ外
- 複数Roleのdiffを取れる
- ただし、「全パーミッション」(全ロールの和)だけつくる
- APIエンドポイントに必要なPermission一覧取得
Permission×Endpointのマトリクスをいい感じに見れる
自動化
- デプロイの自動化(push→公開)
- ロール、パーミッション情報の定期最新化
と
があるの何?
- (APIじゃない)Cloud Client Libraryの方が高級らしい
パーミッションの一覧あった
2574個
CustomRoleサポートレベルという概念を見つけた
2545個
全パーミッション網羅していない?
$ cat result.json | jq -r 'map(.includedPermissions) | flatten | .[]' | LANG=C sort -u | wc -l 2601
そしてドキュメントよりもRoleから抽出されたパーミッションの方が多い
342d341 < bigtable.tables.getIamPolicy 347d345 < bigtable.tables.setIamPolicy 933a932 > compute.instances.update 1008d1006 < compute.nodeGroups.update 1493d1490 < datacatalog.entries.list 1496d1492 < datacatalog.entries.updateTag 1502d1497 < datacatalog.entryGroups.update 1570,1577d1564 < dataproc.autoscalingPolicies.create < dataproc.autoscalingPolicies.delete < dataproc.autoscalingPolicies.get < dataproc.autoscalingPolicies.getIamPolicy < dataproc.autoscalingPolicies.list < dataproc.autoscalingPolicies.setIamPolicy < dataproc.autoscalingPolicies.update < dataproc.autoscalingPolicies.use 2052,2053d2038 < logging.cmekSettings.get < logging.cmekSettings.update 2185,2196d2169 < networkmanagement.connectivitytests.create < networkmanagement.connectivitytests.delete < networkmanagement.connectivitytests.get < networkmanagement.connectivitytests.getIamPolicy < networkmanagement.connectivitytests.list < networkmanagement.connectivitytests.rerun < networkmanagement.connectivitytests.setIamPolicy < networkmanagement.connectivitytests.update < networkmanagement.locations.get < networkmanagement.locations.list < networkmanagement.operations.get < networkmanagement.operations.list
compute.instances.update
がroleから抽出出来てないけど、どうやらそんなパーミッションは無い(なくなった?)
IAMのロゴ無いかな
あった
SVG and PNG Icons
にバッチリ正方形背景透過が
material-uiでAppBarがかぶる問題の解決は theme.mixins.toolbar
Routerまわり
いまのところreach-routerがreact-router v6の先取りっぽい
が、 TypeScriptのサポートが微妙
Reactのパフォーマンスチューニング調べる
勉強会で聞いた React.memoの話
const Button = React.memo((props) => { // your component });
useCallbackとuseMemoの違いってなんだ?
普通に返り値が違った。関数そのままか、関数の返り値か
Since JavaScript has first-class functions, useCallback(fn, deps) is equivalent to useMemo(() => fn, deps).
Updateがかかってるかどうか知りたい
React Developer Tools の設定に Highlight Update あった
単なるオブジェクトリテラル定数にuseMemo使うのか?
JSX外で定義しろ。そりゃそうだ
ESLintは
eslint-config-react の no-bind でアロー関数作って渡すのは検知できる
でもrecommendedでもeslint-config-react-appでも有効にはされてない
関数、オブジェクトリテラル、配列リテラル、全部チェックしてくれるやつ
(でもマイナー?)
丁寧にやってみたけど、そもそもmaterial-uiのAutocompleteがPure化されてないから結局常時Updateされとる
常にPure化すればいいわけじゃない
Don‘t use PureComponent everywhere. Measure. pic.twitter.com/4obA2vhxs5
— Dan Abramov (@dan_abramov) July 30, 2016
そのとおり。
とりあえず全部戻した
for-ofでarray.entries()使うとエラー
Type 'IterableIterator<[number, string]>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators. TS2569
tsconfigのtargetは esnext
とかで生成されたほうがいい気がする
長いTableをレンダリングしようとすると遅い
raect-virtualized
を使ったサンプルがドキュメントに
でも react-window
の方がオススメ感ある
https://react-window.now.sh/#/examples/list/fixed-size
別に普通に react-window
でもやれるっぽい
いったん諦めた。
Ctrl-F で検索できなくなるし
react-router スクロール問題
画面遷移後に前の位置のままなのは解決できる
でも出来ればブラウザバックしたときは前居たときの位置に戻りたい
ネイティブでサポートされはじめている?
ライブラリがある が、v4対応の方はPopularityがイマイチ
const ScrollToTop: React.FC = () => { const history = useHistory() React.useEffect(() => { if (history.action === "PUSH") { window.scrollTo(0, 0); } }, [history.location.pathname, history.action]); return null; }
でいいのでは?? 遷移したときだけリセット、ブラウザバック・フォワードだと維持
eslint-config-react-app
の .ts
へのoverridesが、
自分で定義した plugins
を上書きしている感
package.json : "extends": "plugin:prettier/recommended"
packages/web/package.json : "extends": ["react-app", "prettier/@typescript-eslint"]
という状況で、rootで指定した plugin:prettier/recommended
が認識されてないように見える
packages/batch/package.json : "extends": "eslint:recommended"
としてる方は問題ない
わかった
config-react-app で root: true
が指定してあるからだ・・・
eslint-configパッケージの方で root: true 指定してくるのって一般的なのか・・・?
もしそうならmonorepoとかでネストしたeslistコンフィグ書くときはサブディレクトリでは root: false を明記すべきなのかとかって気になってくるけど
plugin:@typescript-eslint/recommended-requiring-type-checking
monorepoの場合、ルートで tsconfigRootDir
以外まで設定して、子パッケージの .eslintrc.js
で tsconfigRootDir: __dirname
@typescript-eslint/prefer-regexp-exec
ESLint本体でリジェクトされたルールがtypescript-eslintで採用されて、しかもrecommended入りしている・・・
typescript-eslint、JSレイヤのルールには関与せずTSでだけ架せれるルールだけ扱う、的なポリシーは特に無い感じなんだろうか
いまさらだけどcss propsって、なんでstyle属性をそのまま使うのよりいいんだ?
but using the style attribute as the primary means of styling elements is generally not recommended.
非推奨だった
でもなんで?
Are inline styles bad?
CSS classes are generally better for performance than inline styles.
パフォーマンスが悪い?
ループで何回も描画とかならわかるけど、一箇所でだけ描画されるような要素なら違いなさそう
コンポーネントの設計として、呼び出され方に制限はかけず、どこで何回使われるかわからない想定でいろということかな
GitHubのアイコン
これのためだけにFontAwesome入れるのは違うと思うのでSVGだけ取ってきたい
公式には.aiと.epsだけで、svgに変換してみたらなんか4種類の画像入りなファイルだった・・・
から取得
SVGに色をつけたい
そもそもちゃんと理解してなかったけど、 fill
はインラインSVGにしか使えない模様
で、
import example from "./example.svg"
じゃなく
import { ReactComponent as Example } from "./example.svg"
でインライン展開されるReactComponentが取得できた・・・
こういうのをSVGRっていうのね
svg: 24 a: 16
aタグをdisplay: blockにしても
a: 29
svgもdisplay: blockにしたらOKだった
なるほど
GAの「業種」設定って目標のテンプレートに影響するだけだったのか
Firebase Analyticsをローカルで止める方法
とりあえずCreateReactAppのserviceWorkerで使ってるのとおなじ isLocal
関数コピペして防いでおいた
測定機能の強化、はFirebase Analyticsだとどうやるんだ
データストリームの設定は「Firebase のストリーム設定」となっていて操作できない
ソース公開されてるのか
たぶん出来ない感
Webの場合、Firebase側のトラッキング方法は無視して連携されたGAを直接使ったほうがいいのでは・・・?
そうする
OGP対応
実行時のmetaタグの操作はreact-helmet
でも配信時には影響しないのでTwitterCardには効果がない
それ用のサービスやNetlifyを使うという手
Pre-Rendering into Static HTML Files
CRAのページからのリンク
weekly: 4,129 dependents: 9
Heavily inspired by prep and react-snapshot, but written from scratch.
weekyly: 7,162 dependents: 17
react-snapshotに載ってるAlternatives
weekly: 27,382 (gatsbyの影響だろう)
いいまとめ
weekly: 7,433
react-snap で行ってみる
なにもトラブルなく動いたすごい
metaタグがreact-helmetで変更されない
<meta property="og:title" content="Compare : GCP IAM Explorer">
のまま
<meta property="og:title" content="Compare : GCP IAM Explorer" data-react-helmet="true">
がheadの末尾に追加されてた
data-react-helmet="true"
がついてないものには触らない模様
prerenderingするのでindex.htmlから消してしまえば良い
data-react-helmet="true"
をつければindex.htmlに書いたやつを拾ってくれはしそう
firebase hostingで末尾スラッシュ無しに統一したい
"trailingSlash": false
firebase hostingで404を返す
react-snapでprerenderingしているので初期化時にSPA用としてセットアップして作られたrewriteルールを消せばOK
公開