- 投稿日:2021-06-21T23:25:48+09:00
なぜrequire又はimportができない?!(a.k.awebpack投入の理由)
0. 当時の環境 C:\git\keepOnEye_money>node -v v12.18.4 C:\git\keepOnEye_money>npm -v 6.14.6 エラーモメント ライブラリーをインストールは無事完了。 C:\git\keepOnEye_money>npm install pinyin > nodejieba@2.5.2 install C:\git\node_modules\nodejieba > node-pre-gyp install --fallback-to-build [nodejieba] Success: "C:\git\node_modules\nodejieba\build\Release\nodejieba.node" is installed via remote npm WARN saveError ENOENT: no such file or directory, open 'C:\git\package.json' npm WARN enoent ENOENT: no such file or directory, open 'C:\git\package.json' npm WARN git No description npm WARN git No repository field. npm WARN git No README data npm WARN git No license field. + pinyin@2.10.2 added 60 packages from 97 contributors and audited 306 packages in 10.529s 19 packages are looking for funding run `npm fund` for details found 0 vulnerabilities 2 packages are looking for funding run `npm fund` for details found 0 vulnerabilities ドキュメントのサンプールコードを叩いてみよう。 app.js var unirest = require('unirest'); でも画面では効かないよう、、 Uncaught ReferenceError: require is not defined 原因はCommonJSとes6の違い(と思いきや違ったことを後でわかる) とても親切な説明がありまして貼っておくと、 https://zenn.dev/naoki_mochizuki/articles/46928ccb420ee733f78f 要するに commonJS: requireが es06: importで使うことになる なので特にどっちを選んでも機能は同じのこと。 試しにimportに変えてみた。 app.js import unirest from 'unirest'; Uncaught SyntaxError: Cannot use import statement outside a module モジュール関係の問題らしい、、 webpackの登場。 簡単に言いますと、散らかっているモジュルを一つにまとめてくれるもの。開発環境とブラウザーは環境が違うため、ブラウザーで表現したい機能の実現のために開発環境から必要道具(?)をまとめて送る必要がある。 袋みたいに一つにまとめるものの認識。 webpackをセットアップしてみよう。 npm init npm i -D webpack webpack-cli 上記のコマンドを作成してwebpack.config.jsを生成、中身を埋める。 const path = require('path'); module.exports = { mode: 'production', // or "development" or "none", output: { filename: 'bundle.js', path: path.resolve(__dirname, './dist'), }, entry:{ main : "./app.js" }, }; HTMLのjsパスをOUTPUTのパスに修正する。 index.html <!-- <script src="app.js"></script> --> <script src="./dist/bundle.js"></script> package.jsonへwebpack実行用コマンドを追加する。 package.json "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, 最後に確認用コードを追加してみる app.js var pinyin = require("pinyin"); console.log(pinyin("中心")); それでは実行してみようー! npm run build できました!! なぜlibraryのrequire(import)が効かなかった?はnode.js はサーバーの言語なのでfrontのブラウザーと話すことがが違う とのことでした。今のエラーはnode.jsのみの環境だと問題なしと思われて、画面側に持ち出した時の問題だったこと!
- 投稿日:2021-06-21T23:19:10+09:00
FirestoreでMapオブジェクト内のフィールドに対してWhere検索する
はじめに 以下のような、Mapオブジェクトを持つコレクションに対してWhere句で条件指定してデータ取得するメモ。 自分用備忘録を兼ねる。(むしろそっちの目的が大きい) 検索方法 where('[フィールド名].[Mapオブジェクト内のフィールド名]' , '==' , 'hogehoge')のように指定する。 上の例だとwhere('data.name','==','hogehoge')とする。 以下Node.jsのサンプル const admin = require('firebase-admin'); admin.initializeApp(); const db = admin.firestore(); const hogehoge = db.collection('Hogehoge'); async function getHogehoge() { try { const querySnapShot = await hogehoge.where('data.name' , '==' , 'hogehoge').get(); // ここで条件指定する var datas = []; querySnapShot.forEach(async (d)=>{ datas.push(await d.data()); }); return datas; } catch(err) { throw err; } } module.exports = { getHogehoge: getHogehoge, }; 演算子==の部分は公式ドキュメントに載っている他の演算子も利用可能。 https://firebase.google.com/docs/firestore/query-data/queries?hl=ja#query_operators 上記のドキュメントにはMapオブジェクトに対するWhereの指定が明記されてないように見えたので一応自分用にメモとして興した。
- 投稿日:2021-06-21T22:43:08+09:00
Git-hub を使う!
Git とは何じゃ? ビッグカメラで買えるんか? すでにプログラミングを業務にされている諸先輩方は、今更なトピックかも知れませんが、プログラミングはじめました という入門者にとっては、GitやGit hubっていうのは、何やら世界のプログラマーが使う、怪しい秘密のプラットフォームで、色々なトラップが埋め込まれたハッカーの溜まり場的なイメージがあると思うのじゃ。 Gitっていうのは、ざっくり言うとプログラムの”バージョンコントロール”で、ドラクエで言う”セーブ”。教会で行うアレじゃ。 プログラムっていうのは、ほんの一文字で全てが崩壊する危機をはらんでおり、えらいことが起こった時に、その前に戻れるようにする機能のこと。 Git hubはそのデータをセーブしたり、管理したりするクラウドの場所。また、そのデータをチームで共有して、一緒に作業していく場。 今回はnodeのプロジェクトを解説していこうと思うので、その中でどう使うのかを解説してみるぞ。 どうやって使うんじゃ? まずはGitの機能を自分のコンピューターで使うために、ダウンロードしないと始まりません。 ビッグカメラでは売られていません。 ここからダウンロード↓ https://git-scm.com/ OSにインストールできたら、コマンドラインから以下のコマンドを打ってみましょう。バージョンが表示されたらインストールが出来てます。 /myProject$ git --version git version 2.25.1 次にする事は、Gitでトラックしたいプロジェクトの親フォルダを初期化する。そのフォルダ内のファイルがGitの監視下に入る。 myProject/$ git init Initialized empty Git repository in /home/ubuntu/myProject/spicy_mandarin/.git/ この時自動生成された隠れディレクトリ.gitリポジトリに、変更履歴などのデータが蓄積されていくが、git側が勝手に処理してくれるので、特に気にしなくて大丈夫。 リポジトリっていうのはフォルダみたいなもので、更新履歴やファイルもひっくるめて、Gitに関する全てが保存されてる場所。 これで準備はオーケー。 これでGitでファイルをトラックしたり、Git hubやサーバーにコマンド一つでプッシュ出来るようになったでござる。 Gitで使う主なコマンドは以下。 git status // ファイルの状態をみる git add ファイル名 // コミットするファイルに加える。また、新しく作ったファイルをGit監視下に加える時に使う。 git commit // コミット(変更をセーブ)する。 git push // コミットしたファイルと情報をGit hubなどのサードパーティーにアップ 流れとしては、statusで状態を確認して、addしてcommitしてpush! 何故addっていう作業を挟むかと言うと、commitはひとまとまりのファイルを一気にセーブするから、その束に加える必要がある。 で、Gitに一々変更をトラックさせる必要のないファイルや、Git hubなどにあげるとセキュリティ上問題のあるpornhub的なエッチなファイルやディレクトリは、.gitignoreというファイルを作って、そこに記述しておくと、 Gitの監視対象からは外される。 git:.gitignore node_modules/ myEroFiles/ コードを変更したり、新しいファイルを作ったり、ここらで一旦セーブって所で、add commit。 ローカルのgitリポジトリに変更が記録されていく。 で、次の作業はそれをgit hubにアプ。 バイトの時間が来たので、今回はここまでじゃ! 次回はSSHキーを作って、ローカルリポジトリをgit hubにアップするぞい。
- 投稿日:2021-06-21T22:43:08+09:00
ビッグカメラで買ったGit-hub を使う
Git とは何じゃ? ビッグカメラで買えるんか? すでにプログラミングを業務にされている諸先輩方は、今更なトピックかも知れませんが、プログラミングはじめました という入門者にとっては、GitやGit hubっていうのは、何やら世界のプログラマーが使う、怪しい秘密のプラットフォームで、色々なトラップが埋め込まれたハッカーの溜まり場的なイメージがあると思うのじゃ。 Gitっていうのは、ざっくり言うとプログラムの”バージョンコントロール”で、ドラクエで言う”セーブ”。教会で行うアレじゃ。 プログラムっていうのは、ほんの一文字で全てが崩壊する危機をはらんでおり、えらいことが起こった時に、その前に戻れるようにする機能のこと。 Git hubはそのデータをセーブしたり、管理したりするクラウドの場所。また、そのデータをチームで共有して、一緒に作業していく場。 今回はnodeのプロジェクトを解説していこうと思うので、その中でどう使うのかを解説してみるぞ。 どうやって使うんじゃ? まずはGitの機能を自分のコンピューターで使うために、ダウンロードしないと始まりません。 ビッグカメラでは売られていません。 ここからダウンロード↓ https://git-scm.com/ OSにインストールできたら、コマンドラインから以下のコマンドを打ってみましょう。バージョンが表示されたらインストールが出来てます。 /myProject$ git --version git version 2.25.1 次にする事は、Gitでトラックしたいプロジェクトの親フォルダを初期化する。そのフォルダ内のファイルがGitの監視下に入る。 myProject/$ git init Initialized empty Git repository in /home/ubuntu/myProject/spicy_mandarin/.git/ この時自動生成された隠れディレクトリ.gitリポジトリに、変更履歴などのデータが蓄積されていくが、git側が勝手に処理してくれるので、特に気にしなくて大丈夫。 リポジトリっていうのはフォルダみたいなもので、更新履歴やファイルもひっくるめて、Gitに関する全てが保存されてる場所。 これで準備はオーケー。 これでGitでファイルをトラックしたり、Git hubやサーバーにコマンド一つでプッシュ出来るようになったでござる。 Gitで使う主なコマンドは以下。 git status // ファイルの状態をみる git add ファイル名 // コミットするファイルに加える。また、新しく作ったファイルをGit監視下に加える時に使う。 git commit // コミット(変更をセーブ)する。 git push // コミットしたファイルと情報をGit hubなどのサードパーティーにアップ 流れとしては、statusで状態を確認して、addしてcommitしてpush! 何故addっていう作業を挟むかと言うと、commitはひとまとまりのファイルを一気にセーブするから、その束に加える必要がある。 で、Gitに一々変更をトラックさせる必要のないファイルや、Git hubなどにあげるとセキュリティ上問題のあるpornhub的なエッチなファイルやディレクトリは、.gitignoreというファイルを作って、そこに記述しておくと、 Gitの監視対象からは外される。 git:.gitignore node_modules/ myEroFiles/ コードを変更したり、新しいファイルを作ったり、ここらで一旦セーブって所で、add commit。 ローカルのgitリポジトリに変更が記録されていく。 で、次の作業はそれをgit hubにアプ。 バイトの時間が来たので、今回はここまでじゃ! 次回はSSHキーを作って、ローカルリポジトリをgit hubにアップするぞい。
- 投稿日:2021-06-21T22:43:08+09:00
ビッグカメラで買ったGit-hub を使う(初めてのgithub完全ガイド)
Git とは何じゃ? ビッグカメラで買えるんか? すでにプログラミングを業務にされている諸先輩方は、今更なトピックかも知れませんが、プログラミングはじめました という入門者にとっては、GitやGit hubっていうのは、何やら世界のプログラマーが使う、怪しい秘密のプラットフォームで、色々なトラップが埋め込まれたハッカーの溜まり場的なイメージがあると思うのじゃ。 Gitっていうのは、ざっくり言うとプログラムの”バージョンコントロール”で、ドラクエで言う”セーブ”。教会で行うアレじゃ。 プログラムっていうのは、ほんの一文字で全てが崩壊する危機をはらんでおり、えらいことが起こった時に、その前に戻れるようにする機能のこと。 Git hubはそのデータをセーブしたり、管理したりするクラウドの場所。また、そのデータをチームで共有して、一緒に作業していく場。 今回はnodeのプロジェクトを解説していこうと思うので、その中でどう使うのかを解説してみるぞ。 どうやって使うんじゃ? まずはGitの機能を自分のコンピューターで使うために、ダウンロードしないと始まりません。 ビッグカメラでは売られていません。 ここからダウンロード↓ https://git-scm.com/ OSにインストールできたら、コマンドラインから以下のコマンドを打ってみましょう。バージョンが表示されたらインストールが出来てます。 /myProject$ git --version git version 2.25.1 次にする事は、Gitでトラックしたいプロジェクトの親フォルダを初期化する。そのフォルダ内のファイルがGitの監視下に入る。 myProject/$ git init Initialized empty Git repository in /home/ubuntu/myProject/spicy_mandarin/.git/ この時自動生成された隠れディレクトリ.gitリポジトリに、変更履歴などのデータが蓄積されていくが、git側が勝手に処理してくれるので、特に気にしなくて大丈夫。 リポジトリっていうのはフォルダみたいなもので、更新履歴やファイルもひっくるめて、Gitに関する全てが保存されてる場所。 これで準備はオーケー。 これでGitでファイルをトラックしたり、Git hubやサーバーにコマンド一つでプッシュ出来るようになったでござる。 Gitで使う主なコマンドは以下。 git status // ファイルの状態をみる git add ファイル名 // コミットするファイルに加える。また、新しく作ったファイルをGit監視下に加える時に使う。 git commit // コミット(変更をセーブ)する。 git push // コミットしたファイルと情報をGit hubなどのサードパーティーにアップ 流れとしては、statusで状態を確認して、addしてcommitしてpush! 何故addっていう作業を挟むかと言うと、commitはひとまとまりのファイルを一気にセーブするから、その束に加える必要がある。 で、Gitに一々変更をトラックさせる必要のないファイルや、Git hubなどにあげるとセキュリティ上問題のあるpornhub的なエッチなファイルやディレクトリは、.gitignoreというファイルを作って、そこに記述しておくと、 Gitの監視対象からは外される。 git:.gitignore node_modules/ myEroFiles/ コードを変更したり、新しいファイルを作ったり、ここらで一旦セーブって所で、add commit。 ローカルのgitリポジトリに変更が記録されていく。 で、次の作業はそれをgit hubにアプ。 バイトの時間が来たので、今回はここまでじゃ! 次回はSSHキーを作って、ローカルリポジトリをgit hubにアップするぞい。
- 投稿日:2021-06-21T22:43:08+09:00
ビッグカメラで買ったGit-hub を使う(初めてのgithub完全ガイド1)
Git とは何じゃ? ビッグカメラで買えるんか? すでにプログラミングを業務にされている諸先輩方は、今更なトピックかも知れませんが、プログラミングはじめました という入門者にとっては、GitやGit hubっていうのは、何やら世界のプログラマーが使う、怪しい秘密のプラットフォームで、色々なトラップが埋め込まれたハッカーの溜まり場的なイメージがあると思うのじゃ。 Gitっていうのは、ざっくり言うとプログラムの”バージョンコントロール”で、ドラクエで言う”セーブ”。教会で行うアレじゃ。 プログラムっていうのは、ほんの一文字で全てが崩壊する危機をはらんでおり、えらいことが起こった時に、その前に戻れるようにする機能のこと。 Git hubはそのデータをセーブしたり、管理したりするクラウドの場所。また、そのデータをチームで共有して、一緒に作業していく場。 別記事ではnodeのプロジェクトを解説していこうと思うので、その中でどう使うのかを解説してみるぞ。 どうやって使うんじゃ? まずはGitの機能を自分のコンピューターで使うために、ダウンロードしないと始まりません。 ビッグカメラでは買えません。 ここからダウンロード↓ https://git-scm.com/ OSにインストールできたら、コマンドラインから以下のコマンドを打ってみましょう。バージョンが表示されたらインストールが出来てます。 myProject$ git --version git version 2.25.1 次にする事は、Gitでトラックしたいプロジェクトのメインフォルダを初期化する。そのフォルダ内のファイルがGitの監視下に入る。 今回はmyProjectディレクトリを制作。 myProject/$ git init Initialized empty Git repository in /home/ubuntu/myProject/spicy_mandarin/.git/ この時自動生成された隠れディレクトリ.gitリポジトリに、変更履歴などのデータが蓄積されていくが、git側が勝手に処理してくれるので、特に気にしなくて大丈夫。 リポジトリっていうのはフォルダみたいなもので、更新履歴やファイルもひっくるめて、Gitに関する全てが保存されてる場所。 これで準備はオーケー。 これでGitでファイルをトラックしたり、Git hubやサーバーにコマンド一つでプッシュ出来るようになったでござる。 Gitで使う主なコマンドは以下。 git status // ファイルの状態をみる git add ファイル名 // コミットするファイルに加える。また、新しく作ったファイルをGit監視下に加える時に使う。 git commit // コミット(変更をセーブ)する。 git push // コミットしたファイルと情報をGit hubなどのサードパーティーにアップ 流れとしては、statusで状態を確認して、addしてcommitしてpush! 何故addっていう作業を挟むかと言うと、commitはひとまとまりのファイルを一気にセーブするから、その束に加える必要がある。 で、Gitに一々変更をトラックさせる必要のないファイルや、Git hubなどにあげるとセキュリティ上問題のあるpornhub的なエッチなファイルやディレクトリは、.gitignoreというファイルを作って、そこに記述しておくと、 Gitの監視対象からは外される。 git:.gitignore node_modules/ myEroFiles/ コードを変更したり、新しいファイルを作ったり、ここらで一旦セーブって所で、add commit。 ローカルのgitリポジトリに変更が記録されていく。 で、次の作業はそれをgit hubにアプ。 バイトの時間が来たので、今回はここまでじゃ! 次回はSSHキーを作って、ローカルリポジトリをgit hubにアップするぞい。
- 投稿日:2021-06-21T07:38:26+09:00
【Node.js, TypeScript】天気予報アプリをLINE MessageAPIで作ってみた!
先日、Node.jsでアプリを天気予報アプリを作成しました。 今回はNode.jsとTypeScriptで作ってみました。 完成形としては以下の通りです。 以前作成したLaravelに関してはこちらからどうぞ。 追記(2021/06/22) AWSでデプロイしました。 AWS勉強中の方はこちらの記事もどうぞ! 追記(2021/06/24) 新たに、現在地から美味しいお店を探すアプリをLINE Messaging APIで作ってみました! こちらでは、Google Maps APIを使用しています。 ぜひこちらの記事もどうぞ! どのようなアプリか 皆さんは、今日の気温を聞いて、「快適に過ごすために今日のファッションをこうしよう」ってパッと思いつきますか? 私は、最高気温、最低気温を聞いてもそれがどのくらい暑いのか、寒いのかがピンと来ず、洋服のチョイスを外したことがしばしばあります。 こんな思いを2度としないために今回このアプリを作りました。 line-bot-sdk-nodejsの型定義で多少躓きましたが、TypeScript初心者でもそこまで時間かからずにできるかと思います。 なので、TypeScriptを勉強中の方はぜひ取り組んでみてください。 アプリの流れ アプリの流れは大まかに以下の4つのステップで成り立っています。 ・①クライアントが現在地を送る ・②OpenWeatherから天気予報を取得 ・③データの整形 ・④クライアントに送る GitHub 完成形のコードは以下となります。 では実際に作成していきましょう! LINE Developersにアカウントを作成する LINE Developersにアクセスして、「ログイン」ボタンをクリックしてください。 その後諸々入力してもらったら以下のように作成できるかと思います。 注意事項としては、今回Messaging APIとなるので、チャネルの種類を間違えた方は修正してください。 チャネルシークレットとチャネルアクセストークンが必要になるのでこの2つを発行します。 ではこの2つを.envに入力します。 .env LINE_CHANNEL_SECRET=abcdefg123456 LINE_CHANNEL_ACCESS_TOKEN=HogeHogeHoge123456789HogeHogeHoge package.jsonの作成 以下のコマンドを入力してください。 これで、package.jsonの作成が完了します。 ターミナル $ npm init -y 必要なパッケージのインストール dependencies dependenciesはすべてのステージで使用するパッケージです。 今回使用するパッケージは以下の4つです。 ・@line/bot-sdk ・express ・dotenv ・axios 以下のコマンドを入力してください。 これで全てのパッケージがインストールされます。 ターミナル $ npm install @line/bot-sdk express dotenv axios --save devDependencies devDependenciesはコーディングステージのみで使用するパッケージです。 今回使用するパッケージは以下の7つです。 ・typescript ・@types/node ・@types/express ・ts-node ・ts-node-dev ・rimraf ・npm-run-all 以下のコマンドを入力してください。 これで全てのパッケージがインストールされます。 ターミナル $ npm install -D typescript @types/node @types/express ts-node ts-node-dev rimraf npm-run-all package.jsonにコマンドの設定を行う npm run devが開発環境の立ち上げに使います。 npm run startが本番環境用です。 package.json { "scripts": { "dev": "ts-node-dev --respawn api/src/index.ts", "clean": "rimraf dist", "tsc": "tsc", "build": "npm-run-all clean tsc", "start": "npm run build && node ." }, } tsconfig.jsonの作成 以下のコマンドを実行しTypeScriptの初期設定を行います。 ターミナル $ npx tsc --init それでは、作成されたtsconfig.jsonの上書きをしていきます。 tsconfig.json { "compilerOptions": { "target": "ES6", "module": "commonjs", "sourceMap": true, "outDir": "./api/dist", "strict": true, "moduleResolution": "node", "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["api/src/**/**/*"] } 簡単にまとめると、 api/srcディレクトリ以下を対象として、それらをapi/distディレクトリにES6の書き方でビルドされるという設定です。 tsconfig.jsonに関して詳しく知りたい方は以下のサイトをどうぞ。 また、この辺りで必要ないディレクトリはGithubにpushしたくないので、.gitignoreも作成しておきましょう。 .gitignore node_modules package-lock.json .env dist https://localhost:3000にアクセスするとhello worldが表示 APIサーバーが正しく動くか検証のため一応作っておきましょう。 api/src/index.ts // Load the package import { Client, ClientConfig } from '@line/bot-sdk'; import express from 'express'; require('dotenv').config(); // Read the ports from the process.env file const PORT = process.env.PORT || 3000; // Load the access token and channel secret from the .env file const config: ClientConfig = { channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '', channelSecret: process.env.CHANNEL_SECRET || '', }; // Instantiate const app: express.Express = express(); const client = new Client(config); // Do routing // Testing Routing app.get('/', (req: express.Request, res: express.Response): void => { res.send('Hello World'); }); // Start the server app.listen(PORT, (): void => { console.log('http://localhost:3000'); }); 上記の内容としては、 ①必要なパッケージを読み込む ②PORT番号を選択する(デプロイ先でPORT番号が指定されるパターンに備えて一応.envを読み込む形式にしています。) ③config の作成(これはおまじないのようなものです) ④インスタンス化を行う。(clientもおまじない) ⑤ルーティングの作成 ⑥WEBサーバーの実行 おまじないだけで片付けるのもアレなので公式サイトを貼っておきます。 またLINEBot関連の型定義に関してもこちらは基本なので、参考コードがあります。 それを丸パクリしましょう。 localhost.runで開発用のhttpsを取得 前回のNode.jsの記事でも使ったlocalhost.runを使います。 ということでここからはターミナル2つ使って開発していきます。 ターミナルに2つのコードを貼り付けて実行してください。 ターミナル $ npm run dev $ ssh -R 80:localhost:3000 localhost.run Webhook URLの登録 localhost.runで作成したhttpsのURLをコピーしてください。 私の場合は以下のURLです。 これをLINE DevelopersのWebhookに設定します。 これで初期設定は完了です。 ここからの流れはこのような感じです。 ①「今日の洋服は?」というメッセージを受け取る ②「今日の洋服は?」を受け取ったら、位置情報メッセージを送る ③「今日の洋服は?」以外を受け取ったら、「そのメッセージには対応していません」と送る ④「位置情報メッセージ」を受け取る ⑤「位置情報メッセージ」を受け取ったら、緯度と経度を使って天気予報を取得する ⑥「位置情報メッセージ」を受け取ったら、天気予報メッセージを送る では作っていきましょう! またこれら全てのコードをapi/src/index.tsに書くとコードが肥大化し可読性が落ちます。 なのでCommonディレクトリに関数に切り分けて作成していきます。 またここからはLINEBotのオリジナルの型が頻出します。 1つずつ説明するのはあまりに時間がかかるので、知らない型が出てきたらその度に以下のサイトで検索するようにしてください。 ①「今日の洋服は?」というメッセージを受け取る api/src/index.ts // Load the package import { Client, middleware, ClientConfig, MiddlewareConfig, WebhookEvent } from '@line/bot-sdk'; import express from 'express'; import dotenv from 'dotenv'; dotenv.config(); // Load the module import { SendMessage } from './Common/Send/ButtonOrErrorMessage'; // Read the ports from the process.env file const PORT: string | 3000 = process.env.PORT || 3000; // Load the access token and channel secret from the .env file const clientConfig: ClientConfig = { channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '', channelSecret: process.env.CHANNEL_SECRET || '', }; const middlewareConfig: MiddlewareConfig = { channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '', channelSecret: process.env.CHANNEL_SECRET || '', }; // Instantiate const app: express.Express = express(); const client: Client = new Client(clientConfig); // Do routing // Testing Routing app.get('/', (req: express.Request, res: express.Response): void => { res.send('Hello World'); }); // API Routing app.post( '/api/line/message', middleware(middlewareConfig), async (req: express.Request, res: express.Response): Promise<void> => { const events: WebhookEvent[] = req.body.events; events.map( async (event: WebhookEvent): Promise<void> => { try { await SendMessage(client, event); } catch (err) { console.error(err); } } ); } ); // Start the server app.listen(PORT, (): void => { console.log('http://localhost:3000'); }); ②「今日の洋服は?」を受け取ったら、位置情報メッセージを送る api/src/Common/Template/ButtonMessageTemplate.ts // Load the package import { TemplateMessage } from '@line/bot-sdk'; export const ButtonMessageTemplate = (): TemplateMessage => { return { type: 'template', altText: 'This is a buttons template', template: { type: 'buttons', text: '今日はどんな洋服にしようかな', actions: [ { type: 'uri', label: '現在地を送る', uri: 'https://line.me/R/nv/location/', }, ], }, }; }; api/src/Common/Send/ButtonOrErrorMessage.ts // Load the package import { Client, WebhookEvent } from '@line/bot-sdk'; // Load the module import { ButtonMessageTemplate } from '../Template/ButtonMessageTemplate'; export const SendMessage = async (client: Client, event: WebhookEvent): Promise<void> => { try { if (event.type !== 'message' || event.message.type !== 'text') { return; } const { replyToken } = event; const { text } = event.message; if (text === '今日の洋服は?') { await client.replyMessage(replyToken, ButtonMessageTemplate()); } else { // エラーメッセージを送る } } catch (err) { console.log(err); } }; ボタンメッセージのJSON作成に関しては公式サイトを参考にしましょう。 ③「今日の洋服は?」以外を受け取ったら、「そのメッセージには対応していません」と送る api/src/Common/Template/ErrorMessageTemplate.ts // Load the package import { TextMessage } from '@line/bot-sdk'; export const ErrorMessageTemplate = (): TextMessage => { return { type: 'text', text: 'ごめんなさい、このメッセージは対応していません。', }; }; api/src/Common/Send/ButtonOrErrorMessage.ts // Load the package import { Client, WebhookEvent } from '@line/bot-sdk'; // Load the module import { ButtonMessageTemplate } from '../Template/ButtonMessageTemplate'; import { ErrorMessageTemplate } from '../Template/ErrorMessageTemplate'; export const SendMessage = async (client: Client, event: WebhookEvent): Promise<void> => { try { if (event.type !== 'message' || event.message.type !== 'text') { return; } const { replyToken } = event; const { text } = event.message; if (text === '今日の洋服は?') { await client.replyMessage(replyToken, ButtonMessageTemplate()); } else { await client.replyMessage(replyToken, ErrorMessageTemplate()); } } catch (err) { console.log(err); } }; テキストメッセージのJSON作成に関しては公式サイトを参考にしましょう。 ④「位置情報メッセージ」を受け取る api/src/index.ts // Load the package import { Client, middleware, ClientConfig, MiddlewareConfig, WebhookEvent } from '@line/bot-sdk'; import express from 'express'; import dotenv from 'dotenv'; dotenv.config(); // Load the module import { SendMessage } from './Common/Send/ButtonOrErrorMessage'; import { FlexMessage } from './Common/Send/FlexMessage'; // Read the ports from the process.env file const PORT: string | 3000 = process.env.PORT || 3000; // Load the access token and channel secret from the .env file const clientConfig: ClientConfig = { channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '', channelSecret: process.env.CHANNEL_SECRET || '', }; const middlewareConfig: MiddlewareConfig = { channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN || '', channelSecret: process.env.CHANNEL_SECRET || '', }; // Instantiate const app: express.Express = express(); const client: Client = new Client(clientConfig); // Do routing // Testing Routing app.get('/', (req: express.Request, res: express.Response): void => { res.send('Hello World'); }); // API Routing app.post( '/api/line/message', middleware(middlewareConfig), async (req: express.Request, res: express.Response): Promise<void> => { const events: WebhookEvent[] = req.body.events; events.map( async (event: WebhookEvent): Promise<void> => { try { await SendMessage(client, event); await FlexMessage(client, event); } catch (err) { console.error(err); } } ); } ); // Start the server app.listen(PORT, (): void => { console.log('http://localhost:3000'); }); ⑤「位置情報メッセージ」を受け取ったら、緯度と経度を使って天気予報を取得する Flex Messageの作成方法に関してファイル名も出しながら説明します。 【ファイル名】GetWeatherForecast.ts 天気予報を取得します。 まずはOpenWeatherで天気予報を取得するために必要な情報が3つあります。 ①API ②経度 ③緯度 それではこの3つを取得していきましょう。 ①API 以下にアクセスしてください。 アカウントを作成し、APIキーを発行してください。 発行できたらこのAPIを.envに保存します。 .env # OpenWeather(https://home.openweathermap.org/api_keys) WEATHER_API = "a11b22c33d44e55f66g77" あとは関数内で.envを取得するだけです。 ②経度、③緯度 これら2つは、eventから取得できます。 ということで作っていきましょう。 api/src/Common/Template/WeatherForecast/GetWeatherForecast.ts // Load the package import { WebhookEvent } from '@line/bot-sdk'; import axios, { AxiosResponse } from 'axios'; export const getWeatherForecastData = async (event: WebhookEvent): Promise<any> => { try { if (event.type !== 'message' || event.message.type !== 'location') { return; } // Get latitude and longitude const latitude: number = event.message.latitude; const longitude: number = event.message.longitude; // OpenWeatherAPI const openWeatherAPI: string | undefined = process.env.WEATHER_API || ''; // OpenWeatherURL const openWeatherURL: string = `https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&units=metric&lang=ja&appid=${openWeatherAPI}`; const weatherData: AxiosResponse<any> = await axios.get(openWeatherURL); return weatherData; } catch (err) { console.log(err); } }; 【ファイル名】FormatWeatherForecast.ts 取得した天気予報のデータの整形を行う。 こちらでは、const weatherとconst weatherArrayの2つで型定義ファイルを作成する必要があります。 ということで作成しましょう。 api/src/Common/Template/WeatherForecast/types/weather.type.ts export type WeatherType = { dt: number; sunrise: number; sunset: number; moonrise: number; moonset: number; moon_phase: number; temp: { day: number; min: number; max: number; night: number; eve: number; morn: number; }; feels_like: { day: number; night: number; eve: number; morn: number; }; pressure: number; humidity: number; dew_point: number; wind_speed: number; wind_deg: number; wind_gust: number; weather: [ { id: number; main: string; description: string; icon: string; } ]; clouds: number; pop: number; rain: number; uvi: number; }; api/src/Common/Template/WeatherForecast/types/weatherArray.type.ts export type WeatherArrayType = { today: string; imageURL: string; weatherForecast: string; mornTemperature: number; dayTemperature: number; eveTemperature: number; nightTemperature: number; fashionAdvice: string; }; 作成した型定義を使ってファイルを完成させます。 api/src/Common/Template/WeatherForecast/FormatWeatherForecast.ts // Load the package import { WebhookEvent } from '@line/bot-sdk'; import { AxiosResponse } from 'axios'; // Load the module import { getWeatherForecastData } from './GetWeatherForecast'; // types import { WeatherType } from './types/weather.type'; import { WeatherArrayType } from './types/weatherArray.type'; export const formatWeatherForecastData = async (event: WebhookEvent): Promise<WeatherArrayType> => { // Get the getWeatherForecastData const weathers: AxiosResponse<any> = await getWeatherForecastData(event); // Util const weather: WeatherType = weathers.data.daily[0]; // Five required data // 1) Today's date const UNIXToday: number = weather.dt; const convertUNIXToday: Date = new Date(UNIXToday * 1000); const today: string = convertUNIXToday.toLocaleDateString('ja-JP'); // 2) Weather forecast const weatherForecast: string = weather.weather[0].description; // 3) Temperature (morning, daytime, evening, night) const mornTemperature: number = weather.feels_like.morn; const dayTemperature: number = weather.feels_like.day; const eveTemperature: number = weather.feels_like.eve; const nightTemperature: number = weather.feels_like.night; // Bifurcate your clothing by maximum temperature const maximumTemperature: number = Math.max( mornTemperature, dayTemperature, eveTemperature, nightTemperature ); // 4) Fashion Advice let fashionAdvice: string = ''; // 5) Fashion Image let imageURL: string = ''; if (maximumTemperature >= 26) { fashionAdvice = '暑い!半袖が活躍する時期です。少し歩くだけで汗ばむ気温なので半袖1枚で大丈夫です。ハットや日焼け止めなどの対策もしましょう'; imageURL = 'https://uploads-ssl.webflow.com/603c87adb15be3cb0b3ed9b5/60aa3c44153071e6df530eb7_71.png'; } else if (maximumTemperature >= 21) { fashionAdvice = '半袖と長袖の分かれ目の気温です。日差しのある日は半袖を、曇りや雨で日差しがない日は長袖がおすすめです。この気温では、半袖の上にライトアウターなどを着ていつでも脱げるようにしておくといいですね!'; imageURL = 'https://uploads-ssl.webflow.com/603c87adb15be3cb0b3ed9b5/6056e58a5923ad81f73ac747_10.png'; } else if (maximumTemperature >= 16) { fashionAdvice = 'レイヤードスタイルが楽しめる気温です。ちょっと肌寒いかな?というくらいの過ごしやすい時期なので目一杯ファッションを楽しみましょう!日中と朝晩で気温差が激しいので羽織ものを持つことを前提としたコーディネートがおすすめです。'; imageURL = 'https://uploads-ssl.webflow.com/603c87adb15be3cb0b3ed9b5/6087da411a3ce013f3ddcd42_66.png'; } else if (maximumTemperature >= 12) { fashionAdvice = 'じわじわと寒さを感じる気温です。ライトアウターやニットやパーカーなどが活躍します。この時期は急に暑さをぶり返すことも多いのでこのLINEで毎日天気を確認してくださいね!'; imageURL = 'https://uploads-ssl.webflow.com/603c87adb15be3cb0b3ed9b5/6056e498e7d26507413fd853_4.png'; } else if (maximumTemperature >= 7) { fashionAdvice = 'そろそろ冬本番です。冬服の上にアウターを羽織ってちょうどいいくらいです。ただし室内は暖房が効いていることが多いので脱ぎ着しやすいコーディネートがおすすめです!'; imageURL = 'https://uploads-ssl.webflow.com/603c87adb15be3cb0b3ed9b5/6056e4de7156326ff560b1a1_6.png'; } else { fashionAdvice = '凍えるほどの寒さです。しっかり厚着して、マフラーや手袋、ニット帽などの冬小物もうまく使って防寒対策をしましょう!'; imageURL = 'https://uploads-ssl.webflow.com/603c87adb15be3cb0b3ed9b5/6056ebd3ea0ff76dfc900633_48.png'; } // Make an array of the above required items. const weatherArray: WeatherArrayType = { today, imageURL, weatherForecast, mornTemperature, dayTemperature, eveTemperature, nightTemperature, fashionAdvice, }; return weatherArray; }; 【ファイル名】FlexMessageTemplate 整形したデータを取得して Flex Messageのテンプレートを作成する。 api/src/Common/Template/WeatherForecast/FlexMessageTemplate.ts // Load the package import { WebhookEvent, FlexMessage } from '@line/bot-sdk'; // Load the module import { formatWeatherForecastData } from './FormatWeatherForecast'; export const FlexMessageTemplate = async (event: WebhookEvent): Promise<FlexMessage> => { const data = await formatWeatherForecastData(event); return { type: 'flex', altText: '天気予報です', contents: { type: 'bubble', header: { type: 'box', layout: 'vertical', contents: [ { type: 'text', text: data.today, color: '#FFFFFF', align: 'center', weight: 'bold', }, ], }, hero: { type: 'image', url: data.imageURL, size: 'full', }, body: { type: 'box', layout: 'vertical', contents: [ { type: 'text', text: `天気は、「${data.weatherForecast}」です`, weight: 'bold', align: 'center', }, { type: 'text', text: '■体感気温', margin: 'lg', }, { type: 'text', text: `朝:${data.mornTemperature}℃`, margin: 'sm', size: 'sm', color: '#C8BD16', }, { type: 'text', text: `日中:${data.dayTemperature}℃`, margin: 'sm', size: 'sm', color: '#789BC0', }, { type: 'text', text: `夕方:${data.eveTemperature}℃`, margin: 'sm', size: 'sm', color: '#091C43', }, { type: 'text', text: `夜:${data.nightTemperature}℃`, margin: 'sm', size: 'sm', color: '#004032', }, { type: 'separator', margin: 'xl', }, { type: 'text', text: '■洋服アドバイス', margin: 'xl', }, { type: 'text', text: data.fashionAdvice, margin: 'sm', wrap: true, size: 'xs', }, ], }, styles: { header: { backgroundColor: '#00B900', }, hero: { separator: false, }, }, }, }; }; ⑥「位置情報メッセージ」を受け取ったら、天気予報メッセージを送る api/src/Common/Send/FlexMessage.ts // Load the package import { Client, WebhookEvent } from '@line/bot-sdk'; // Load the module import { FlexMessageTemplate } from '../Template/WeatherForecast/FlexMessageTemplate'; export const FlexMessage = async (client: Client, event: WebhookEvent): Promise<void> => { try { if (event.type !== 'message' || event.message.type !== 'location') { return; } const { replyToken } = event; const message = await FlexMessageTemplate(event); await client.replyMessage(replyToken, message); } catch (err) { console.log(err); } }; これで完成です! めちゃくちゃ簡単ですね。 最後にデプロイをしましょう 今回もデプロイはGlitchを使います。 アカウントは、Githubで作るのがおすすめです。 作成しましたら、プロジェクトを作成します。 「import from GitHub」をクリックします。 ここには、GithubのURLを貼り付けます。 ちょっと待つとこのように読み込まれます。 便利なのは全てのファイルが確認できるところです。 HerokuなどはどちらかというとCUIであり、GUIのGlitchは直感的に操作できてすごく良かったです。 最後に.envに値を入力します。 ここまで行えばデプロイは成功です! ちなみに URL変えたいときはここをいじってください ShareボタンをクリックすればURLがLive siteに書いているよ Webhookの設定を変更 これで完成です! 最後に FlexMessageなどコードにミスが起きやすいので、TypeScriptの型定義さえあればミスに気づきやすくなるなぁと実感しました。 次は、このアプリをAWSへデプロイするハンズオン記事を書いていきます。
- 投稿日:2021-06-21T03:56:30+09:00
node で TypeScript プロジェクトの新規作成手順
今までのあらすじ 既に誰かが作ったプロジェクトを動かしたり触ったりすることはできたけど、そもそも新規プロジェクトを作成するにはどうすんの?ということでこの記事が決定版 覚えて置く必要は無いけどやり方知らないとつらい。 全てにおいて最小構成 環境 Version OS Windows 10 EDI VSCode ? 手順 初期化 npm init terminal npm init package.jsonが作成されます。 このプロジェクトがnpmの管理下に置かれます。 プロジェクトの基本的な情報が入ってます。 インストールしたパッケージが追加されていきます。 TypeScript TypeScriptのインストール terminal npm install --save-dev typescript TypeScript初期化 terminal tsc --init Webpack webpackのインストール terminal npm install --save-dev webpack webpack-cli ts-loader おなじみwebpackのインストール webpack.config.jsの作成 webpack.config.js module.exports = { mode: "development", entry: "./typescript/script.js" }; 最小構成 他にも色々できる 時間があれば公式ドキュメント見たほうが良い ググれば日本語で解説してるページも出てくる index.html作成 サンプル index.html <html lang="ja"> <head> <meta charset="utf-8" /> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <meta http-equiv="Expires" content="0"> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <title>a!</title> </head> <body> <script src="./dist/main.js"></script> </body> </html> (最小構成じゃない....) キャラセットにutf-8を指定してたり サーバーのファイルを更新した時にブラウザキャッシュが残らないようにしてたり してるけど実質最小構成 script.ts(名前は何でもよい)の作成 typescript/script.ts console.log('a!'); コンソールにa!と表示させます script.tsでなくても問題無いけど、その場合はwebpack.config.jsを修正せなあかんです。 小休止 ここまで終われば後は必要なパッケージを入れるだけ pixi.jsインストール terminal npm install @types/pixi.js --save-dev npm install pixi.js + npm install @types/pixi.jsでも良い。変わらんけど --save-devはローカルインストールを表す 終わり あとはいつものビルドコマンド+Live Server 参考
- 投稿日:2021-06-21T02:18:53+09:00
huskyを使ってgit hooksを作成する
これは何 huskyというライブラリを使用して、git commit時やgit push時にコマンドを実行する方法をお伝えする記事です。 git commit時にフォーマッタを適用させたり、git push時にテストを実行したり、開発自動化を進める時などに有効です。 対象読者 gitを使用しており、開発自動化を進めたい方 huskyの使い方を学びたい方 huskyとは gitで特定のアクションを行った際に、コマンドを実行してタスクを行う(これをgit hooksとも言います)ための仕組みを提供するライブラリです(Node.js環境があれば利用可能) huskyを使用することで、git pushした時にテストコードを実行させるなどが可能となります lint-stagedと組み合わせることで「ステージングしているファイル」や「コミットしたファイル」に対してのみコマンドを実行させる、ということが可能となります huskyの使い方 環境 以下の環境で動作確認を行いました。 名前 バージョン windows10 Node.js 12.13.0 npm 6.12.0 yarn 1.21.1 husky 4.2.1 インストール npmを使用する場合 npm install -D husky yarnを使用する場合 yarn add -D husky package.jsonへの記述 (関係のない記述は省略しております) { "devDependencies": { "husky": "^4.2.1", }, "husky": { "hooks": { "pre-commit": "git commit時に実行したいコマンド", "pre-push": "git push時に実行したいコマンド" } } } 例:git commit時にeslintとprettierを適用させたい (eslintとprettierはインストール済みであることを前提とします) package.jsonの記述 (git commit時にルートディレクトリ配下のファイルに対してprettierとeslintによる修正を行います) { "devDependencies": { "eslint": "^7.24.0", "eslint-config-prettier": "^6.11.0", "husky": "^4.2.1", "prettier": "^2.0.5", }, "husky": { "hooks": { "pre-commit": "prettier --write . && eslint --fix ." } } } 例:git push時にJestのテストを実行させたい package.jsonの記述 { "devDependencies": { "jest": "^27.0.4", "husky": "^4.2.1", }, "husky": { "hooks": { "pre-push": "jest" } } } lint-stagedとの組み合わせ lint-stagedと組み合わせることで、「git commit時にはステージング中のファイルに対してのみ」「git push時にはcommitしたファイルに対してのみ」コマンドを実行することができます。 package.jsonの記述 "pre-commit": "lint-staged --allow-empty"の箇所では、単に"pre-commit": "lint-staged"と記述した場合、以下のエラーが出てしまう場合があるため空コミットを許容するようにしています。 参考 Prevented an empty commit! また、lint-stagedのバージョン10以降ではコマンド実行後のgit addは不要(自動でgit addされる)ため記述しておりません。 { "devDependencies": { "eslint": "^7.24.0", "eslint-config-prettier": "^6.11.0", "husky": "^4.2.1", "lint-staged": "^10.0.7", "prettier": "^2.0.5" }, "husky": { "hooks": { "pre-commit": "lint-staged --allow-empty" } }, "lint-staged": { "**/*.{css,html,js}": [ "prettier --write" ], "**/*.js": [ "eslint --fix" ] } } git commit時にステージングしたファイルに対してのみprettierやeslintを適用させます。 エラーが無い場合、git commitが行われます。 エラーがある場合、以下のようなメッセージがターミナル上に表示されてgit commitは行われません。 154:5 warning Unexpected console statement no-console 158:17 error 'event' is defined but never used no-unused-vars ✖ 15 problems (1 errors, 1 warnings) husky > pre-commit hook failed (add --no-verify to bypass) 参考 husky の pre-commit が(また)動かない 【JavaScript】コミットする前にlint-stagedでeslintのチェックをする
- 投稿日:2021-06-21T02:18:53+09:00
huskyでgit hooksを作成して開発自動化を行う
これは何 huskyというライブラリを使用して、git commit時やgit push時にコマンドを実行する方法をお伝えする記事です。 git commit時にフォーマッタを適用させたり、git push時にテストを実行したり、開発自動化を進める時などに有効です。 対象読者 gitを使用しており、開発自動化を進めたい方 huskyの使い方を学びたい方 huskyとは gitで特定のアクションを行った際に、コマンドを実行してタスクを行う(これをgit hooksとも言います)ための仕組みを提供するライブラリです(Node.js環境があれば利用可能) huskyを使用することで、git pushした時にテストコードを実行させるなどが可能となります lint-stagedと組み合わせることで「ステージングしているファイル」や「コミットしたファイル」に対してのみコマンドを実行させる、ということが可能となります huskyの使い方 環境 以下の環境で動作確認を行いました。 名前 バージョン windows10 Node.js 12.13.0 npm 6.12.0 yarn 1.21.1 husky 4.2.1 インストール npmを使用する場合 npm install -D husky yarnを使用する場合 yarn add -D husky package.jsonへの記述 (関係のない記述は省略しております) { "devDependencies": { "husky": "^4.2.1", }, "husky": { "hooks": { "pre-commit": "git commit時に実行したいコマンド", "pre-push": "git push時に実行したいコマンド" } } } 例:git commit時にeslintとprettierを適用させたい (eslintとprettierはインストール済みであることを前提とします) package.jsonの記述 (git commit時にルートディレクトリ配下のファイルに対してprettierとeslintによる修正を行います) { "devDependencies": { "eslint": "^7.24.0", "eslint-config-prettier": "^6.11.0", "husky": "^4.2.1", "prettier": "^2.0.5", }, "husky": { "hooks": { "pre-commit": "prettier --write . && eslint --fix ." } } } 例:git push時にJestのテストを実行させたい package.jsonの記述 { "devDependencies": { "jest": "^27.0.4", "husky": "^4.2.1", }, "husky": { "hooks": { "pre-push": "jest" } } } lint-stagedとの組み合わせ lint-stagedと組み合わせることで、「git commit時にはステージング中のファイルに対してのみ」「git push時にはcommitしたファイルに対してのみ」コマンドを実行することができます。 package.jsonの記述 "pre-commit": "lint-staged --allow-empty"の箇所では、単に"pre-commit": "lint-staged"と記述した場合、以下のエラーが出てしまう場合があるため空コミットを許容するようにしています。 参考 Prevented an empty commit! また、lint-stagedのバージョン10以降ではコマンド実行後のgit addは不要(自動でgit addされる)ため記述しておりません。 以下の流れで処理されます。 コミット時にlint-staged --allow-emptyコマンドが実行される コミットしたファイルがcss,html,jsいずれかのファイル形式であればprettier --writeを実行してprettierのフォーマット適用 コミットするファイルがjsのファイル形式であればeslint --fixを実行してeslint適用 { "devDependencies": { "eslint": "^7.24.0", "eslint-config-prettier": "^6.11.0", "husky": "^4.2.1", "lint-staged": "^10.0.7", "prettier": "^2.0.5" }, "husky": { "hooks": { "pre-commit": "lint-staged --allow-empty" } }, "lint-staged": { "**/*.{css,html,js}": [ "prettier --write" ], "**/*.js": [ "eslint --fix" ] } } エラーが無い場合、git commitが行われます。 エラーがある場合、以下のようなメッセージがターミナル上に表示されてgit commitは行われません。 154:5 warning Unexpected console statement no-console 158:17 error 'event' is defined but never used no-unused-vars ✖ 2 problems (1 errors, 1 warnings) husky > pre-commit hook failed (add --no-verify to bypass) 参考 husky の pre-commit が(また)動かない 【JavaScript】コミットする前にlint-stagedでeslintのチェックをする