docker-composeのENVはbuild時に適用されない

まとめ

  1. DockerfileのENVはbuild時もコンテナ起動時も適用される。
  2. docker-compse.yamlのENVはbuild時に適用されず、コンテナ起動時にDockerコンテナ内に展開される。

環境

$docker --version
Docker version 19.03.8, build afacb8b

検証

Dockerfile

FROM node:alpine
ARG ARG1=args_default_value_defined_dockefile
ENV ENV1 $ARG1
ENV ENV2 "ENV2"
ENV ENV3 ""
RUN echo $ENV1
RUN echo $ENV2
RUN echo $ENV3
RUN echo $ENV4
RUN echo $ENV5
RUN printenv

1の検証

ENVはbuild時に適用される

$docker build -t test  --no-cache .
Step 11/11 : RUN printenv
...
ENV1=args_default_value_defined_dockefile
ENV2=ENV2
ENV3=
...

ENVはコンテナ起動時に適用される

$docker run -it --rm test ash 
/ # printenv
...
ENV1=args_default_value_defined_dockefile
ENV2=ENV2
ENV3=
...

2の検証

Dockerfileは1と同様
docker-compose.yaml

version: "3"
services:
  test:
    build:
      context: .
      args: 
        ARG1: "arg_defined_docker-compose.yaml"
    environment: # docker-compse upのときcontainerに展開される
      - ENV3=ENV3
      - ENV4=$ENV4 # 実行環境で定義された環境変数を読み込む
      - ENV5=ENV5
    tty: yes

ENVはbuild時に適用されない

$docker-compose build --no-cache
Step 11/11 : RUN printenv
...
ENV1=arg_defined_docker-compose.yaml
ENV2=ENV2
ENV3=
...

ENVはコンテナ起動時に展開される

$docker-compose build --no-cache
$docker-compose up -d
$docker-compose exec test ash -c "printenv"
...
ENV1=arg_defined_docker-compose.yaml
ENV2=ENV2
ENV3=ENV3
ENV4=hoge
ENV5=ENV5
...

参考

https://docs.docker.com/engine/reference/builder/#env

The ENV instruction sets the environment variable to the value . This value will be in the environment for all subsequent instructions in the build stage and can be replaced inline in many as well.

https://docs.docker.com/compose/compose-file/#environment

If your service specifies a build option, variables defined in environment are not automatically visible during the build. Use the args sub-option of build to define build-time environment variables.

lighthouse-ciの使い方メモ

github.com

lighthouseのCIインテグレーションツールがある。

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md
を読んだメモを残す

概要

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#overview lighthouse-ciはassert,upload機能を有する。

前準備

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#prerequisites

  • Git管理されておりCIに統合されていること
  • プロダクション環境用のアセットをbuildできること
  • プロダクション用のアセットでサーバを起動できる、もしくは静的サイトであること

結果の収集

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#collect-lighthouse-results

  • レポート結果はGoogleCloudStorageに保存される

ex): https://storage.googleapis.com/lighthouse-infrastructure.appspot.com/reports/xxx.report.html

  • 自前で保存用のサーバを用意することもできる

  • デフォルトではレポートをあげるだけなので
    履歴、diffを見たい -> カスタムサーバたてる
    ビルド落としたい -> assertion入れる、GitHubAppの通知入れる

Note:静的サイトでない場合は下記ドキュメントを参照
https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/cli.md#autorun

アサーション

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#add-assertions

  • 開発初期はスコアを上げるのが大変なのでアサーションせずにレポートだけしましょう
  • プロジェクトが成熟したらアサーションでビルドを落としましょう
  • 設定ファイルに記述できるのでプロジェクトの特性によってアサーションを切ることも可能

GitHub Status Checks

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#github-status-checks GitHub Appを導入すると - Lighthouseで失敗したかどうかわかるようになる - ビルド結果にレポートのURLが表示される

リポジトリにAppをインストールするとTokenが発行されるので変数としてCIに読み込む

CI Serverの起動

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/getting-started.md#the-lighthouse-ci-server

  • 下記に従ってCI Serverをたてる

https://github.com/GoogleChrome/lighthouse-ci/blob/master/docs/recipes/docker-server/README.md

  • 下記コマンドでCI Serverを設定する
$lhci wizard
  • 一つのビルドに対して一つのチェックしかできないので注意

GitHub Actions

Actionが公開されている https://github.com/GoogleChrome/lighthouse-ci#related-projects

Jestでwindow.location.hrefをmockしたいとき

環境

  • Jest: v24.8.0

モチベーション

Jestでwindow.location.hrefをmockしたい。

結論

下記公式ドキュメントを参照。
https://jestjs.io/docs/en/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom

window.location.hrefのmock

describe('mock window.location.href', () => {
    beforeEach(() => {
        delete window.location;
    });

    test('hogehoge', () => {
        Object.defineProperty(window, 'location', {
            configurable: true,
            value: {
                href: 'https://example.com/',
            },
        });

        expect(window.location.href).toBe('https://example.com/');
    });
});

レガシーをぶっつぶせ。現場でDDD!2nd 「インプット<アウトプット!」参加ログ

genbade-ddd.connpass.com

参加してきたので感想を書く

オープニングトーク

DX(デジタルトランスフォーメーション)についての話。 2025年以降の技術的負債の経済損失がが12兆円/年にのぼる。 comemo.nikkei.com つまり、レガシーなシステムを改善すること、負債化を最小限に留める設計が重要。 という話だった。

B:モデル・コードの変更がどう表現されるかハンズオン

内容

格安SIMモデリングとコーディングハンズオン。
モデルとコード間を行ききして、モデルを改善していく流れを体験する。
全体の流れとしては下記のようなものだった。

  1. 格安SIMの仕様書に対し仕様書に出てくる文字をモデルとして書き出す プラン、オプション、料金、月額料金など
  2. まずは愚直にコードに落とし込む
  3. テストがグリーンになるように実装する
  4. コードとモデルを比較し、コードとの乖離がないようにモデルを更新する
  5. モデルで依存関係を確認し、依存が多いところをリファクタリングする
  6. リファクタリングの際に概念が足りないことが発覚したり不要な概念が見つかる

以下繰り返し

学び

普段はVSCode,TypeScriptなので下記のようなものが使えそう
vscode-ts-uml - Visual Studio Marketplace

QA

Q.どれくらいの頻度でドメインモデルを育てるか?
A.新しい機能追加のタイミングでドメインモデルもリファクタしている
サービスにif文雅出現しているのでドメインサービスをつくる。判断はドメインの役割。

Q.モデリングに使う道具は?
A.紙と付箋
ただし全体像は紙で表現できないので一部のみ

資料

資料は後日TechBlogに公開していただけるとのこと https://style.biglobe.co.jp/archive/category/TechBlog

f:id:mMQnaZ7vL2DWkoU:20191214212507j:plain
作成したモデル

C:モデリングワークショップ 〜割り勘ドメイン編〜

内容

割り勘システムのモデリングと実装のハンズオン。
ユースケースの大枠が決められており、それに従いドメインモデルの作成->実装を行う。
詳しくは下記リポジトリのREADME.md参照
https://github.com/j5ik2o/warikan-domain

学び

  • モデリングが難航した
    作業全体をハンドリングする人が必要だった。(前のハンズオンは主催者側のドライバがいたが今回は全員参加者だった。)
    モデリングの認識合わせが曖昧だったため話の方向性が定まらなかった。(モデルに全員同意していることが大事)
  • 区分という概念はEnumとして表現する(現場で役立つシステム設計の原則でも見た)
  • 値の表明と型の表明
  • 内部データをそのまま返すGetterはドメインの文脈では使わない、何らかの計算をして返す。(ただしI/Oの文脈では使うこともある)

資料

それぞれのチームが考えたモデルは以下のようになった。

f:id:mMQnaZ7vL2DWkoU:20191214212602j:plainf:id:mMQnaZ7vL2DWkoU:20191214212611j:plainf:id:mMQnaZ7vL2DWkoU:20191214212625j:plainf:id:mMQnaZ7vL2DWkoU:20191214212635j:plainf:id:mMQnaZ7vL2DWkoU:20191214212646j:plain
各チームのモデル

クロージングトーク

大規模開発とDDDについて参加者同士で話した。

学び

開発者の人数について

5~6人が適切(肌感)でそれ以上は増やさない。
それ以上増やすときはドメインを増やす。

負債化を防ぐ方法について

  • ペアチームを作り交代でモブプログラミングする
    2ペアチームで1人ずつ交代していき、モブプログラミングする。すると4人全員がドメインの知識を把握し、コードを把握できるようになった。
  • プロジェクトに対してチームを交代制でまわしていく
    プロジェクトAに対し最初はチームAが担当し、一定の期間がすぎるとチームBが担当する。こうすることで引き継ぎ資料が必ず作られるようにする。
    これは自チームに取り入れてみても良いかもしれない。
    チーム全員交代は難しいかもしれないけどドメインチーム間でメンバー交換とかやってみると、別ドメインの理解が深まったり、新しいメンバーによる発見があるかもしれない。

ドメインの粒度について

ユーザに機能を届けるまでのリリース間隔が長い場合はチームの粒度を見直す。
リリースサイクルを評価関数とする。
一つの変更に多くのチームが関わる状況ならばチームの粒度を見直す。

ドメインの理解について

ドメインごとのKPIが決まるはずなのでKPIについて考えてドメインの理解を深める。

ドメインと組織構造について

ドメインの編成に伴い組織構造も変更が生じる。

f:id:mMQnaZ7vL2DWkoU:20191214205256j:plain
クロージングトークの内容

感想

  • 例題をもとにモデルとコード間を往復するハンズオンを通してモデルを育てていく感覚をつかめた
  • 次のアクションとして実際の業務のモデリングをやっていく
  • 変更に強い設計についてもう少し具体的に学ぶ必要があることがわかった

f:id:mMQnaZ7vL2DWkoU:20191214212946j:plain
購入したモデリングの本

実践ドメイン駆動設計 (Object Oriented SELECTION)

実践ドメイン駆動設計 (Object Oriented SELECTION)

JSConf JP 2019 Day2参加記録

概要

JSConf JP 2019に参加してきました。
https://jsconf.jp/2019/

自分用メモとしてブログに残します。

Day1はこちら
JSConf JP 2019 Day1参加記録 - tom-256.log

以下スケジュールです。

f:id:mMQnaZ7vL2DWkoU:20191204130319p:plain
スケジュール

時間はただの幻想である… JavaScriptにおいては

まとめ

WEB の自重

まとめ

  • ブラウザは追加仕様を受け入れることでどんどん肥大化している
  • ブラウザの多様性はあるが、ブラウザエンジンの多様性が減っている
  • レイヤを下げ、責務をアプリに移すことでブラウザの仕様を小さくしていけるのではないだろうか
    https://mozilla.github.io/standards-positions/

GraphQLを用いたECサイトにおけるパフォーマンス改善

まとめ

  • 継続的な観測を行うことでパフォーマンスを改善した
  • パフォーマンス改善のアプローチをフロントエンド、サーバサイド、GraphQLの3つに分けて説明した
  • GraphQLのデメリットをカバーするポイントについて説明した

資料

https://speakerdeck.com/nobuhikosawai/improving-online-shopping-site-performance-which-using-the-graphql

マイクロフロントエンドについての話

マイクロフロントエンドについて雑に話してきました
https://speakerdeck.com/nobuhikosawai/the-theory-and-practice-of-micro-frontends

Q.ログに関して
A.統合レイヤーにイベント送信したほうが責務が統一されて良さそう

Q.バンドルサイズ調整の事例
A.toBのシステムなのである程度諦めている。
マイクロフロントエンドアーキテクチャは開発スピードとアプリケーションの速度はトレードオフだと思う
thoughtworksの資料があるのでそれを参考にすると良さそう(ベストプラクティスかは怪しい,資料見つけられず)

JavaScriptのままでTypeScriptを始める

まとめ

資料

https://speakerdeck.com/ginpei/start-typescript-leaving-javascript-as-js

Your Benchmark May Not Guide a Real Application Performance

まとめ

Recruit Speed Hackathon(ワークショップ)

まとめ

  • Lighthouseで100点出せた
  • Lighthouseはv6でスコアの項目と重みが変わる予定
  • 40%のサイトは改善後6ヶ月で性能が戻ってしまう→継続的な計測・改善が必要
  • パフォーマンスハッカソンの良さ→Biz要件(制約)を一旦無視して考える事ができる

資料

リクルートのパフォーマンス改善について

ワークショップが終わったあと講師の https://twitter.com/maxmellon_9039 さんにインタビューしてきました

Q.パフォーマンスバジェットで読み込みにかかる時間が3秒とのことだったが妥当性は?
A.Googleが提唱している資料から決めた

Q.パフォーマンスバジェットはいつ決めた?
A.機能を全部入れてから。目標値があるわけではなく、これ以上悪くならないように意識する目的。

Q.Real User Monitoringどうやってる?
A.独自基盤を作っている
 reduxのアクションの間の時間を記録
 CPUの負荷が低いときにLambdaでデータを送信する
 ElasticSearch,Kibanaで可視化
 一般的な指標では足りなかったので自分たちで改善指標を決めた

持ち帰ったアクション

  • 独自のパフォーマンス指標を4つほど考えてみた(ブログでは書けないので内容は省略)

JSConf JP 2019 Day1参加記録

概要

JSConf JP 2019に参加してきました。

https://jsconf.jp/2019/

自分用メモとしてブログに残します。
Day2はこちら
JSConf JP 2019 Day2参加記録 - tom-256.log

以下スケジュールです。

f:id:mMQnaZ7vL2DWkoU:20191204130319p:plain
スケジュール

JAVASCRIPT AST プログラミング: 入門とその1歩先へ

まとめ

  • 抽象構文木(abstract syntax tree,AST)についての簡単なデモをおこなった
  • 配列とオブジェクトの操作を理解すれば、ASTを理解できる
  • ESLintやBabelの仕組みを学ぶことができた

メモ

抽象構文木はただのオブジェクトツリーである 配列とオブジェクトの操作ができれば問題ない parser(JavaScriptをObjectツリーにする)

parser https://github.com/jquery/esprima

traverseなどの処理

unparser

https://github.com/estools/escodegen

まずはsimpleなツールで原理を理解し、次にEasyなツールで生産性をあげる
JavaScriptはのAST標準がある。https://github.com/estree/estree

"b" + "a" + +"a" + "a"ついて何が起こっているのかparerserを使って説明

"b" + "a" + +"a" + "a"; // -> 'baNaNa'

https://github.com/denysdovhan/wtfjs#banana

ASTのノードを解析して条件に一致したものを検知するデモ

覚醒するアクセシビリティ

まとめと感想

JS開発者のためのSEOテクニック

まとめと感想

各テストサイト
https://search.google.com/test/mobile-friendly
https://search.google.com/test/rich-results

WEB ACCESSIBILITYのすゝめ

まとめ

コントラストのチェッカー
https://color.a11y.com/

予測的 PREFETCHING によるパフォーマンス改善

まとめ

CACHE ME IF YOU CAN

まとめ

持ち帰ったアクション

  • a11yについてチーム内で共有した
    特にグローバル展開のサイトのため、リーガルに十分注意するように話した

Mercari x Merpay Frontend Tech Talk vol.3参加記録

https://mercari.connpass.com/event/153687/

参加してきました。

一番の目的だった最後の発表に関してフォーカスして感想を書きます。

Practical tips for making a global EC site

概要

ユニクロのグローバルサイト(https://www.uniqlo.com/us/en/home/)のアーキテクチャ、工夫点についての話

特に気になった点

URL設計

URLに接続国を含める

https://www.uniqlo.com/us/en/home/

のように国名をURLに含めていた。

国判定はGeoIPでやっているとのこと。

SEO

GoogleBot以外のBotも考慮する

展開する国によってはGoogle以外の検索エンジンのランキングも考慮する

Google,Bing,YANDEX,Baidu

参考:https://www.globalmarketingchannel.com/press/survey20190319

パフォーマンス

毎日国別にWebpageTestとLightHouse実行

国に近いリージョンにインスタンスを立てて実施しているとのこと

結果を集計して毎週メールしているらしいが、ダッシュボードを大型ディスプレイで共有したほうが良さそう

指標はSpeedIndexとTTIを見ているらしいが変えていく必要があるとのこと

i18n

webpackで翻訳言語ファイルごとにエントリポイントを分ける

bundle-analyzerで翻訳ファイルが混ざっても検知できる

一部のインタラクティブな翻訳はランタイム上でおこなう、このとき単数形と複数形で出し分ける

a11y

下記をチェックする

https://www.matuzo.at/blog/beyond-automatic-accessibility-testing-6-things-i-check-on-every-website-i-build/

画像

画像が大きいほうがコンバージョンが上がる

最適化する

CDNでwebp形式にして配信する

発表のまとめ

・URLは初期段階で考える

・リダイレクトの初期段階でレイヤも決める

・a11yを怠ると起訴されるケースがあるので気をつける(US、カナダなど)

・Webpackを使い倒して国別対応する

感想

現状のアプローチの方向性が一部正しいことを確認できたのが良かった。 現状の仕事でa11yがまだ考慮できてないので、今後に役立てたい。 現状画像最適化のアプローチが足りていない。 現在の仕事ではGoogleBotだけ意識すれば良さそう。

現在グローバルシステムを担当していることもあり、とても興味深く聞かせていただきました。

他のブログ

https://ozaki25.hatenadiary.jp/entry/2019/11/26/205938 https://lealog.hateblo.jp/entry/2019/11/26/210503