フレームワークを使用しないプログレッシブWebアプリケーションの設計と構築(パート3)
公開: 2022-03-10このシリーズの最初の部分に戻って、このプロジェクトが生まれた理由を説明しました。 つまり、小さなWebアプリケーションをバニラJavaScriptで作成する方法を学び、非設計開発者に自分の設計チョップを少し動作させたいという願望です。
パート2では、いくつかの基本的な初期設計を行い、いくつかのツールとテクノロジーを選択して稼働させました。 設計の一部が変更された方法と理由、およびそれらの変更の影響について説明しました。
この最後のパートでは、基本的なWebアプリケーションをプログレッシブWebアプリケーション(PWA)に変換し、アプリケーションを「出荷」してから、単純なWebアプリケーションをIn / Outにすることで学んだ最も価値のある教訓について説明します。
- JavaScript配列メソッドの莫大な価値。
- デバッグ;
- あなたが唯一の開発者である場合、あなたは他の開発者です。
- デザインは開発です。
- 継続的なメンテナンスとセキュリティの問題。
- 心やモチベーション、またはその両方を失うことなく、サイドプロジェクトに取り組む。
- 一部の製品を出荷することは、製品を出荷しないことよりも優れています。
したがって、学んだ教訓を見る前に、HTML、CSS、およびJavaScriptで記述された基本的なWebアプリケーションをプログレッシブWebアプリケーション(PWA)に変換する方法を見てみましょう。
この小さなWebアプリケーションの作成に費やされた合計時間の観点から、おそらく2〜3週間程度だったと思います。 ただし、夕方に30〜60分のスナッチで行われたため、最初のコミットから2018年8月に「1.0」バージョンと見なすものをアップロードするまでに実際には約1年かかりました。アプリを入手したので機能が完了しました」、またはもっと簡単に言えば、私が満足した段階で、私は大規模な最終プッシュを期待していました。 ほら、私はアプリケーションをプログレッシブWebアプリケーションにするために何もしていませんでした。 結局のところ、これは実際にはプロセス全体の中で最も簡単な部分でした。
プログレッシブWebアプリケーションの作成
幸いなことに、JavaScriptを利用した小さなアプリを「プログレッシブウェブアプリ」に変えることになると、生活を楽にするためのツールが山ほどあります。 このシリーズのパート1に思いを馳せれば、プログレッシブWebアプリであるということは、一連の基準を満たすことを意味することを思い出してください。
Webアプリケーションがどのように測定されるかを把握するには、最初に立ち寄るのはおそらくGoogleChromeのLighthouseツールです。 プログレッシブウェブアプリの監査は、[監査]タブにあります。
これは、私が最初に灯台を出入りしたときに灯台が私に言ったことです。
当初、イン/アウトはプログレッシブWebアプリで55⁄100のスコアしか得ていませんでした。 しかし、私はそこから1時間足らずで100⁄100にそれを取りました!
そのスコアを改善するための便宜は、私の能力とはほとんど関係がありませんでした。 それは、Lighthouseが何をする必要があるかを正確に教えてくれたからです。
必要な手順の例: manifest.json
ファイル(基本的にはアプリに関するメタデータを提供するJSONファイル)を含め、ヘッドに多数のメタタグを追加し、CSSにインライン化された画像を標準のURL参照画像に切り替えます。たくさんのホーム画面画像を追加します。
多数のホーム画面イメージの作成、マニフェストファイルの作成、および一連のメタタグの追加は、1時間以内に行うのは大変なことのように思えるかもしれませんが、Webアプリケーションの構築に役立つすばらしいWebアプリケーションがあります。 なんて素敵なことでしょう。 https://app-manifest.firebaseapp.comを使用しました。 アプリケーションとロゴに関するデータをフィードし、[送信]をクリックすると、必要なものがすべて含まれているzipファイルが提供されます。 そこからは、コピーアンドペーストの時間です。
知識不足のためにしばらく延期していたサービスワーカーのようなものも、https://serviceworke.rsのようなサービスワーカー専用の多数のブログ投稿やサイトのおかげで、かなり簡単に追加されました。 サービスワーカーが配置されているということは、アプリがオフラインで動作できることを意味します。これは、プログレッシブWebアプリケーションの必須機能です。
アプリケーションをPWAにすることと厳密には関係ありませんが、Chrome DevToolsの[カバレッジ]タブも非常に便利でした。 何ヶ月にもわたって設計とコードを散発的に繰り返した後、冗長なコードがどこにあるかを明確に示すことができました。 単に忘れていたコードベースを散らかしている古い関数をいくつか見つけました!
簡単に言えば、灯台の監査の推奨事項に取り組んだことで、私は先生のペットのように感じました。
現実には、アプリケーションを取得してプログレッシブWebアプリケーションにすることは、実際には非常に簡単でした。
その最後の開発が終わったので、私は小さなアプリケーションを私のWebサイトのサブドメインにアップロードしました。それだけでした。
ふりかえり
私の小さなWebアプリケーションの開発を開始してから数か月が経過しました。
それ以来、私はこのアプリケーションを何気なく使用してきました。 現実は、私が今でもテキストメッセージで行っているチームスポーツ組織の多くです。 ただし、このアプリケーションは、ゲームの夜ごとに紙切れを見つけるよりも、誰が出入りしているかを書き留めるよりも間違いなく簡単です。
ですから、真実はそれが不可欠なサービスではないということです。 また、開発や設計の基準も設定していません。 私も100%満足しているとは言えませんでした。 私はちょうどそれを放棄することができて幸せなところに到達しました。
しかし、それは演習のポイントではありませんでした。 私はその経験から多くを学びました。 以下は、私が最も重要なポイントと考えるものです。
デザインは開発です
当初、私はデザインを十分に評価していませんでした。 このプロジェクトを開始したのは、パッドとペンを使用したスケッチやSketchアプリケーションでのスケッチに費やした時間は、コーディングに費やしたほうがよい時間だと信じていたからです。 しかし、私がコードに直行したとき、私はしばしば忙しい愚か者でした。 可能な限り低い忠実度で最初に概念を探求することで、長期的にははるかに多くの時間を節約できました。
最初は、ユーザーエクスペリエンスの観点から根本的に欠陥があることに気付くために、コードで何かを動作させるために何時間も費やされたことが何度もありました。
私の意見では、紙と鉛筆は最高の計画、設計、コーディングツールです。 直面したすべての重大な問題は、主に紙と鉛筆で解決されました。 テキストエディタは、ソリューションを実行するための単なる手段です。 紙の上で意味のあるものがなければ、コードで作業する可能性はありません。
次に感謝することを学びましたが、なぜ理解するのにそれほど時間がかかったのかわかりませんが、デザインは反復的であるということです。 私は無意識のうちに大文字の「D」を持つデザイナーの神話を取り入れました。 誰かがぶらぶらして、シャープペンシルをまっすぐな端で持ち上げ、書体について叙情的にワックスをかけ、平らな白(豆乳を含む)をすすりながら、何気なく出産する前に、視覚的な完璧さを世界に完全に形成しました。
これは、「天才」プログラマーの概念とは異なり、神話です。 デザインは初めてですが、手を試しているのであれば、興奮を誘う最初のアイデアにとらわれないことをお勧めします。 バリエーションを試すのはとても安いので、その可能性を受け入れてください。 In / Outのデザインについて私が気に入っているものは、最初のデザインにはありませんでした。
「本は書かれておらず、書き直されている」という格言を生み出したのは、小説家のマイケル・クライトンだったと思います。 すべての創造的なプロセスは本質的に同じであることを受け入れます。 プロセスを信頼することで不安や練習が減り、審美的な理解と判断が洗練されることに注意してください。
あなたはあなたのプロジェクトの他の開発者です
これが散発的にしか作業されないプロジェクトに特有であるかどうかはわかりませんが、私は次のばかげた仮定をしました:
「これは私だけなので、文書化する必要はありません。もちろん、私が書いたので理解できます。」
真実と違うことがあってはならない!
30分間、プロジェクトに取り組まなければならなかった夜がありました。私は6か月前に書いた関数を理解しようとするだけでした。 コードの方向転換に時間がかかった主な理由は、質の高いコメントがないことと、変数と関数の引数の名前が適切でないことでした。
私は日常業務でコードにコメントすることに非常に熱心であり、他の誰かが私が書いていることを理解する必要があるかもしれないことを常に意識しています。 しかし、この場合、私は他の誰かでした。 6か月の間に書いたコードのブロックがどのように機能するかを本当に覚えていると思いますか? あなたはしません。 これについて私を信じて、少し時間を取って、そのことをコメントしてください!
それ以来、「あなたの構文ハイライトはコメントの重要性に関して間違っています」というタイトルのブログ投稿を読みました。 基本的な前提は、構文ハイライターがコメントをフェードアウトさせてはならないということです。それらは最も重要なものでなければなりません。 私は同意する傾向があり、そのかゆみを傷つけるコードエディタのテーマがすぐに見つからない場合は、自分でその目的に適合させる必要があるかもしれません!
デバッグ
バグに遭遇し、すべてのコードを記述した場合、エラーがキーボードと椅子の間で発生している可能性が高いことを示唆するのは不公平ではありません。 ただし、それを仮定する前に、最も基本的な仮定でさえテストすることをお勧めします。 たとえば、コードが原因であると想定した問題を修正するのに2時間以上かかったことを覚えています。 iOSでは、入力ボックスにテキスト入力を受け入れることができませんでした。 なぜそれが以前に私を止めなかったのかは覚えていませんが、この問題に対する私の欲求不満は覚えています。
Safariのバグが原因であることが判明しましたが、まだ修正されていません。 あなたが持っている場合、Safariでそれがわかります:
* { user-select: none; }
スタイルシートでは、入力ボックスは入力を受け取りません。 これを回避するには、次の方法を使用します。
* { user-select: none; } input[type] { user-select: text; }
これは、「アプリのリセット」CSSリセットで採用するアプローチです。 しかし、これの本当に苛立たしい部分は、私がこれをすでに学び、その後それを忘れていたことでした。 問題のトラブルシューティング中にWebKitのバグ追跡を確認することにようやく取り掛かったとき、1年以上前にバグレポートスレッドに回避策を書き、削減を完了したことがわかりました。
データを使って構築したいですか? JavaScript配列メソッドを学ぶ
おそらく、このアプリ構築の演習を行うことで私のJavaScriptスキルが得た最大の進歩は、JavaScript配列メソッドに慣れることでした。 私は今、すべての反復とデータ操作のニーズにそれらを毎日使用しています。 map()
、 filter()
、 every()
、 findIndex()
、 find()
、 reduce()
などのメソッドがどれほど有用であるかを十分に強調することはできません。 それらを使用すると、事実上すべてのデータの問題を解決できます。 まだ武器庫にない場合は、https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Arrayをブックマークして、できるだけ早く掘り下げてください。 私が好む配列メソッドの概要は、ここに記載されています。
ES6は、 Set
、 Rest
、 Spread
など、配列を操作するための他の時間節約機能を導入しました。 私が1つの例を共有している間、私を甘やかしてください。 単純なフラット配列からでも重複を削除したい場合は、以前はたくさんの問題がありました。 もう違います。
重複エントリ「MrPink」を持つ配列のこの単純な例を考えてみましょう。
let myArray = [ "Mr Orange", "Mr Pink", "Mr Brown", "Mr White", "Mr Blue", "Mr Pink" ];
ES6 JavaScriptで重複を取り除くには、次のようにします。
let deDuped = [...new Set(myArray)]; // deDuped logs ["Mr Orange", "Mr Pink", "Mr Brown", "Mr White", "Mr Blue"]
以前はソリューションを手作業でローリングしたり、ライブラリにアクセスしたりする必要があったものが、今ではその言語に組み込まれています。 確かに、それほど大したことではないように聞こえるかもしれませんが、何百ものエントリと重複がある配列を見るときにどれだけの時間を節約できるか想像してみてください。
メンテナンスとセキュリティ
ビルドツールのためだけであっても、NPMを使用してビルドするものはすべて、セキュリティの問題に対して脆弱である可能性があります。 GitHubは、潜在的な問題を認識し続けるための優れた機能を果たしますが、それでもメンテナンスの負担があります。
単なる副次的なプロジェクトである場合、これは活発な開発に続く数か月および数年で少し苦痛になる可能性があります。
現実には、セキュリティの問題を修正するために依存関係を更新するたびに、ビルドが破損する可能性があります。
何ヶ月もの間、私のpackage.json
は次のようになりました:
{ "dependencies": { "gulp": "^3.9.1", "postcss": "^6.0.22", "postcss-assets": "^5.0.0" }, "name": "In Out", "version": "1.0.0", "description": "simple utility to see who's in and who's out", "main": "index.js", "author": "Ben Frain", "license": "MIT", "devDependencies": { "autoprefixer": "^8.5.1", "browser-sync": "^2.24.6", "cssnano": "^4.0.4", "del": "^3.0.0", "gulp-htmlmin": "^4.0.0", "gulp-postcss": "^7.0.1", "gulp-sourcemaps": "^2.6.4", "gulp-typescript": "^4.0.2", "gulp-uglify": "^3.0.1", "postcss-color-function": "^4.0.1", "postcss-import": "^11.1.0", "postcss-mixins": "^6.2.0", "postcss-nested": "^3.0.0", "postcss-simple-vars": "^4.1.0", "typescript": "^2.8.3" } }
そして2019年6月までに、GitHubから次の警告が表示されていました。
私が直接使用していたプラグインに関連するものはありませんでした。それらはすべて、私が使用したビルドツールのサブ依存関係でした。 これがJavaScriptパッケージの両刃の剣です。 アプリ自体に関しては、In / Outに問題はありませんでした。 プロジェクトの依存関係を使用していませんでした。 しかし、コードがGitHubにあるので、私は物事を修正しようとする義務があると感じました。
package.jsonにいくつかの選択肢を変更することで、パッケージを手動で更新することができます。 ただし、YarnとNPMの両方に独自の更新コマンドがあります。 私はyarnupgrade yarn upgrade-interactive
を実行することを選択しました。これにより、ターミナルから物事を更新する簡単な手段が得られます。
簡単そうに見えますが、どの更新が最も重要かを示す小さな色付きのキーもあります。
--latest
フラグを追加して、パッチが適用された最新バージョンだけでなく、依存関係の最新のメジャーバージョンに更新できます。 ペニーのために…
問題は、JavaScriptパッケージの世界では物事が速く進行するため、いくつかのパッケージを最新バージョンに更新してからビルドを試みると、次のようになります。
そのため、 package.json
ファイルをロールバックし、今回は--latest
フラグを指定せずに再試行しました。 それは私のセキュリティ問題を解決しました。 正直に言うと、月曜日の夜に私が過ごした中で最も楽しいことではありません。
これは、サイドプロジェクトの重要な部分に触れています。 あなたの期待に現実的であること。
サイドプロジェクト
あなたが同じかどうかはわかりませんが、気の利いた楽観主義と興奮が私にプロジェクトを開始させ、もしあれば、恥ずかしさと罪悪感が私にプロジェクトを終わらせてくれることを発見しました。
暇なときにこの小さなアプリケーションを作った経験は楽しかったと言っても過言ではありません。 誰にも口を開かないようにしたいと思うことがありました。 しかし、今ではそれが完了しました。私は、投資する価値があると100%確信しています。
とはいえ、直面している問題を理解して解決するのにかかる時間を現実的に考えることで、このようなサイドプロジェクトに対するフラストレーションを軽減することができます。 週に数泊、1泊30分しかありませんか? サイドプロジェクトを完了することはできます。 あなたのペースが氷のように感じても、ただ不満を抱かないでください。 物事があなたの完全な注意を楽しむことができないならば、あなたがおそらく慣れているよりもゆっくりと着実なペースに備えてください。 それは、コーディング、コースの修了、ジャグリングの学習、または小さなWebアプリケーションの作成に非常に時間がかかった理由に関する一連の記事の作成のいずれであっても当てはまります。
シンプルな目標設定
あなたは目標設定のための凝ったプロセスを必要としません。 しかし、それは物事を小さな/短いタスクに分解するのに役立つかもしれません。 「ドロップダウンメニューのCSSを書く」のような単純なことは、限られた時間の中で完全に達成可能です。 一方、「状態管理のデザインパターンを調査して実装する」ことはおそらくそうではありません。 物事を分解します。 次に、レゴのように、小さなピースが一緒になります。
このプロセスをより大きな問題を切り刻むものとして考えると、有名なビル・ゲイツの引用を思い出します。
「ほとんどの人は、1年でできることを過大評価し、10年でできることを過小評価しています。」
これは、ポリオ撲滅に貢献している男性からのものです。 ビルは自分のものを知っています。 Billy'allを聞いてください。
何かを出荷することは、何も出荷しないことよりも優れています
このWebアプリケーションを「出荷」する前に、私はコードを確認し、完全にがっかりしました。
私は完全な素朴さと経験の浅い点からこの旅に出ましたが、コードをどのように設計するか(あなたが非常に壮大な用語を許すなら)に関しては、いくつかのまともな選択をしました。 私はデザインパターンを研究して実装し、そのパターンが提供するすべてのものを楽しんでいました。 悲しいことに、私はプロジェクトを終わらせるためにもっと必死になったので、規律を維持することができませんでした。 現状のコードは、アプローチの真の寄せ集めであり、非効率性に満ちています。
私が気付いてから数ヶ月で、それらの欠点は実際には問題ではありません。 あまり。
私はヘルムート・フォン・モルトケからのこの引用のファンです。
「主な敵対勢力との最初の接触を超えて、確実に拡張される作戦計画はありません。」
これは次のように言い換えられています。
「敵との最初の接触を生き残る計画はありません」。
おそらく、私たちはそれをさらに煮詰めて、単に「たわごとが起こる」と行くことができますか?
私は、次の例えで出荷されたものに同意したと推測できます。
友人が最初のマラソンに挑戦することを発表した場合、フィニッシュラインを乗り越えることが重要になります。私は彼らのフィニッシュタイムを非難することはありません。
私は最高のWebアプリケーションを書き始めませんでした。 私が自分で設定した使命は、単にそれを設計して作ることでした。
具体的には、開発の観点から、Webアプリケーションの構築方法の基礎を学びたいと思いました。 デザインの観点から、私は自分自身のためにいくつかの(単純ではありますが)デザインの問題を試してみたかったのです。 この小さなアプリケーションを作成することで、これらの課題といくつかの課題に対応しました。 アプリケーション全体のJavaScriptはわずか5KB(gzip圧縮)でした。 ファイルサイズが小さいので、どのフレームワークでもうまくいきません。 多分Svelteを除いて。
この種の課題を自分で設定していて、ある時点で何かを「出荷」することを期待している場合は、最初に、なぜそれを行っているのかを書き留めてください。 あなたの心の最前線にそれらの理由を保ち、それらによって導かれます。 すべては最終的にはある種の妥協です。 高尚な理想があなたがやろうとしていることを終えることからあなたを麻痺させてはいけません。
概要
全体として、イン/アウトに取り組んでから1年が経ちますが、私の気持ちは大きく3つに分類されます。後悔したこと、改善/修正したいこと、そして将来の可能性です。
後悔したこと
すでにほのめかされているように、アプリケーションの状態を変更してDOMにレンダリングする、より洗練された方法と考えていた方法に固執していなかったのでがっかりしました。 このシリーズの第2部で説明したように、予測可能な方法で非常に多くの問題を解決したオブザーバーパターンは、プロジェクトの「出荷」が優先されるようになったため、最終的には破棄されました。
最初は自分のコードに戸惑いましたが、その後数か月で哲学的になりました。 後で歩行者用のテクニックをこれ以上使用していなかったとしたら、プロジェクトが終了しなかった可能性が非常に高くなります。 改善が必要な何かを世界に持ち出すことは、それがまったく世界に生まれることがないよりも、それでも気分が良くなります。
イン/アウトの改善
セマンティックマークアップを選択する以外に、私はアクセシビリティのためのアフォーダンスをしませんでした。 イン/アウトを構築したとき、私は標準のWebページのアクセシビリティに自信を持っていましたが、アプリケーションに取り組むのに十分な知識がありませんでした。 私は今、その分野ではるかに多くの仕事/研究を行ってきたので、このアプリケーションをよりアクセスしやすくするためのまともな仕事をするために時間を割いて楽しんでいます。
「個人の追加」機能の改訂された設計の実装が急いでいました。 それは災害ではなく、私が望むよりも少し荒いです。 それを滑らかにするといいでしょう。
また、大画面についても考慮していません。 単にコンテンツのチューブにするだけでなく、より大きなサイズで機能させるという設計上の課題を検討することは興味深いことです。
可能性
localStorageの使用は私の単純なニーズには有効でしたが、「適切な」データストアがあればいいので、データのバックアップについて心配する必要はありませんでした。 ログイン機能を追加すると、ゲーム組織を別の個人と共有する可能性も広がります。 それとも、すべてのプレーヤーが自分でプレイしているかどうかをマークすることができますか? このような単純で謙虚な始まりから、探索する道がいくつあるかは驚くべきことです。
iOSアプリ開発用のSwiftUIも興味深いものです。 Web言語を扱ったことがない人にとって、SwiftUIは、一見すると、私が今や大胆に試しているもののように見えます。 SwiftUIを使用してIn / Outを再構築してみてください。開発の経験と結果を構築して比較するために、特定の何かを用意するだけです。
それで、物事をまとめて、これらすべてのTL; DRバージョンを提供する時が来ました。
Webで何かがどのように機能するかを知りたい場合は、抽象化をスキップすることをお勧めします。 フレームワークがCSSであろうとJavaScriptであろうと、フレームワークが何を意味するのかを本当に理解するまで、フレームワークを捨ててください。
設計は反復的であり、そのプロセスを受け入れます。
自由に使える最低忠実度の媒体で問題を解決します。 Sketchでアイデアをテストできる場合は、コードに移動しないでください。 ペンと紙を使用できる場合は、Sketchで描画しないでください。 最初にロジックを書き出します。 次に、それをコードで記述します。
現実的であるが、決して落胆しないでください。 1日30分ほどで何かを削る習慣を身につけると、結果を得ることができます。 その事実は、あなたの探求がどんな形であれ真実です。