2023年6月6日にオンラインメンタリングサービスMENTAにて有料メンタリング契約を締結し、3か月でWEBアプリ開発のいろはを習得し 就職に備える計画を立てました。メンターは組織化しており、独自のノウハウにより作成された個別学習カリキュラムにて3か月学習を 行ってきました。3か月のメンタリングサービスは、週1回のオンライン面談と、スラック質問への24時間対応です。
メンター付き学習の3か月間は、Visual Studio Code、Command Line、Git、GitHub、Google Chrome 検証ツール、 JavaScript、JavaScript DOM、TypeScript、React、Next.jsについて主に 学習してきました。ちなみに本サイトは、Next.js、TypeScriptにより作成しています。
アプリ開発についてはReactも含めて、これまで独学でプロゲートやUdemyで学習を行なってきたものの、学習プラットフォームに準備 されたアプリを操作するだけで、アプリケーションを自分のPCのローカル環境で作成する方法が全くわかりませんでした。そんな中、 独学エンジニアというサブスクリプションで独学でアプリ開発に着手したのですが、パッケージのバージョンの違いなどにより多発するエラーを自己解決することが できず悩んでいた時にMENTAに出会った次第です。
パッケージ、ライブラリ、フレームワーク等のバージョン違いを解決するために、npmやyarnといったパッケージマネージャーが存在する ことを知り、それらを操作することでエラーを解決し開発環境を整えることは、アプリ開発において重要なことであることを痛感しています。
3か月の学習後、大阪のアプリ開発会社に就職し、そこで1.5か月間の実務経験を積むことができました。 その内容はLaravel/TypeScriptシステムのコード改修とテストですが、その間に、GitHub、Docker、CodeIgniter4、PhpStormの操作方法や、bash、build、npm run devなどのコマンドの使い方、 PHPアプリ、JavaScriptアプリそれぞれのブラウザへの表示方法を習得いたしました。
その会社を退職後、フルスタックアプリ開発の習得を目的とし再度独学を開始し、2023年11月20日現在、Next.js、Express(Node.js)、Prisma、AWSを使用したTodoリストの開発 (教材を見ながらのトレーニング)を完了しました(Vol.15)。一番の悩みは実装力不足です。つまり、自分で機能を実装するロジックを組むことが苦手であることです。特に、 フロントエンドとバックエンド、データベースを連携するようなアプリだとなおのこと実装が困難です。しかしなんとか、またしてもMENTAのアドバイスをもらいながら、2024年 1月の約1か月でオリジナルアプリを完成することができました。とはいうものの、新規ユーザーのゲームデータの格納、ゲームデータのブラウザ表示などの実装が未完了であり、 デプロイはしたものの、課題は山積みです。
フロントエンドをNext.js、TypeScriptで作成し、データベースをFirebase Firestoreで、 グーグル認証をFirebase Authenticationで実装いたしました。まず46文字のひらがなのローマ字データをcsvパーサーによりFirestoreに追加し、それをランダムにブラウザに表示することで出題機能を実装。そして、Firestoreの関数であるgetDocsとmap関数により出題 ローマ字の示すひらがな文字1文字と間違えの文字1文字を、2つの選択肢ひらがなカードとしてランダム表示することで解答機能を実装し、文字毎のゲームデータ(正解数、不正解数、出題数、正解率)をFirestoreに格納します。また、useEffectによりBGMを流し、playメソッドによりボタンクリック時の効果音を出すなど、学習者のモチベーションを維持する工夫をこらしました。
一先ず、Node.jsサーバーをTypeScriptベースで構築し、Postmanを使ってエンドポイントが正しく 機能しているかAPIテストを実行し、Prismaでデータベースを管理(リレーショナルマッピング)。Node.jsのフレームワークであるExpressを用いてCRUDのAPIを構築し、ローカル環境で実装後、本番環境としてフロントエンドをAWS Amplifyに、バックエンドをAWS App Runnerにフルスタックデプロイ。デプロイ時の環境変数の取り扱い(App Runnerのデフォルトドメインを、AmplifyのAPI URLとして設定)について学習。 また、Amplifyデプロイの際にビルドで失敗しましたが、これはNext.js14のNode.jsサポート範囲の変更に起因するものということで、ビルドイメージの設定を変更することにより解決しました。デプロイ後、ブラウザで データ更新し、バックエンドのデータ管理状態をブラウザで確認することが実現できました(App Runnerを一時停止すると、データが表示されなくなります)。
Glitch(開発用SaaS)を用いたオンラインスクールサイトモックアップです。 PHPファイル、CSSファイル、JSファイルで成り立っています。ヘッダー、フッター等の共通パーツをPHPファイルでテンプレート化し、
入力フォームのエラー表示・ページ遷移、学習日数の表示をJavaScriptで、カレンダーの実装をjQueryで行なっています。Glitchのちょっとした 設定変更によりPHPファイルの実装が容易に可能となっています。ヘッダーからは、会員登録ボタン、ログインボタンをそれぞれ押下して頂くと、会員登録、ログイン画面に遷移し、入力内容確認画面表示後、マイラーニング画面に遷移します。フッターでは、 サイトマップのみ別タプで表示され、また、会員登録画面からは、会員規約が別タブで表示されるようになっています。これらの機能の実装は全てJavaScriptによります。
Next.jsによるTODOリストです。サインアップページは'/signup'です。こちらでユーザー登録して頂くと、TODOリストのメインページ '/' に遷移し、ログアウトするとログインページ'/login' に遷移します。 Next.jsのルーター機能を活用するためにuseRouterフックを使用しています。これはページ間のナビゲーションやコンポーネントの表示切り替えなどのルーティング 関連のタスクを実行するのに役立っています。また、本アプリはバージョン13のappルーティングではなくバージョン12のpagesルーティングを利用しており、コンポーネント内でルーター情報にアクセスするためのuseRouterと、特定URLに対応するpagesルーティングの両者が連携してルーティングとナビゲーションを制御しています。 そしてFirebaseのAuthentificationを導入しメールアドレスとパスワードでの認証を行なっています。 登録ユーザーの情報はFirebaseコンソールで確認することができます。サインイン済みのユーザーをサインインページからログインページに、あるいはログアウト後のユーザーをログインページにリダイレクトするなどの制御を行っています。 UIコンポーネントライブラリーとしてChakura UIを使用しており、UIコンポーネントのデザインに一貫性を持たせています。また、Firebase/FirestoreによりクライアントでインプットされたデータをFirebaseデータベースに渡しています。 Next.jsのアプリはホスティング時のエラー解決が困難で、ローカル環境に眠っているアプリが複数ありますが、このアプリはnpm run build時に発生するエラーを解決することでホスティングが可能になりました。
Vol.11をTypeScriptで再作成しました。interfaceを用いて型定義しています。
lockファイルが二つ存在している点はバージョン競合、保守性低下、共同作業の困難さの点で改善すべきところですが、未実施です。react-beautiful-dndというライブラリからDraggableやDroppableのコンポーネントをインポートし、カードのドラッグアンドドロップを実現しています。
環境変数を.envファイルに分けて設定しバージョン管理から除外することで、機密情報の漏洩を防いでいます。FirebaseのFirestore機能を使い、useEffectフックとfetchData関数によりFirebaseデータベースからデータを非同期に取得し、Reactコンポーネントのtodosステートに更新してデータを表示しています。 UIコンポーネントにMaterial UIを使用しています。Firebaseの設定は初期化、環境変数を含め慣れるまで何度も繰り返しました。
filteringTodos関数内でスイッチ文を用い、filterの値によって、つまり、フィルターされたTODOがどの状態であるか(未着手、作業中、完了)によって表示するTODOを切り替える設定を行なっています。そのほか、voidを用いた関数(props)の型定義や、set関数に対するReact.Dispatchによる型定義を実施しました。 また、styleプロパティにより特定の要素に個別のインラインスタイルを適用しています。4つのコンポーネントに切り分け、App.tsxで呼び出しています。
TODOの各要素(inputValue、id、checked)のオブジェクト型による型定義や、引数e、ステートなどのお決まりの型定義方法に若干慣れてきたため、TypeScriptアプリのコンポーネント化も実施できました。条件演算子によりTODOリストが空の場合は&apos登録されたTODOはありません&aposと文字列を返すよう設定しています。
こちらもコンポーネント化未実施のTypeScriptによるTODOリストです。checkedパラメータは現在のチェック状態を表し、関数handleCheckedによりTODO要素のチェック状態をトグルしています。disabled属性は、todo.checkedの値がtrueの場合入力フィールドを無効にします。
JavaScriptで作成したアプリケーションをTypeScriptに移行する際に厳格な型チェックによるエラー続出でエラーを解決するのに相当 苦労しました。その解決策として、TODO入力フィールド、作成ボタン、TODO表示、完了ボタンだけの最もシンプルなTODOリストをイチから作成して みたところ、それぞれの関数・メソッド・フック・ステート(props)の渡し方についての理解を深めながら、TypeScriptにおける型定義を 学習することができました。また、TODOの入力フィールドが空の場合は関数を実行しないこと(バリデーション)、TODOの更新後は入力 フィールドを初期値に戻すこと(ステートのクリア)について学習しました。
未完了/完了TODOリストをそれぞれ表示するものをTypeScriptで直書きで作成。エラーに対応できず、コンポーネント化は実施できませんでした。UIコンポーネントとしてMaterial UIを用い、スタイリッシュなフォームフィールドとボタンを設置しました。 TODOリストの各要素(inputValue、id、checked)の型をカスタム型として定義しています。こちらもエラーによりコンポーネント化が実施できませんでした。
useEffectフックにより、データの取得、外部ライブラリとの統合、コンポーネントの状態の変更などコンポーネントの外部とやり取りする多くのタスク(副作用)を実行します。 App.jsに各種ステート関数を定義し、InputFormとEditFormの2つのコンポーネントを設置。多くのpropsを渡しています。App.js内returnの冒頭で、三項演算子により、ステートisEditableがtrueなら、EditFormコンポーネント(編集要素)を出力し、 falseなら、InputFormコンポーネント(入力要素)とSelectコンポーネント(todoステータスのプルダウンリスト)を出力するように定義しています。尚、イベントハンドラーにおいて引数eを定義し、テキスト入力フィールドの値が変更された時にe.target.valueによりその値を受け取ります。 オブジェクトとしてスタイルを定義し、それを要素のstyle属性に設定することで要素のスタイルを制御しています。select要素によりTODO要素のステータスを示すドロップダウンリストを作成しています。
Twitterクローンアプリです。UIコンポーネントライブラリにmaterial UIを使用しTwitterの各UIコンポーネントを利用しています。Firebase/Firestoreにより、インプットされたデータをデータベースに渡しています。react-twitter-embedライブラリを活用し、Twitterのタイムライン、ツイート埋め込み、ツイートのシェアボタンなど、TwitterウィジェットをReactコンポーネントとしてアプリケーションに組み込んでいます。
...prevTodosはスプレッド構文を使用して前回のTODOリストの要素をコピーし、新しいTODOを追加することでprevTodos配列の要素を展開します。useRefフックを使用してReactコンポーネント内のDOM要素(テキスト入力フィールド)への参照を保持し現在の値を取得、そしてcurrent.valueをnullにしクリアします。尚TODO配列の要素を識別するためにuuidを活用しています。これは、配列の要素を識別するための世界的に一意である可能性が極めて高い識別子です。map関数を使いtodos配列内の各TODO要素をループ処理し、Todoコンポーネントに渡しています。keyプロパティにはtodo.idを指定しています。また、コンポーネント内に各関数を定義していますが、filter関数を使用してtodos配列内のTODO要素をフィルタリングし、!todo.completed(完了していないTODO要素のみを新しい配列に残しています。
高速動作が可能といわれるビルドツールViteでReactライブラリを用いてTODOアプリを作成しました。 Reactプロジェクトはindex.htmlのdiv要素(ID:root)をエントリーポイントとし、App.jsxが documentGetElementByIdメソッドでそのDOM要素を取得し、そこにコンポーネントツリーをレンダリングします。 TODO入力用のInputFormと編集用のEditFormにコンポーネントを分け、App.jsxで呼び出しています。useStateフック(第一引数に現在の状態、第二引数に状態を管理する関数、そして初期値を設定)により、 TODOに変更があった際に再レンダリングします。各コンポーネントはinputとbutton要素で構成され、その中に onChangeやonClick属性を定義しボタンクリックや入力内容更新に基づくイベントハンドラーを実行し、TODOのCRUD操作(create, read, update, delete)を可能にしています。