PlawrightでゴリゴリE2Eテスト実装してCSSとPhotoshopでできたUIデザインにキレてたら一日終わった。
タスク4つほど並行ある上に某クライアントがMTG多すぎてあの会社いやすぎるってなっている。
タスクは減るものの来週もこんな調子になりそうでうーん。
あまりにも更新しなさすぎなので、最近やってることについて書いていく。 今後もちゃんと日誌にして雑多なことを書いていって、まとまった技術的な知見はzennに書いていく感じにしていきたい。
去年はずっとTypeScriptとGCPとTerraformをやっていた。
TypeScriptはType Challengeは全くやっていないが一通り業務で自分で実装もするしレビューもしたのでそれなりに実装できていると思う。 ただ信頼できない外部からの入力に対しては脆く、実践導入はできなかったがio-tsとか使えばもっと楽になったかもしれない。
Terraformはぶっつけ本番で実戦投入して、良かったこともあるし知識不足でうまくいかなかったこともあり、全部含めて学びになった。(次はもっとうまくやるぞ)
ここ数ヶ月は大したことはやっていないが、直近はplaywrightでJavaのWebアプリケーションのE2Eテストを実装している。E2Eテスト、慣れてないのもあるかもしれないが壊れやすくて難しい。
プライベートでpuppeteerでスクレイピングしたりそのpuppeteerをkickするAPIをExpressとかNestJSで実装するなど。
Reactは1月に社内の課題でviteとかesbuildとか使ってフォームをいい感じにvalidationするのをTDDでやってた。
とはいえ型周りの仕様に疎い(inferとか)のでType Challengeを4月はやりたい。(時間あるのか?)
現職の社内プロジェクトでGoでAPIを隙間時間で開発したりTerraformの環境構築したりしている。 如何せん本業の隙間なので時間があまりない。
Goのhot reloadに何がいいかを同僚と検討していて、reflexがいいんじゃないかという話になり採用している。
現状ではGoでしか使ってないが、他の使い道がありそうで良さげ。
Database Clientはいまいち何が主流なのかあまりわかってない。SQL firstなsqlcも良さそうだしGraphQLと相性が良いentも良さそうな感はあるが、そんなに使えてないので不明。
個人で細々とAPIを開発している。actix-webがベタだけど、axumも良いかもしれないと思い始めている。
ちまちまとやっていた雀魂で雀聖になった。このぐらいはいけると思っていたので今も粛々とやっている。基本に忠実に打って、若干引き気味ぐらいがちょうど良いという感じがある。一向聴からは思っているよりも押せないというのを科学する麻雀で確認できたのとNAGAと対戦して序盤の切り順を矯正できたのが良かった。天鳳もやっていきたいが時間がない。
同僚に布教したら自分よりもどハマりしており毎日やっている。
久しぶりの投稿です。TypeScript+Reactの素振り用に前から気になっていたHeadless CMSのContentfulを使ってブログをNetlifyにホスティングしてみました。今ならCloudflare Pagesとかになるんでしょうか。
Netlifyから提供されるドメインではなく独自ドメインを設定する方法も合わせて追記しています。今回はGoogle Domainを使いました。お名前.comは使いたく無い
NextでもVueでも同じようにできると思うので置き換えてください。
参考になるか分かりませんが、記事の例で使用している自分の実装はこちらです。あくまで参考程度ですが、特にeslintとかprettierとかの設定は参考にしないでください。
Contentful自体の日本語での説明はこちら(次世代Headless CMS「contentful」事始め)をみてください。
何はともあれログインしてspaceを作成します。基本Freeで大丈夫です。
spaceを作成したらmodelを作成します。これが実際のデータ構造になります。
Contentfulは多くのfieldを用意しています。ReferenceはRDBの外部キーのような使い方ができます。今回はカテゴリとタグを紐づけるのに使用しました。 今回は記事のカテゴリとタグ、記事自体のmodelを用意します。
まずカテゴリのmodelです。 次にtagのmodelです。 最後に記事のmodelにカテゴリとタグを紐付けます。 記事本文は今回はMarkdownを指定してください。描画時にMarkdownをhtmlに変換します。 カテゴリとタグの紐付けはReferencesを選択するとOne ReferencesとMany Referencesが選択できます。カテゴリは記事に対して一対一、タグは一対多で一つの記事に複数紐づくようにしました。
最終的に以下のようになります。
最後に記事を取得するためのAPI keyを生成します。ヘッダーのSettings→API KeysからAdd API Keyを選択して生成します。 後でContentfulのSDKを使いますが、その際にSpace IDとContent Delivery API - access tokenが必要になります。
これでContentfulは終わりです。
Reactの一通りの環境構築が終わっている前提で、SDKのinstallと使い方の説明をします。
SDKをinstallします。
npm install --save contentful
記事一覧を取得する実装です。
createClient
にSpace IDとaccess tokenを渡してContentfulClientApi
のインスタンスを生成します。
その後getEntries
で全体を取得できます。
ここでは実装していませんが、検索条件を付与することも可能です。詳しくはドキュメントを読んでください。
型定義については後で説明します。
import {ContentfulClientApi, createClient, Entry} from 'contentful'; import {Article as ContentfulArticle} from '../domain/contentful/article'; const getClient = (): ContentfulClientApi => { return createClient({ space: process.env.REACT_APP_CONTENTFUL_SPACE_ID as string, accessToken: process.env.REACT_APP_CONTENTFUL_DELIVERY_API as string, resolveLinks: true, }); }; const getContent = async ( contentType: string ): Promise<Entry<ContentfulArticle>[]> => { const client = getClient(); const response = await client.getEntries<ContentfulArticle>({ content_type: contentType, }); return response.items; };
Contentfulの記事はここをanyにしてごまかしている実装がよく検索でヒットします。JavaScriptではなくTypeScriptを使っているのでanyに逃げずにちゃんと型定義をします。
先ほどのgetEntries
の戻り値の型はPromise<EntryCollection<T>>>
です。
その戻り値のitem
プロパティの型はEntry<T>
でこれがmodelの実体になります。このT
に自分で設定したmodelの型定義をあててあげれば型をつけて取得できます。
Entry
型は以下のようなデータ構造になっています。
export interface Entry<T> { sys: Sys; fields: T; toPlainObject(): object; update(): Promise<Entry<T>>; }
sysはuniqueなidや作成日時、更新日時などのメタデータが定義されています。 fieldsがモデルの定義になります。
よって今回の型定義は以下のようになります。
import {Sys} from 'contentful'; export type Category = { fields: { name: string; }; sys: Sys; }; export type Tag = { fields: { name: string; slug: string; }; sys: Sys; }; export type Article = { category: Category; content: string; tag: Tag[]; title: string; };
Article
型はEntry
型のfields
プロパティの型を定義してsys
プロパティの型定義は不要です。
NetlifyはGitHub連携でpush時に自動でデプロイするのとSDKでのGitHub Actionsでのデプロイがあります。
starter planではビルドが月300分までなので、頻繁にデプロイしたいならGitHub Actionsでビルドしてデプロイするとお得です。
以下のような.github/workflows/deploy.yaml
を用意してください。
masterブランチへのpush時に以下のworkflowが実行されます。
name: Deploy on: push: branches: - master jobs: build: runs-on: ubuntu-latest steps: - name: Checkout source code uses: actions/checkout@v2 - name: Cache node_modules uses: actions/cache@v1 with: path: node_modules key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.OS }}-build- ${{ runner.OS }} - name: Setup Node uses: actions/setup-node@v1 with: node-version: 14.x - name: npm install and build run: | yarn install yarn build - name: Deploy to netlify run: npx netlify-cli deploy --dir=./build env: NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
まずAUTH_TOKENとSITE_IDですが、アプリケーション設定画面に遷移するとNew access token
とあるので押下するとAUTH_TOKENが取得できます。
SITE_IDはhttps://app.netlify.com/sites/[自分のサイト名]/settings/general
に遷移するとAPI ID
とあるのでこれがSITE_IDです。
これらをGitHub Actionsで使うために環境変数として登録します。 GitHubのリポジトリのSettingタブからSecretsを選択すると環境変数が登録できます。
Google DomainsはGoogleが提供するドメイン管理サービスです。 日本だとお名前.comがありますが、個人的には使いたくないので今回はGoogle Domainsを使います。
これ読んででいいですか?ダメ?
大切なのは、Google DomainsのカスタムリソースレコードにnetlifyのIPアドレスとwwwつきドメインを追加してください。
NetlifyのDomain ManagementからAdd Custom Domainで以下のような設定されていればおkです。
最後にbaseURLを設定したカスタムドメインにすれば終わりです!
覚えてしまえばそんなに難しく無いかなと思います
今度はNext.jsでcloudflare pagesにデプロイしてみたいです。
Eloquentのfactoryでテストデータを用意してテストを実行した際、以下のようなエラーが突如発生した。
PHP Fatal error: Maximum function nesting level of '256' reached, aborting! path/to/vendor ...
依存関係が循環するfactoryを定義して実行しており、factoryの実行自体でエラーにならなかったため。
これは大量の再帰呼び出しを行った際に発生するエラーです。 再帰呼び出しの回数が非常に多い場合、メモリにひたすら実行された処理の結果が積み重ねられ、スタックオーバーフローが発生する可能性があるため、PHPでは一定回数を超えるとエラーが発生します。
このエラーになる回数自体はXDebugの設定で変更できます。
ですが、今回テスト対象の実装には再帰呼び出しもなければ大量のループもありませんでした。 本当の原因はエラーの原因はfactoryの実装で以下のような実装になっていました。
factory(Room::class, function(Faker $faker){ return [ 'name' => 'room name', 'house_id' => factory(House::class)->create()->id ]; }); factory(House::class, function(Faker $faker){ return [ 'name' => 'house name', 'room_id' => factory(Room::class)->create()->id ]; });
RoomモデルとHouseモデルが循環しており、実質無限に再帰的に相互で呼び出しを行う処理が作られていました。
しかし、Houseモデルが参照しているhousesテーブルにはroom_idは存在しません。
存在しないカラムをfactoryで定義しているのでエラーになりそうですが、Eloquentのfactoryでは存在しないカラム自体ではエラーにならず、今回のエラーになるまでずっと処理が止まらなかったということです。
想定していなかった動作だったので原因の発見に少し時間がかかりました。 個人的には存在しないカラムを定義しているのであればエラーを発生させて欲しいですね。
社内勉強会で乱数と擬似乱数について発表しました。
内容的にはそんなに深いことはしていないですが、難しかったと言う声が多かったのでちょっと意外でしたが、非エンジニアも見るのでそれはそうかもと言う感ある。
内容的には、CSPRNGと真の乱数生成器以外は暗号技術に使わないでねってことと、線形合同法はよく考えて使ってねって内容でした。
まだメルセンヌツイスターとXorshiftはアルゴリズムがよく分かっていないのでまたちゃんと勉強したいですね。
あとで見返せるようにするのと、やることを宣言するために。
これも簡潔かつわかりやすい説明でとてもよかったです。ただ現状マイクロサービスのサービス間通信が主となっている?
他にも細かく色々あるがとりあえずこんなところ。
今年は計算機科学の基礎固めとエンジニアリングの両立で行きたいと思います。
上期はこっちをやる。
下期はおそらくこっち。
アルゴリズムとデータ構造、コンピュータアーキテクチャが必須で、最後は読めたら。一年でざっと読了できればいいなぐらい。
アルゴリズムとデータ構造枠として
型の勉強する前に論理の勉強をちゃんとやっておいたほうがいいから、「論理学」→「論理と計算の仕組み」→「プログラミング言語の基礎概念」→「型システム入門」の順番で読む感じがおすすめだなー。途中でやめても、そこまでで役に立つし。
— きしだൠ(K8S(Kishidades)) (@kis) December 12, 2013
本当はサーバサイドKotlinとかRustとかもやりたいが、今年は上記をやっていくことを優先。
エンジニアとして優先度が相対的に低いもの。多分来年にやることになりそう。
去年は上期は特定のフレームワークとか言語ばかりだったので、ひたすら計算機科学とエンジニアリングの基礎を固めていくようにしたい。
フレームワークとかパブリッククラウドなどは必要な時に必要に応じてやる程度にしてあまり深入りしない方針にします。
追記 大切ぽいことが書いてあったので
年越しそば食べたのとポケモンで盛大に順位溶かしたので。
前職で開発やってた。Spring BootとAngular1を2:8ぐらいの割合で書いてた。
単体試験(実際の内容は結合試験)をやってた。
この辺から転職するつもりで動く。
現職の面接の前に2社で面接があり落ちた。うち1社はエージェントの紹介で面接を受けた会社が、あまりにも酷い態度で憤慨した記憶があり、エージェントはダメだと思った。
確か6月半ばぐらいに内定通知が来て、そこから辞める話をしたら営業がゴネ始めて(社会人としてのマナーがどうとしか言ってなかった)とりあえず常駐先とは統合試験がある7月いっぱいまでで交渉。
7月は統合試験があり残業時間が80こそ超えなかったものの70は超えてた気がする。(でも基本給低いので残業代はそこまで)
この時期エクセルスクショしかやってなかった上に忙しかったので最悪だった。
8月に転職し、9月まで社内向けでLaravelで改修やったり新規案件やってた。(新規案件は諸事情により凍結となった)
10月からすでに進行している案件のヘルプ?としてエンジニアが欲しいとのことでアサインされる。
だいたいLaravelとVueやってた。
技術書典にも行った。
12月は社内で使ってる稼働入力と日報管理アプリのリライトでRailsとNuxt触ったりDjangoでAPI実装したりしてた。
年末はフロントエンドエンジニアの部署で燃えつつある案件のヘルプで非同期周りを書いて終わった。(DOMを返すAPI is 何)
今年は人権がある環境に転職できたので総じて良かったと言えるでしょう。
ただ、転職前はもっと色々やっていた気がするので、転職して充足感もありインプットはともかくアウトプットが微妙だったので、来年は社内外ともにアウトプットを意識していきたい。