サーバレスでExpressと再会
eslint-typescript (様子見)
tslintとtslint-config-airbnbを常用していますが、中の人による上記記事ではいずれ世の中はtslintからeslintに移行されていくってことが予見されています。eslintの方が設定をpackage.jsonの中に書けるってのが好き。IDEやビルドツール群との連携は元々eslintの方が強いので、ルールのTypeScript対応が成熟してくれば。現在困ってないので今はちょっと待ちで、近い将来に移行してみようと思う。過渡的にeslintでtslintのルールを使うブリッジが提供されているけど特に狙いもないので冗長なので、eslintネイティブにいい感じになるのを様子見ながら待ち。
serverless-webpack
今まで使ってたserverless-plugin-typescripitでは、コードのコンパイルについてゼロ設定で対応してくれるけど、node_modulesはそのままクラウドへ持ち上げるのでデプロイの際に無駄に大きなパッケージを作ります。Jestとか@types以下全部とか、明らかに不要なものが含まれています。webpackでまとめて小さくするととてもコンパクトになり、結果としてデプロイ速度もスピンアップも早くなりとても有用です。
SPAを作る時にはクソめんどくさいwebpack設定も、この用途ではTypeScriptをコンパイルするだけなのでシンプルです。特にプロジェクト毎に変わるものでは無いので一度作ったらしばらく使い回しできる。
// webpack.config.js const path = require('path'); const serverlessWebpack = require('serverless-webpack'); const webpackNodeExternals = require('webpack-node-externals'); module.exports = { mode: serverlessWebpack.lib.webpack.isLocal ? "development" : "production", entry: serverlessWebpack.lib.entries, resolve: { extensions: [ '.js', '.json', '.ts' ] }, output: { libraryTarget: 'commonjs', path: path.join(__dirname, '.webpack'), filename: '[name].js' }, target: 'node', externals: [webpackNodeExternals()], module: { rules: [ { enforce: 'pre', test: /\.ts$/, use: [ { loader: 'tslint-loader', options: { typeCheck: true, emitErrors: true, }, }, ], }, { test: /\.ts$/, use: [ { loader: 'ts-loader' } ], } ] } };
さらに、serverless.ymlではプラグイン登録と、ちょっと設定が必要。
# serverless.ymlの該当部分 plugins: - serverless-webpack custom: webpack: includeModules: forceExclude: - aws-sdk packager: 'yarn'
webpack設定の方でnode_modulesに入るものを取り除き、serverless設定の方でパッケージに追加しています。custom.webpack.includeModulesはtrueを設定すると依存パッケージを全部取り込みます。aws-sdkは入れなくてもAWS環境側で用意されてますので、forceExcludeにホワイトリスト登録するとパッケージから省く&ワーニングが無いとのこと。
パッケージマネージャーは惰性でyarnを使ってますが、その後の機能追随と速度向上および元々のデフォルト感から、折見てnpmへ戻して良いかもと思っています。
Express
Reactアプリの対となるAPIを作る際に、引き続きAWSのサーバーレス製品群でやろうと思っています。今回の手法としてはServerless Frameworkとaws-serverless-expressでExpressアプリをLambdaへ載せてみてます。
今まではLambda上でExpressを使うことはなんとなく遅くてダメなんじゃないかなと思い込んでたけど、よく考えたらExpressのミドルウェアによってちょっとぐらいコールスタックが増えてもパワフルな現代のコンピューターの前にはなんの影響もないだろうし、一個のLambdaでエンドポイントだけ面倒見てもらってそれ以下はExpressのコードで書いた方が見通しもよく、変更にも強く、テストもしやすく、他クラウドへの移植性もよいんじゃないかなと。さらにはServerless Framworkで管理対象が巨大になってくると、背後のCloudFormationの由来にてリソース上限数制限200個が来るから、Lambdaが一個になってれば当然制限を避けられる。
社内でちょっと話してた時に指摘されたのは、多数Lambaがそれぞれ立ち上がるよりはコールドスタートが掛かりにくいってメリットはあるかもと。そしてLambdaなのにExpressで書いて良いってことになればExpressの既存知識や膨大な世間のコード資産が有効活用できそう。
# serverless.yml service: express provider: name: aws runtime: nodejs8.10 stage: dev region: ap-northeast-1 plugins: - serverless-webpack custom: webpack: includeModules: forceExclude: - aws-sdk packager: 'yarn' functions: app: handler: lambda.default events: - http: method: ANY path: '{proxy+}' cors: true
serverless.ymlの方では、methodが「ANY」で、pathが「{proxy+}」を設定します。これはAWSのドキュメントではプロキシ統合と呼んでいる。これでAPI GatewayではルーティングをせずにExpressの方に全てが回って来ます。
// lambda.ts import { createServer, proxy } from 'aws-serverless-express'; import { eventContext } from 'aws-serverless-express/middleware'; import { APIGatewayProxyEvent, Context } from 'aws-lambda'; import * as express from 'express'; // 普通にExpressのインスタンスを作る const app = express(); // aws-serverless-express/middlewareでAPI Gatewayのイベントを搭載してみる // http.Requestですでにアプリを作るのに十分な情報があるので、実戦だったらいらない機能かなと思います。 app.use(eventContext()); type Event = { apiGateway: { event: any; }; }; const dumpEvent: express.Handler = (req, res) => { res.json((req as unknown as Event).apiGateway.event); }; // ここでは例なのでワイルドカードによる全部受けハンドラ登録をExpressに対して行っている。 // 実戦では、app.get('/dump', dumpEvent); というようにメソッドとパスの組み合わせを具体的に設定する。 app.all('*', dumpEvent); // aws-serverless-expressでLambdaと直結する。 const server = createServer(app); export default function (event: APIGatewayProxyEvent, context: Context) { proxy(server, event, context); }
上記ではとりあえず例としてExpressでもワイルドカード利用でリクエスト全部受けのコード書いてますが、実戦ではExpressのルーティング作法で細かく普通にやればよく、そうすれば想定外パスへのリクエストはExpressの機能として404が返ります。
Serverless Components (様子見)
Serverless Frameworkが定義ファイルからCloudFormationテンプレートを生成してクラウド操作するのではなく、定義ファイルからコンポーネントインスタンスが生成されてそれらがAPIを直接操作する仕組みになっていた。これは良いアイディアで良いアーキテクチャだと思うけど、実装として今はまだ未成熟。Serverless Frameworkの先としてうまく融合 or 進化してほしい。
CLIだけでなく コードでデプロイなどの操作を行う機能 も素敵。そのほかそここことなく、Gulpのようなものを目指してるのかなと思った。
Amplify (お蔵入り)
amplify-cliのfunctionやapi機能がTypeScriptにまだ対応していない。また吐き出すScaffoldの構造がちょっと好きじゃないかな。そもそもにExpressでいいじゃないかと思ったのは、AmplifyでAPIを定義する際にCLIが表示する選択肢の中にExpress利用を見つけたからなので、もうちょいTypeScript対応が進めば個人的な見え方は変わると思います。でも今日ではなかった。
LoopBack (お蔵入り)
5年ぐらい前に、自分的には第1期としてNodeに触れていた時期に、チューンドNodeバイナリを提供していたStrongLoopを見つけました。StrongLoopは当時住んでた近所のSan Mateoに会社が所在していたので、そこで開催されたNodeのMeetupに参加するのにオフィスに入ったこともあります。連想的に彼らが作ってたNode上でRESTful-APIを作るCLI/フレームワークとしてLoopBackを触ったことがありましたが当時APIはGo言語で書くことになったのと、モノとして時期尚早感があったので使うことはありませんでした。ニューストピックとしてその後すぐにStrongLoopがIBMに買収されたことまで追いましたが、しばらく忘れていました。Expressを検討する中で懐かしい名前としてStrongLoopとLoopBackがまた出てきた。
ちょうど新しいバージョン4を出す前夜ぐらいなタイミングで、しかもその4はそれまでのコードベースを捨ててTypeScriptで書き直しているということで、俄然興味がでてきます。
CLIで吐き出すのはTypeScriptオンリーでそれは素敵なのですが、フレームワークの作法としてクラスを書いてデコレータでDIするなど昔のJavaフレームワークかのような。製品WEBでGraphQLとかも語ってたのでこれまでの実績捨ててゼロから作り直した動機はこの辺かと期待しましたが。。。分厚い。。。スタックが深いよ、これは。また4はそれまでと異なりExpressベースではなくなっていました。そしてさすがan IBM Company。IBMクラウドを基本に考えているので、サーバレスにはちょっと背を向けてる風な感じ。各クラウドベンダーの独自なマネージドサービスを多用するサーバレスは現時点での競争負け組であるIBMの戦略には合わないみたい。そして、4が出てくるこのタイミングでわざわざExpressベースとはいえ古い3を使うかというと、なんか気が進まない。よってまたLoopBackはそっと閉じて心の隅にしまう。
Tech-on MeetUp#04「APIでつなぐ・つながるFinTecher」
Tech-on MeetUp#04「APIでつなぐ・つながるFinTecher」というイベントに行ってきた。
KDDIの金融な人たちのホストで、じぶん銀行・au WALLETと連携するカブドットコム証券のセッションに、二本立てのようにゲストStripeで、それぞれFintechの入口のところを事例中心に関係者掛け合いの体で盛りだくさんでした。それぞれのコマが30分程度なので掘り下げ浅めで聴きやすくはありましたが、もっと時間をかけて実装的なことも語られるともっとよかった。 じぶん銀行のAPI(Open API+独自API)はとても興味深いが、法人が気合い入れて取り組まねば利用のためのハードルは超えられなさそうという。。。以下は聴きながら取ってたメモの流し込み。
カブドットコム証券、KDDI
じぶん銀行、KDDI
Stripe、600株式会社
- Stripe:クレジットカード周辺の機能をワンストップ&ペーパーレスでAPIサービス提供する
- Stripeを用いるとクレジットカード情報を直接取り扱わないので、結果としてセキュア
- 600:無人コンビニ、AWSとStripeを利用している
- Fintech/キャッシュレスをビジネスマンとしてどう見るか
- ハードウェアビジネス
- ソフトウェアと違って、デプロイサイクルが長く重い
- 不具合の検出の課題
- 見つけた不具合を更新する際の課題
- オンラインとオフラインの境界が曖昧になってきているように、ハードウェアとソフトウェアも融合
- 自分の専門領域を持ちながら隣接領域にも詳しくなると有利。ハードウェアがその一つだと貴重
- ソフトウェアと違って、デプロイサイクルが長く重い
年末年始
あけましておめでとうございます。
年末年始の10連休でコード書こうかと思ってましたが、Diablo3 for SwitchとNFL game passと積んでた「NEVER LOST AGAIN グーグルマップ誕生 (世界を変えた地図)」を読んで(以上、割合順)過ごしました。残る明日はNFLワイルドカードゲームの現地土曜開催分が未明と午前中にLive放送なのと、17pmまでスプラトゥーン2のフェスなのでほとんど非生産的なまま私の休暇は終わりです。
休み中ちょっとだけReactキャッチアップ。v16.3からContextが変更されてReduxいらないじゃん議論を目にしました。私は新しいContextも含めて以下のように3つ併用した方がキレイだと思います。無理にReduxでなんでもやろうとするとか、Reduxを全く使わないとか、極端にすると余計にテクニックを要して複雑かなと、先入観。
- Redux: SPA背後のドメインモデルを持つ
- Context: 複数ビューを必然的にまたぐルーティングとテーマだけを持つか、使わない
- State: 単一ビューに閉じる画面状態だけを持つ。特にフォーム画面ではフォームの情報を取り扱う。前にライブラリ書いた。
しかーし。ReduxをContextに置き換えてみれば山ほどあるReduxお約束コードがシンプルになるメリットがあるかも。しかしここで考察が足りないのは自分的に未経験なGraphQLのSubscribeが入った場合にどうなるか。Redux続行なら多分イベント直結でストアにDispachさせればいいんじゃないなかと思ってるけど、Diable3やっててそこまで手をつけてない。
今日時点ではRedux続行派な私も、数日後には言うこと変わってるかもしれない。ドメインモデルが直感的に書けてテストしやすいままなら、最低限、依存ライブラリをバッサリ絞れるだけでもステキな予感はある。
2018年の振り返り
2018年は色々あった筈なのですが、全体的に印象に乏しい一年でした。米国駐在からの帰任があったのでそれなりにライフイベント満載な筈なのですが。。。単に自分の感受性の問題だろうか?書き出しながらなんとか思い出す。
1月〜4月
2017 to 2018の年越しは日本にいました。4年の駐在を終えて夏に帰任することが決まったために新春帰国してその後の準備を色々するはずだったのです。プライベートではその時期に長女の高校受験というのもありました。長女は12月初めに帰国させて行徳の実家に預け、その後は公立中学校に3学期だけ通わせました。早生まれの彼女は現地での9年生を終了しておらずそのままだと日本では一学年下がってしまうので、日本の中学校に帰国編入して卒業見込みを得ることが必要だったのです。しかもそれは1月に高校入学願書を出す時点で編入していないといけない。帰国子女枠での受験は海外に3年以上住み&帰国から一年以内に進学というのがよくある条件なので、有識者に聞くと夏休みに入ってすぐに母親と子供だけ先に帰って受験準備をするのがベストプラクティスだったようですが、その分せっかくの海外生活経験も短くなります。ウチは頑張ればどうにでもなるだろうとギリギリまで引っ張りました。
私は3ヶ月間都内ホテル住まいで、サイオステクノロジー社内で進めてたサービス開発に支援で関わってサーバーレス on AWSに触れていた他、その先の仕込みでコツコツ古いものを温めたり、新しいことの種まきしたりと。幸いに長女の受験は全勝してくれたので3月中旬には心安らかに米国へ。しかし諸般の事情でこの時点まで帰任先が明確にはなってなかったのです。なんとなく持株会社ではなく事業会社の方に行くことにはなりそうな雰囲気でしたが、それがサイオステクノロジーなのか(そうならばどの事業部なのか)グルージェントなのか、その他のグループ会社なのか決まってなかった。そんな中で暫定的にサービス開発に関わってましたが、結局はそのサービスが管掌される所の技術部門を担当することになりました。そのサービスとはSIOS Coatiで、技術部門はサイオステクノロジー株式会社第一事業部です。確か内示時期はこの長期出張から戻る直前だったような記憶です。
- この時期に取り組んだコト
- AWSのマネージドサービス群。CognitoとStepFunctionsが初物で、Lambda中心にDynamoDB、S3、API Gateway、SQS、CloudWatchなど。
- Serverless Framework。これをキッカケにAWS Cloud Formationを調べたり戻ったり。とても便利でもっと栄えると良いと思う。
- Vue.js。それまでReactに馴染んでた私でしたが、現場がVue.jsでやりたい声に溢れてたので何でもよかろうと採用。。。が、個人的には失敗だった。Reactの方が良かったと12月の今は心の底から思う。FLUX的なストア構造、ルーティング、コンポーネント毎での描画ユニットテスト、それぞれVue.jsでも論点あるのだと思うけど、Reactの方が一周以上先を走ってる。Vue.jsにはエンジン/フレームワークをTypeScriptで全部書き直すことも構想されているらしい次世代に期待。Anglarは結局食わず嫌いだった。
- Hugo。Static Site Generatorを一通り評価しつつ、結果としてバイナリを一つ置くだけのシンプルな環境で、コンテンツもGo Templateでサクサク書けたHugoを選ぶ。多分私がGoは書くけどRubyは書かないってことが大きく影響していると思う。これも良いと思う。栄よ!
- Stripe。必要になってから他の選択は考えもせずに一択。これまでもこれからもAPIが重要。
5月〜6月
サーバレス on AWSでの経験についてAWS Sumitで登壇することになり、プライベートでは不動産巡りも兼ねてまた日本出張二週間。私と長女の通勤通学の便利から目黒線沿線&大型犬飼育可能の条件で、幸いに奥沢に物件見つけて契約。出張から帰るともう米国は残り1ヶ月しかなく、その辺りは引越しの手配とフェアウェルパーティしか覚えてません。
- この時期に取り組んだコト
7月〜8月
6月末に荷物を出してから船便が届くのに2ヶ月かかった。よって家具もなく床で寝てたしTVも無いし。かろうじて食卓だけは米国に持って行かずに実家に預けてたので、家族全員でほとんどの生活がダイニング。猛暑が続き、毎日家でビール飲んでました。ヤッホー・ブルーイング「インドの青鬼」専門、大好き。
仕事としては、「オマエは技術部門の統括だ、以上!」としかJob Descriptionがない中で、社内観察を行いつつApplication Lifecycle Management(もしくはDevOps環境とでもいうべきか)の統合と刷新を始めています。
- この時期に取り組んだコト
- Chatツールの全般評価。Slack、ChatWorks、Yammer、Workplace by FB、Line、Typetalkなど。結果として初めからそうかなと思ってたけどSlackを採用。その後にSlack TeamとTeam PlusとEnterpriseGridを検討し、Team Plusを採用。
- GitHub Enterpriseの評価。初めはGitHub Businessを評価してたけど、コイツだと事故るな、とすぐに思ってEnterprise。AWS上で何度かインスタンスを作っては壊し、その他コラボツールやSSOを検討していった。
- SSO、つまりはIdPの全般評価。初めはAuth0で作ろうと思って組んで書いた。社内で面白がって手伝う雰囲気があったら本気でAuth0を使ったアプリケーションを作ってたかもしれない。が、とにかく面倒になってきて古巣にご存知Gluegent Gateがあったからそっちに転向。
9月〜10月
船便が届いてから行ったことはソファーの貼り替え。業者事例ページでは世田谷区を目黒区って間違ってる。結構なお値段するんで色々な素材&色々なカラーの見本を取り寄せては考え、最終的に白の合皮で貼り替え終わるまでたっぷり2ヶ月はかかった。決め手は犬でした。彼が土足で登るから汚れても掃除しやすい合皮で、掃除しやすい合皮だからこそ白にチャレンジできた。最近毎晩、彼が就寝用に占有していますがさほど手間をかけずともキレイに保てています。あとはたくさん本を読んでた気がする。シリーズで続いているものの新刊追ってなかったのをまとめて読んだり。大きな本屋に行って書棚を眺めていると何か見つかる。亡きトム=クランシーのジャック=ライアンものとか、漫画とかも。
仕事面ではALMの展開で社内にSSOされたSlackとGitHub Entepriseの本番環境を作ってIDを段階的に増やしつつ、メインは中期経営計画(3年)とさらなる長期ビジョン(10年)の策定で社内ワークショップをファシリテーションしたり、内容をまとめたり。ITイベントに積極的に参加するようにし始めたのはこの頃で、理由は米国に行くしばらく前からイベントやコミュニティに参加しないようになってたので新しい人脈改めて広がれば良いなとか、業界どうなってるのかリサーチのため。
- この時期に取り組んだコト
- スクラム。現場課題にマイクロパッチを充てがう傍で、理屈としてスクラムのベストプラクティスについて書籍やイベント参加などで温め直し。
- Business Model Canvas。派生のValue Proposition Canvasとともにビジネスモデルの考察と表現に採用するのに温め直し。ワークショップはワールドカフェにBMCやVPCを自己ブレンドしたやり方を試してみましたが、結果よかったんじゃないかなと思ってる。
- Slackアプリ開発。Slackでまずはスラッシュアプリ(Slackのコメント欄に”/"から始めるコマンドを打つと定められたURLにアクセスして結果をコメント書き出しするアプリ)から。Hello Worldでは超簡単で世のブログでもそこまではよく見るのだけど、セキュアなサードパーティとしての振る舞いを、きちんとトークンを取得し補完するなどの手間を実装するのは、ベストプラクティスが何かは知られていない。で、試行錯誤。サーバーレスでトークンはDynamoDBに補完する仕組み組んでみたけど、多分これでいいんじゃないかなと思う。需要があれば内外に解説します。
11月〜12月
生活環境も流石に落ち着き、土日も特にどこか家族で行くこともなく淡々と。平日に外で飲むことも以前に比べると少なくなって自室で過ごすことが多くなってくる。9月に開幕したNFLで長年応援しているChicago Bearsが今年は強く、NFL GamepassというWEB視聴サービスを購入して熱心に観てます。1試合が2時間半ぐらいなんで、週に3試合から5試合ぐらい観てるとすぐ夜も更ける。特にBearsは冬に勝ち続けてしばらくぶりに地区優勝!大晦日のシーズン最終戦までプレイオフのシード権を巡って期待させてくれて目が離せない。しかも正月からプレイオフでドキドキさせてくれる。
仕事は日常の日米開発体制で少々イシューありつつも、中期で取り組むべき内容について。アウトプットが量的に停滞して来てたので空き時間はコード書くようにしてます。で、React。サーバー側はAWSサーバーレスで、使ったことないものを眺めながらグルグルウロウロしてます。
- この時期に取り組んだコト
年末最後に、Switch版のDiablo3を買っちゃった。。。
2018年の総括
温故知新、ってことです。日本に戻ってそれまで断絶してた知識や関係をアップデートしている。
2019年の抱負
今の所日々の雑たることはたくさんあると思うけど、私が新しいことをやる予算の獲得はままならず手足縛られているので多分ヒマ予測。イベントやコミュニティに参加したりコード書いたりしてキャッチアップを進めることと、後半ぐらいには人前に出て自分の考えや知見を喋れたらと思う。社内需要次第ですが、勉強会やハッカソンなども考えます。手元では、もうTypeScriptでReactとAWSのサーバーレスで可能な範囲だけでいいやって感じ。他に色々手を広げる気力がない。気力あればMLaaSとかいよいよの時期なのだろうけど。コンテナでk8sなマイクロサービスとかも、AWS以外のクラウドも、社内に有識者いるのでそちらにオマカセ。
プライベートには、やはりダイエットが重点課題になるでしょう。
新年もどうぞよろしくお願いいたします。
Reactは15ヶ月前に比べて相当様子が違った
17年9月ごろを最後にReact書いてなかったので、15ヶ月ぐらいのブランクでしたが、再び寝たReactを起こしてみました。すると、なんとまあ、相当様子が違うのです。Cliツールで雛形を作るのはView.jsで経験していましたが、そもそもに元祖だったらしいReactのソレ(create-react-app)がいい感じに良く動く。複雑なWebpackの設定とか、ライブラリスタックのバージョン合わせなどを全くしなくてもOK。素敵。TypeScriptもちゃんと対応。
package.json
まずやるのは、scriptsから事故防止のためにejectを削ります。
その後にだいたい使いそうなライブラリを加えたりしてまずは以下の感じ。せっかくcreate-react-appで依存性をシンプルに見せられているのに@typesの連続で汚れる。TypeScriptの機能としてJSライブラリに型定義がなければ自動的に@typesみてくれるようになればいいのにな。
まだアプリケーションのコード一切書いてないのでライブラリは入れ出しするでしょう。material-ui関連ではバージョンがあがりすぎてて見当がつかないのでまずドキュメント読み直すところからです。最近のお気に入りはramda。関数型「風」に書くのが好きなのでlodashとかより適している。GraphQL with AppSyncは初挑戦。
{ "scripts": { "start": "react-scripts-ts start", "build": "react-scripts-ts build", "test": "react-scripts-ts test --env=jsdom" }, "dependencies": { "@material-ui/core": "^3.7.0", "@material-ui/icons": "^3.0.1", "aws-amplify": "^1.1.17", "aws-amplify-react": "^2.2.4", "ramda": "^0.26.1", "react": "^16.7.0", "react-dom": "^16.7.0", "react-redux": "^6.0.0", "react-router-dom": "^4.3.1", "redux": "^4.0.1", "redux-actions": "^2.6.4" }, "devDependencies": { "@types/enzyme": "^3.1.15", "@types/enzyme-adapter-react-16": "^1.0.3", "@types/jest": "^23.3.10", "@types/nock": "^9.3.0", "@types/node": "^10.12.18", "@types/ramda": "^0.25.45", "@types/react": "^16.7.17", "@types/react-dom": "^16.0.11", "@types/react-redux": "^6.0.11", "@types/react-router-dom": "^4.3.1", "@types/redux-actions": "^2.3.1", "enzyme": "^3.8.0", "enzyme-adapter-react-16": "^1.7.1", "nock": "^10.0.4", "react-scripts-ts": "3.1.0", "tslint-config-airbnb": "^5.11.1", "typescript": "^3.2.2" } }
ここで疑問なのは、react-scripts-tsが自動生成されたものではdependensiesに入ってたこと。これってdevDependenciesでいいんじゃないかなと思うので移しておいて様子見ます。
watchman
create-react-appはJestのテスト環境もすぐ作ってくれますが、テスト実行すると立ち上がったままで変更監視を始めます。すると「ファイルが多すぎ」エラーが出てしまいそのままでは動かなかった。調べるとファイル変更を監視するためにwatchmanというのをインストールしないとダメだとのこと。
$ HOMEBREW_PREFIX=$(brew --prefix) brew install watchman
HomeBrewで淹れますが、単に「$ brew install watchman」だと入れたwatchmanがアクセス権の問題で動きませんので、上記のようにPREFIX環境変数を設定します。これは長時間ハマりました。
テスト周辺
import * as React from 'react'; import { configure, shallow } from 'enzyme'; import * as Adapter from 'enzyme-adapter-react-16'; import App from '../App'; describe('App', () => { beforeAll(() => { configure({ adapter: new Adapter() }); }); test('renders without crashing', () => { const wrapper = shallow(<App/>); // mountでもyarn testならOK。IDEからの直接起動はNG expect(wrapper.contains(<h1 className="App-title">Welcome to React</h1>)).toBeTruthy(); }); });
デフォで書き出されてたテストをEnzymeバージョンにして動作確認。Dom不要のshallowはいつでも動くが、mountを使ったテストは単独でGoLand(IDEはWebStormもCLionもやめてGoLandにしました)から実行できない。
こちらのように、Jestのオプション設定で「--env=jsdom」を書いてあげればOK。yarn testの実行時でもreact-scripts-ts testの引数として書かれてます。jestの設定で指定する方法をやってみると以下のエラーで、ejectしろと言ってくるので、とりあえず先のIDE設定で回避します。
Out of the box, Create React App only supports overriding these Jest options: • collectCoverageFrom • coverageReporters • coverageThreshold • snapshotSerializers • moduleNameMapper. These options in your package.json Jest configuration are not currently supported by Create React App: • testEnvironment If you wish to override other Jest options, you need to eject from the default setup. You can do so by running npm run eject but remember that this is a one-way operation. You may also file an issue with Create React App to discuss supporting more options out of the box.
しかしEnzymeは前からこんなに簡単に書けたかな?Reactノードを引数にとるのも、containsってのも記憶にない。。。これはView.jsに替えてReactを選ぶ強力な説得材料になるかも。jsx/tsxでテストが書けるのでDom断片を気軽に使える=ユニットテストが楽しい。nock使っての通信のところもフックすると、ユニットテストの延長線上でE2Eに近いことがさほど手数多く無く書けそう。
HMR環境
create-react-appのデフォではHMR環境が組まれてないのですが、まあ、無くてもいいかな。画面見ながら作るよりUIもTDDで書くようにしたら実際に動かす必要は常の事ではないので。トリッキーにアプリのブートストラップコードのところで細工しないといけないのが改善されていないのであればwebpackの設定をこじ開けるなど無理するのも嫌なのでHMRは入れなくていいや。
NoOps Meetup Tokyo #3に行ってきた
さて、久しぶりにソフトバンク本社へ。サイオスビルの入口前にある古川橋バス停から新橋行きに乗って新橋五丁目で降りてちょっと歩く、G-Suiteでオシッコのひっかけ合いしてたときには何度も行き来して慣れた道のり約30分。今日の目的、NoOps Meetupに参加してきました。イベントには直前水曜日に登録したのではじめ補欠だったのだけど、今日になって朝からどんどん繰り上がって昼すぎには参加できるようになりました。某からリクエストもあったのでセッションのメモを貼っておきます。メモは今回も時系列ではなく聴きながら内容で上下整理しながらまとめたもの。
西谷さん from AWS
- Opsは悪なのか?
- Amazon流のサービス開発。Two-Pizza Teams
- 2枚のピザで足りるような、少数精鋭チームが効果的
- 作るもの全てに責任をもつ。
- ロードマップの作成
- 開発
- 運用とカスタマーサポート
- You Build it, you run it.
- QAもオンコールもチームの中でやる
- チームには権限が与えられていて、多くの自由が認められている
- チームの水準を高く保つ
- Hiringも各チームで行う。ヘッドカウントを持っている。
- テストで大事なこと。
- Automate Everything! テストがしやすいようにアーキテクチャを整える
- 運用で大事なこと。
- Automate Everything! 自動化が重要。
- 運用ゼロは幻想。NoOpsは難しくとも、LessOpsはできる。
- LessOpsはServerlessでできる。
- Our Leadership Principles、Amazonのクレド
- Customer Obsession
- 全て、お客様から。単純な顧客第一主義には止まらない。
- Ownership
- 長期的な視野
- DevOpsをやるのに大事なことがオーナーシップ。
- Think Big
- お客様に貢献するために、従来と異なる新たな視点を持つ。
- Insist on the Highest Standard
- 常に高い水準を目指す
- Code Reviewをちゃんと行う
- Deliver Result
- 結果をだす。そのために重要なことにフォーカスする。
- イテレーションを重視して、貯め込まずに早めにレビューを繰り返していく
- Minimum Viable Product
- お客様と一緒に製品を作る
- Customer Obsession
牛尾さん from MS、Serverlessの自動化と自動回復(リトライ)
- https://github.com/TsuyoshiUshio/MdTranslator
- Serverlessとは
- ユニットテストをとにかくちゃんとやる。
- テスト可能な設計のためのTips
- リトライ
- APIの制限などで正常系がちゃんと動かないのが普通
- 単一責務にすると、テストも単純になるし、自動リトライができるようになる
- 委譲する、オーケストレーションだけする、など。
- 冪等性を守るとリトライが楽にできる。
- リトライ単位でのFunction設計が望ましい。
そのほか
- NoOps = No Uncomfortable Ops
- Toilを潰す
- node-red: nodeで動くIoT向けフローベース。
感想
牛尾さんのユニットテストをしっかり書くというのは私も普段からの信条なのでとても参考になりました。テスト書くためにアーキテクチャを磨く、そしてテストTipsは、これからテスト書くときに勇気になる。これでいいんだって。
私がAWS Lambdaでポツポツ作る時は、Jestの高度なexpect機能とnockで手数なくできてる。特にnockが強烈。けど、DynamoDBのところはテストしてない。ここもServerless.comのオフラインプラグインを使うか、関数を引数に渡す&Jestモック機能か?
週末にちょっとトライしてみようと思う。
Google Mapsが出るように直した
不恰好なので地図を出るようにしました。Google Maps JavaScript API ドキュメント の通りAPIキーを設定するのですが、これは以前から言われていたことで変更は無いです。ただ、これまではキーを設定しなくても動いてたってだけ。GoogleはAPI提供開始から何年も経って、いよいよちゃんと制限かけたのですね。
今回まっさらなアカウントでコンソールを立ち上げました。その際に課金してなくてもAPIキーは払い出せますが、そのままではMapsのアクセスで課金エラーが出ます。ならばと調べると、Google Mapsには$200/月の無料枠なるものが設定されていました。さらにコンソールでカード登録して課金システムを有効にすると一年間有効のクレジットが付与されたりとかして、おそらくこの件で課金されることはなかろうと判断しました。このブログそんなにPV無いしねw
APIキーはHTMLソースコードで見え見えなので、きちんと制限をかけます。コンソールからリファラーと利用APIを設定すればOK。リファラーはワイルドカードが使えるので、はてなブログの挙動を鑑みて「http://mk.hatenablog.com/*」と設定しています。APIは当然「Maps JavaScript API」縛り。
課金が動き始める可能性も出てくる一年後ぐらい目処にMaps代替の何かをアイディア出して作ることにしよう。当時はサーバ無し(サーバレスではなく)で作れるものが他に思いつかなかったのですが、AWS lambdaとかサーバーレスを利用すれば無料でも結構リッチなものを作れるので。でも先延ばせるものは先延ばし。