信頼はずっと、挑戦はもっと。

お問い合わせ
TEL:03-3496-3888

BLOG コアテックの社員ブログ (毎週月曜~金曜更新中)

LIST OF ARTICLES

記事一覧

  • テクログ

    bfcache と popstateイベント ~地獄のブラウザバック友達~

    どうも!最近、「地獄のブラウザバック友達」ができたわいです!親にはあの子たちとは付き合うなと言われていたのですが、、はい。ブラウザバックを検知して発火するpopstateイベントまず、今回実装しようとした内容は、一覧ページがあって、そこで詳細ボタンをクリックすると、詳細ページがモーダルとして表示されるそして、そのモーダルには一覧ページに戻るための閉じるボタンがあり、ブラウザバックボタンを押下した場合も遷移せず、閉じるボタンと同じ挙動をするというものです。上記の挙動は、History API を使用して実装しました。(簡潔に書くためにjQueryを使ってます。すみません)// 詳細ボタンを押下 $(document).on('click', '.js-detail-open', function() {     history.pushState(null, null, '{$詳細ページのurl}'); // ブラウザバック検知用に履歴を追加     modalOpen(); // モーダルを開く処理 }); // モーダル閉じるボタンを押下 $(document).on('click', '.js-detail-close', function() {     // popstateイベントを発火させる(ブラウザバック押下時と同じ挙動に)     history.back(); }); // ブラウザバック押下時にページ遷移せず、動的に追加したStateが履歴から取り除かれたときに発火 window.addEventListener('popstate', function() {     modalClose(); // モーダルを閉じる処理 }); 簡単に書きましたが、モーダル閉じるボタン押下時に「history.back();」させて履歴を取り除いておくとか、下記bfcacheに出くわしてからいろいろ改善しました。ポイントは、JSで動的に追加した履歴でないと、ブラウザバック時にpopstateイベントが発火しないというところです。挙動についてのイメージは、下記記事が参考になるかと思います。イメージさえ掴めれば、そこまでややこしい話ではないと思います。ブラウザバックをトリガーにしてイベントを発火させる方法JSも含めてすべてのページ情報をメモリにキャッシュするbfcachebfcacheはWebページを速く表示させるためのブラウザの機能です。詳細については、下記記事が参考になりました。Back/forward cache簡単に言うと見出しの通りで、具体的にどのようなことが起こるかというと、ハンバーガーメニューを開いてリンクをクリックして、遷移した先でブラウザバックをすると、ハンバーガーメニューが開いたままで先ほどのページが表示されるとかです。以前ロードしたJSがそのまま使われて、ブラウザバック時にJSをロードしてくれない。ページを離れたときの状態がそのまま再現されるというものです。今回、このbfcacheが iOS の Safari / Chrome の両方で発生しました。ブラウザバック時にキャッシュされているpopstateイベントが発火してバグるbfcacheのせいで、ハンバーガーメニューが開いているだけならまだよかったのですが、初回アクセス時に設定したpopstateイベントがブラウザバック時にそのまま発火して、モーダルを閉じる処理(省略してますが、結構複雑…)を実行してしまうバグにハマりました。bfcacheをJSで検知するには、PageTransitionEvent.persisted を使えば良いそうです。ということで、下記記事を参考にして、ページ読み込みがbfcacheからであれば、JSで強制リロードしてもう一度JSをロードするという処理を実装しました。ブラウザの「戻る」ボタンでキャッシュが表示されてしまう際の対策これで一件落着かと思えば、、、悲劇が起きました、、連続で該当処理が入っているページへ遷移していき、その後ブラウザバックを連続で押していくと、ブラウザバック2回まではページのリロードという期待通りの動きをしてくたのですが、3回目のブラウザバック時に、JSでbfcacheを検知できない(bfcache自体が発動していない?)にもかかわらず、popstateイベントが発火してしまいました。ブラウザの挙動を見る感じ、履歴をpushStateで余分に追加した分のpopstateイベントが発火していました。つまり、適切に履歴を取り除いていかないとこの問題は解決できないということです。そこらへんはブラウザがよきにはからってくれると思っていましたが、そんなに甘くありませんでした。最終的には、下記のような実装で、無事「地獄のブラウザバック友達」と仲良くなることができました。let isBFCache = false; window.onpageshow = function(event) {     // bfcacheを検知、popstateイベントより先に発火     isBFCache = event.persisted; }; // 詳細ボタンを押下 $(document).on('click', '.js-detail-open', function() {     history.pushState(null, null, '{$詳細ページのurl}'); // ブラウザバック検知用に履歴を追加     modalOpen(); // モーダルを開く処理 }); // モーダル閉じるボタンを押下 $(document).on('click', '.js-detail-close', function() {     // popstateイベントを発火させる(ブラウザバック押下時と同じ挙動に)     history.back(); }); // ブラウザバック押下時にページ遷移せず、動的に追加したStateが履歴から取り除かれたときに発火 window.addEventListener('popstate', function() {     if (isBFCache) {         isBFCache = false;         return false;     }     modalClose(); // モーダルを閉じる処理 }); いざ該当箇所のコードだけ抜き出してみると考えやすいですが、ソースコードの方は複雑すぎて、なかなか思考の整理ができませんでした。思考が整理できさえすれば、あとはやることが決まってくるので、いかに論理的に問題を分割できるかということが重要なスキルだなと改めて感じました。まあ、そんな大層なことは言わなくていいんですよ。友達が増えたので、それでOKです。以上、わいでした。健闘を祈る!!

  • テクログ

    Jamstackを理解する

    こんにちは!最近弊社の勉強会でJamstackを取り扱ったのでざっくりとまとめてみます!JamstackとはJavascript/API/Markup で構成されたシステムです特徴静的サイトであるWEBサーバーの管理が不要静的サイトのビルド時にAPIから最新のデータを取得、htmlに反映Jamstack構成が向いているサイトコーポレートサイトメディアページ基本的に全閲覧者に同一の情報を公開するようなサイトに向いていますJamstack構成のサイト作成に必要なものヘッドレスCMS-必要なデータを登録し、APIとして公開するためのサービスです静的サイトジェネレーター   -静的サイトを生成するためのライブラリですホスティングサービス          -作成した静的サイトを公開するためのサービスです勉強会では実際に以下の構成でサイトを作成しました!ヘッドレスCMSmicroCMS(https://microcms.io/)静的サイトジェネレーターNuxt.js(Vue.jsのフレームワーク)ホスティングサービスAWS Amplify(https://aws.amazon.com/jp/amplify/)サイト公開までの下準備Nuxt.jsでプロジェクトを作成し、git(今回はAWS CodeCommitを使用)に紐付けAWS Amplifyでビルドの設定とWebHookURLの発行microCMSでデータ公開のためのAPI設定とWebHookURLの紐付け基本的なサイト運用の流れmicroCMSでデータを登録し、公開AWS AmplifyがWebHookの通知を受け取り、自動的にビルド&デプロイ最新のデータが反映されたhtmlが公開microCMSとAWS Amplifyの設定は割愛しますが、どちらも基本的に管理画面でボタンを押して設定するだけなのでかなり簡単です!Jamstackについての感想サービス構成上向き不向きがありますが、静的サイトであればWEBサーバーの管理を考えずにサイト作成ができるのは非常に楽だと思いましたホスティングサービス側で自動的にCDN配信まで行ってくれるのは、正直驚きました。。余談ですがNuxt.js(Vue.js)とNext.js(React.js)の違いを調べたあとにTypeScriptについて興味が出てきたのでこちらも触っていきたいと思います!それではまた!

  • テクログ

    Google Apps Scriptでお手軽Webアプリ公開してみた

    こんにちは、福神漬けです!自分は実は最近までGAS(Google Apps Script)を触ったことがありませんでした。ひょんなきっかけで触ってみましたが、さすがにGoogleだけあって便利ですね。GASができることとしてGoogle Spread Sheetを操作したりが有名ですが、今回はGASでWebアプリを公開してみてみました!アプリの仕様によっては不向きになるのでその辺りを書こうと思います。というわけで現時点での完成品はこちら。(お試しということで時間を決めて作業したので一部フォントが当たっていないです)https://script.google.com/macros/s/AKfycbwDBOlbzfezy-eZVtdt5jSVilQN6QrcLob0XlPPnRapAzoEAoHOGUoJ6oASfOAaUIm7Dg/exechttps://github.com/kaz912/gasDemoこちらのデザインをお借りしました。https://github.com/afnizarnur/draco所要時間は調べながら実装しましたが2時間ほどです。あと無料です。一番感動したのが、Webサーバーがいらない&設定もほぼない点です!本当に楽にWeb公開できますね...●GASが不向きなもの・大規模なWEBアプリ実行時間や回数が制限されており、今現在有料版でも上限があります。https://developers.google.com/apps-script/guides/services/quotasまた、フロント側はHTML、JS、CSSを全てHTMLファイルとしてアップする必要があるので、凝ったデザインであったり大規模になってくると管理が大変になります。フォントの読み込みなども少々手間でした。・ホームページなどの公式にしたいWEBサイトページ上部に出る利用規約のバナーが致命的です。そしてこれを消すのに一番簡単なのが、「Google Sitesから呼び出すこと」です。WEBサイトはこっちで作れということですね...●GASが得意なことでは得意こと、差別化できる点は何か?個人的には下記の点だと思っています。・小規模でクローズドなWebアプリやWeb APIは十分に無料で簡単に活用できる・他の類似サービスと違ってGoogleのサービスとの連携が圧倒的にやりやすい・日時でのトリガーや、Google Spread Sheet更新と紐づいたアプリ実行ができるつまり社内やプライベートで行っているタスクの自動化などが向いています。GASで書いたAPIをまとめた簡易ページを作ったりもGASで完結しているのが良い点だなと思います。画像もGoogle Driveから読み込めてファイルサーバー要らずです!ということで今回は試しにGASでWebアプリを公開してみました。出来上がったマークアップをGASに載せ替えただけですが、思わぬところで引っかかったりしました。GASの得意な部分を考えて、最大効率でサービスを組み合わせていきたいと思います!機会があったらGASについてまた書くかもしれません。それではお疲れ様でした!

  • テクログ

    Atomic Designへの導入

    コンポーネント指向Vue であろうと React であろうと、コンポーネント指向という開発手段が主流になっています。コンポーネント指向とは一つの様々な機能やデザインからなるサイトが、同じ機能もしくはデザインの部分を一つの部品とし、それらの部品を組み立てることによって構成される開発のことです。バックエンドではオブジェクト指向が主流だと思いますが、フロントエンドだと見た目から直感的に切り分けやすいコンポーネント指向が開発の効率を大幅に上げることが可能です。Atomic Designその中で、コンポーネント指向の一つの設計方法として Atomic Design が上げられます。Atomic Design は UI の要素を原子(Atoms)分子(molecules)有機体(organisms)テンプレート(Templates)ページ(Pages)の5つの階層に分け、最終的なUIとUIの基礎となるものを同時に作成する設計方法で、アメリカのWebデザイナーブラッド・フロスト氏によって提唱されました。イメージとして以下の図がわかりやすいと思います。(出典:https://qiita.com/croco_works/items/e34d1b0c0e50b37031d7)ここで一つの疑問が思い浮かぶと思います。それぞれどの粒度が atoms、molecules、organisms、templates、pages になるのか?粒度の決め方実際には Atomic Design のそれぞれの階層の粒度に関して明確な定義があるわけではない。言い換えれば、これから進めるプロジェクトの粒度は自分もしくはチーム自身で決めることができます。ゆえに、Atomic Design で開発を進めるときは最初の段階でデザイナーとプログラマーが一緒に話し合って、お互いの納得のいくような階層の粒度にして設計書を作るのが最も効率的である。とはいえ、指標がないとなかなか決めるのも難しいですので、僕からそれぞれの階層の定義をここで提示して、粒度決めに役立てればいいなっと思っています。こちらはあくまでも自分がネットで情報を収集して、自分で考えて定義したものなので、一つの考え方として受け止めてください。原子(Atoms)       それ以上UIとしての機能性を破壊しない最小要素分子(molecules)     複数の atoms が一緒になり最小限の機能を構成するグループ有機体(organisms)    インターフェイス上明確な区分を形成するために複数の molecules が集まったグループテンプレート(Templates) データを流し込む前の organisms から構成されるサイトの枠組みページ(Pages)      templatesにデータを流し込んだサイトの完成品

  • テクログ

    【E2Eテスト】codeceptjsをテスト環境に導入してから数ヶ月経過

    こんにちは。E2Eテストを導入して数ヶ月経過しました。画面が生きているかの確認や一定のアクションを実行できるかの確認程度のテストを常に実施しています。忘れた頃にテスト失敗通知がChatWorkに届きます。実施していなかった頃に比べると「検知」のスピードは格段に上がっていると感じます。このままテストと仲良くなりたいです。

  • テクログ

    【E2Eテスト】codeceptjsでシナリオが失敗したときのURLを取得する

    前提として1つのシナリオ内で1画面のテストをしている状況です。const event = require('codeceptjs').event; module.exports = function (options) {     event.dispatcher.on(event.test.failed, async function (test, error) {         let url = await test['steps'][0]['helper'].grabCurrentUrl();     }); } 変数urlに取得したいURLが入ります。これでテストが失敗したときに外部API経由でチャットツールに流して、エラーページのURLがすぐに確認する状況を作れます。参考記事https://codecept.io/hooks/#api