- 投稿日:2020-08-12T22:42:18+09:00
nodenvを使ってnode環境を作る
はじめに
ちょっと仕事で AWS Lamdbaを使うことになりそうなので、いまさらながらお勉強。
WSL2のUbuntuに開発環境を作って、試してみようと思います。環境
Windows 10
WSL2
Ubuntu 20.04 LTSnodenvをインストールする
git clone で必要なファイルを取得します。
git clone git://github.com/nodenv/nodenv.git ~/.nodenv git clone git://github.com/nodenv/node-build.git ~/.nodenv/plugins/node-buildnodenvにパスを通します。
echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.profile echo 'eval "$(nodenv init -)"' >> ~/.profile source ~/.profileNode.jsをインストールする
インストール可能なバージョン一覧を取得し、表示されたバージョンを指定してインストール。
ここでは最新のLTSを選択nodenv install --list nodenv install 12.18.3利用するNode.js のバージョンを指定する
localを指定することで、コマンド実行した配下のディレクトリで、該当バージョンを利用することができます。nodenv local 12.18.3
最後にバージョン確認。指定したバージョンが表示されればOK
node -v
さいごに
これで、準備はできたので、次はServerlessFrameworkだ。
- 投稿日:2020-08-12T22:01:39+09:00
スクワットしないとジェイソン・ステイサムに撃たれるLINE bot ~SQUAT or DIE~
Qiitaで「ジェイソン・ステイサム」というタグを密かに育んでいるたわちゃんです。
もちろん、今回も愛しのステイサムたんがテーマ!
ぜひ、最後までご覧ください♪今回のステイサム作品
自粛により13キロも太ってしまった私。
空いた時間にスクワットしたいけどヤル気が出ないので、スクワットしないとステイサムに殺●れるLINE botを作りました。
その名も「SQUAT or DIE」です。出来たもの
※キャプチャ撮る時LINE botの名前変えるの忘れてた・・・「SQUAT or DIE」です。
基本、私からの問いかけには一切無視というドS設定ですが、スクワット表明をすると反応してくれます。
ステイサムたんの命令は絶対・・・!すぐにスクワット開始です。
ちなみにTシャツに反応した方は、そっとコメントください。シュールすぎるんだが。服装パジャマですみません。 #protoout #obniz pic.twitter.com/GJyARxe6qY
— カレー大好き★たわちゃん (@unias_tawa) August 12, 2020スクワット20回をやり切ると、ステイサムたんからご褒美をいただけます。
逆に諦めると、撃たれます。
作り方
動画でもチラ見えしていますが、Obnizでスクワットの回数をカウントし、LINE Messaging APIを使ってLINE botと連携しています。ソースコードは記事の下部に貼ってるので、ここでは割愛しますね!
Obnizを跨いでスクワットし、超音波距離センサ(HC-SR04)でお股との距離を測り、50㎝以下になるとカウントするようにしました。
※ちなみに、超音波だからかお股だとなかなか反応してくれず、お股に手のひらをかざすとカウントしてくれました。笑スクワットの回数を数えてくれるやつ作りました。私のお股アングルからご覧下さい。 #protoout #obniz #iot pic.twitter.com/l3B6XbMfpb
— カレー大好き★たわちゃん (@unias_tawa) August 12, 2020ちゃんとディスプレイの文字が見えるように、何度もスクワットしながら撮影したので筋肉痛になりました。
ソースコードと改善点
コチラ▶https://gist.github.com/twtjudy1128/05972d30e240979338476d3bc2eef82f
プロトアウトスタジオの先輩の記事
「obnizで腹筋カウンター&line bot」https://qiita.com/karu/items/87e79eeb3c3a0892d00a を参考にさせていただきました!ただ、自分でコード解読できないままお借りしたので、思い通りにカスタムできず、、、
while文の無限ループから抜け出せませんでした(´;ω;`)<< 改善したい点 >>
▶ 回数もLINE BOTに表示させたい
▶ 20回スクワットしたら、自動的にステイサムから褒められたい
▶ 5分以内に20回スクワットしなかったら、自動的にステイサムに撃たれたい
▶ あと9キロ痩せたいこう書き換えたらいいよ!とかアドバイスいただけると嬉しいです・・・
おまけ
実は!先日初めてハッカソンに参加しました!
そのテーマが「チーム制でObnizを楽しもう」だったのですが、チームで役割分担したら、一切Obnizを触ることなくハッカソンが終わっていました(笑)
(ハッカソンの様子はnoteにまとめてます▶ https://note.com/tawata_judy/n/n7b5ac3b60e69 )というわけで、自分でObniz使って何か作ってみよう!と思いチャレンジした次第です。
初めてObniz使った時も不完全燃焼だったのに、今回も中途半端になって悔しい~~~精進します!参照▶【はじめてのIoT】サイリウムを自動的に光らせてみた【ラブライブ】
https://qiita.com/twtjudy1128/items/6df974ea12646665c73b
- 投稿日:2020-08-12T19:28:28+09:00
【Node.js】Expoプッシュ通知を一斉送信するWebAPI|配列を任意の数に分割をする
はじめに
現在Expo ReactNativeを使ってネイティブアプリ開発をしています。
Expoを使ってプッシュ通知を送るためにプッシュ通知のTokenを1つ、1つPOSTリクエストを飛ばしてもいいのですが、Expoの仕様では最大100個のTokenをまとめてPOSTできる。そこでN個ずつに配列を分割して二次元配列にして処理する方法を紹介します。例
以下のような長さ75の配列があるとする、それを10分割して余った分は10個未満になっても分割をする。
今回は長さ75の配列を10個づつ分割して二次元配列にする。処理前
処理後
コード
const main = () =>{ //TOKENにみたて複数の数字を配列にセット let arr = [] for (let i = 0; i < 75; i++) { arr.push(i) } console.log(arr) let result_arr = [] //分割数 const division_count = 10 //配列の数を分割数で割った値を切り上げた値 const add_arr_count = Math.ceil(arr.length / division_count) //add_arr_countの分だけ空配列を追加する for (let i = 0; i < add_arr_count; i++) { result_arr.push([]) } //いい感じに分割して配列にいれる arr.forEach((item,index)=>{ result_arr[Math.floor(index/division_count)].push(item) }) console.log(result_arr) } (async () => { main() })()Expoを使って実際に通知を送る
私の環境ではNode.jsを使ってWebAPIを作り、まとめて送信できるようにしています。
また、Token一覧を管理しているのはMySQLを使っています。Request bodyに
プッシュ通知のタイトルを設定するpush_title
とプッシュ通知の本文部分にあたるpush_body
載せてください※本物のコードは外部から実行できないようにセキュリティ対策をしています
コード
const express = require('express') // expressモジュールを読み込む const cors = require('cors') //クロスドメインでアクセスを許可する系のやつ const bodyParser = require('body-parser') //いい感じにGET POSTを解釈するやつ const util = require('util') // SQL Async/Await const axios = require('axios')//npm install axios const mysql = require('mysql') const multer = require('multer') // multerモジュールを読み込む これがないとBODYの中身をうまく読み取らない //↑ 各種、「npm install」してください //↑ 各種、「npm install」してください //↑ 各種、「npm install」してください // 例1 npm i express // 例2 npm i cors const app = express() // expressアプリを生成する app.use(bodyParser()) app.use(express.static('web')) // webフォルダの中身を公開する app.use(cors())//CROS許可 app.use(multer().none()) // multerでブラウザから送信されたデータを解釈する //サーバの受付ポート番号、SQL接続情報、設定ファイル読み込み const config = require('./server_config.json') // config.server.portのポートでサーバを立てる app.listen(config.server.port, () => console.log('Listening on port ' + config.server.port)) //MySQL接続情報Async/Await★★★★★★★★★★★★★★★★★★★★★★★★★★★★ //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ const pool_config = { host: config.sql.host, user: config.sql.user, password: config.sql.password, port: config.sql.port, database: config.sql.database, timezone: config.sql.timezone //timezoneの指定省略の場合はシステムローカルになる } //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ //汎用的にMySQLを発行する const runQuery = async (sql, data) => { console.log('runQuery...') console.log('sql: ' + sql) console.log('data: ' + data) const pool = mysql.createPool(pool_config) pool.query = util.promisify(pool.query)//これないと動かない const run_sql = mysql.format(sql, data) console.log('発行されたquery:\n' + run_sql + '\n') const result = await pool.query(run_sql) // console.log(JSON.stringify(result)) pool.end() // mysqlのコネクションのプロセスを終了させる。 return result } const uuid = require('node-uuid') app.post('/api/v1/expoPushNotice', (req, res, next) => { (async () => { console.log('/api/v1/expoPushNotice...') //私の環境ではMySQLでpush_tokenというTableを作ってそこでTokenを保存しています let push_token_list = await runQuery( 'select `push_token` from `push_token`', [] ) //通知を送るtoken let to_tokens = [] //分割数 const division_count = 100 //配列の追加数 切り上げた値の数だけ配列を追加 const add_arr_count = Math.ceil(push_token_list.length / division_count) console.log('add_arr_countの文だけから配列を追加する') //add_arr_countの文だけから配列を追加する for (let i = 0; i < add_arr_count; i++) { to_tokens.push([]) } push_token_list.forEach((item, index) => { to_tokens[Math.floor(index/division_count)].push(item.push_token) }) console.log('to_tokens: ') console.log(to_tokens) //APIコール console.log('pushSend...') const req_url = 'https://exp.host/--/api/v2/push/send' const headers = { headers: { Accept: 'application/json', 'Accept-encoding': 'gzip, deflate', 'Content-Type': 'application/json', }, } //分割した分で別々にPOSTリクエストを飛ばす for (let i = 0; i < to_tokens.length; i++) { //bodyに好きなデータを載せると、アプリ側でいろいろできます。 const result = await axios.post( req_url, { 'to': to_tokens[i], 'sound': 'default', 'title': req.body.push_title, 'body': req.body.push_body, 'data': { }, }, headers ) console.log('result: ') console.log(result) } res.json({ status: 200, // message: 'リクエストは正常に受信されました', }) })(res, next).catch((e) => { console.log('サーバエラー : ' + e) console.log('res : ' + res) console.log('e : ' + e) res.json({ status: 500, message: 'サーバエラー\n' + next, }) }) })Tokenを保存しているDB情報
CREATE TABLE `push_token` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `push_token` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `push_token` (`push_token`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;サーバの設定ファイルを記述しているJSONファイル
{ "sql": { "host": "localhost", "user": "hoge", "password": "hoge", "port": 8889, "database": "fuga", "timezone": "jst" }, "server":{ "port": 3003 } }
- 投稿日:2020-08-12T17:07:04+09:00
TypeScript + Node.jsプロジェクトにESLint + Prettierを導入する手順2020
TL;DR
https://github.com/notakaos/typescript-node-base-with-eslint-prettier
完成形のソースコードはこちら↑
この記事の趣旨
TypeScript + Node.js プロジェクトのはじめかた2020 で作成したTypeScript + Node.jsのプロジェクトに
ESLint
/Pretiter
/husky & lint-staged
を導入する手順を紹介します。今回導入するツールとバージョンは以下になります。
項目 バージョン ESLint 7.6.0 Prettier 2.0.5 husky 4.2.5 lint-staged 10.2.11 動作環境
node と npm はインストール済みとします。
$ node -v v12.18.3 $ npm -v 6.14.6また、今回の記事はmacOSにて検証しております。
$ uname -v Darwin Kernel Version 19.6.0: Sun Jul 5 00:43:10 PDT 2020; root:xnu-6153.141.1~9/RELEASE_X86_64 $ sw_vers ProductName: Mac OS X ProductVersion: 10.15.6 BuildVersion: 19G73Linux環境だと手順はほぼ同じだと思いますが、Windows環境の場合は読み替えが必要になるかもしれません。
ESLint
ESLintについて
ESLintはJavaScriptコードのエラーチェックを行うLinterと呼ばれるツールの一つです。
JavaScriptは動的な言語なので、実行するまでエラーがあるのかどうかわからない部分があります。
ESLintを使うことで、JavaScriptのコードを実行することなくコード上の問題を発見するのに役立ちます。また、ESLintは本来JavaScript用ですが、TypeScript用のプラグインを追加することにより、TypeScriptでもESLintが使えるようになります。
以下ではTypeScript (+ Node.js)なプロジェクトへのESLintの導入手順を紹介します。
ESLint (+ TypeScriptプラグイン)の導入
https://github.com/notakaos/typescript-node-base にESLintを導入します。
# typescript-node-base リポジトリをローカルで作成済みとします cd typescript-node-baseNode.jsプロジェクトにESLintとESLintのTypeScript用プラグインを追加します。
typescript-node-basenpm install -D eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin # ESLintのバージョン確認 ./node_modules/.bin/eslint --version #=> v7.6.0次に、ESLint用のTypeScript設定ファイル
tsconfig.eslint.json
を作成します。typescript-node-base# tsconfig.eslint.json ファイルの作成 touch tsconfig.eslint.json # エディターで編集(お好みのエディターをお使いください) vim tsconfig.eslint.jsontsconfig.eslint.json{ "extends": "./tsconfig.json", "include": [ "src/**/*.ts", ".eslintrc.js" ], "exclude": [ "node_modules", "dist" ] }そして、ESLint用の設定ファイル
.eslintrc.js
をプロジェクトディレクトリ直下に作成します。typescript-node-base# .eslintrc.js ファイルの作成 touch .eslintrc.js # エディターで編集(お好みのエディターをお使いください) vim .eslintrc.js~/typescript-node-base/.eslintrc.jsmodule.exports = { root: true, env: { es6: true, node: true, }, parser: '@typescript-eslint/parser', parserOptions: { sourceType: 'module', ecmaVersion: 2019, // Node.js 12の場合は2019、他のバージョンのNode.jsを利用している場合は場合は適宜変更する tsconfigRootDir: __dirname, project: ['./tsconfig.eslint.json'] }, plugins: [ '@typescript-eslint', ], extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended-requiring-type-checking', ], rules: { }, };なお、extendsでいくつかの項目がありますが、extendsはあらかじめ用意されたESLintルールのセットになります。これを入れることによって、以下のルールを適用しています。
- eslint:recommended のルール一覧
- plugin:@typescript-eslint/recommended のルール一覧
- plugin:@typescript-eslint/recommended-requiring-type-checking のルール一覧
これで、ESLint導入完了です。
ESLintの実行
早速、ESLintを実行してみましょう。
typescript-node-basenpx eslint src/index.ts実行結果何も表示されなければ成功です!
設定やソースコードに問題がない場合、何も表示されないのが正常です。
もしここでエラーが表示される場合は記述ミスが考えられますので、各種設定ファイルやソースコードを見直してください。次に、ESLintでエラーを検知できるか確認してみましょう。
src/index.ts
を以下のように編集します。src/index.tsfunction hello(name: string): string { return `Hello, ${name}!`; } - console.log(hello('TypeScript')); + console.log(hello('TypeScript')最後の行の閉じカッコを一つ削除して、文法エラーを意図的に発生させます。
ソースコードを書き換えたら保存し、ESLintを実行します。typescript-node-basenpx eslint src/index.tsすると以下のようなエラーが発生します。
実行結果/Users/notakaos/typescript-node-base/src/index.ts 6:0 error Parsing error: ')' expected ✖ 1 problem (1 error, 0 warnings)「パースエラー:
)
が期待されている(が存在しない)」というエラーがでましたね。
ESLintで文法チェックが正しく動いていることがわかります。ちなみに、文法のチェックに関してはtscでも同様のチェックができます。
(--noEmitオプションをつけてjsファイルを生成しないようにします)typescript-node-basenpx tsc --noEmit
実行結果src/index.ts:6:1 - error TS1005: ')' expected. 6 Found 1 error.
そのため、文法チェックだけだとtscのみでよいのでは? と思われるかもしれませんが、ESLintにはtscに含まれていないエラーチェック機能が入っているため、tscとESLintを併用することによりエラーの検知率をあげることができます。
ここで、tscではエラーにならず、ESLintでエラーになる例を見てみましょう。
src/index.ts
に以下の記述を追加します。src/index.tsfunction hello(name: string): string { return `Hello, ${name}!`; } - console.log(hello("TypeScript") + console.log(hello("TypeScript")); // 元に戻す + function example() {} // どこからも呼ばれない中身が空の関数を用意まずはtscを実行してみます。
npx tsc --noEmit
実行結果特にエラーもなく正常にコマンドが終了しました。
次にESLintを実行します。npx eslint src/index.tseslint実行結果/Users/notakaos/typescript-node-base/src/index.ts 7:10 warning 'example' is defined but never used @typescript-eslint/no-unused-vars 7:20 error Unexpected empty function 'example' @typescript-eslint/no-empty-function ✖ 2 problems (1 error, 1 warning)ESLintでは1つの警告と1つのエラーが発生しましたね。
警告・エラーの内容について、
- 「警告: example関数は定義されているものの使われていない」
- 「エラー: 空の関数は期待されていない」
といった内容になっています。
このように、tscでは通るもののESLintではエラーになるようなものもあり、
両者を適切に設定することでよりバグが少ないコードを書くことができるようになります。最後に毎回
eslint
/tsc
のコマンドを手打ちすると面倒なので、簡単にエラーチェックができるようにpackage.jsonのscriptsに設定を追加します。package.json{ ... "scripts": { "dev": "ts-node src/index.ts", "dev:watch": "ts-node-dev --respawn src/index.ts", "clean": "rimraf dist/*", "tsc": "tsc", "build": "npm-run-all clean tsc", - "start": "node ." + "start": "node .", + "check-types": "tsc --noEmit", + "eslint": "eslint src/**/*.ts", + "eslint:fix": "eslint src/**/*.ts --fix", + "lint": "npm-run-all eslint check-types" }, ... }エラーチェックを実行する時は以下のコマンドを実行します。
typescript-node-basenpm run lintこうすることで、一度のコマンド実行で
eslint
とtsc
の両方を実行することができます。また、以下のように個別に実行することもできます。
typescript-node-base# tsc --noEmit だけ実行 npm run check-types # eslint だけ実行 npm run eslint # eslint のエラーを(できるものだけ)自動修復 npm run eslint:fix普段は
npm run lint
を使い、必要に応じて個別のコマンドを使い分けることになります。Prettier
Prettierについて
Prettierはソースコードの整形ツール(コードフォーマッター)の一つです。
JavaScript/TypeScript/JSON等の形式に対応しています。Prettierを使うことで、スペースやインデント、文字列のクオートの統一、1行が長くなりすぎた場合の改行位置調整などを自動で行ってくれます。
Prettier等のコードフォーマッターを使わない場合、実装者によってコードの書き方がばらばらになり、コードレビュー時にインデント位置やスペース等の指摘が入ってしまうことがあります。それだと本質的なディスカッションができません。そのため、フォーマッターを設定しておくことで、コードの書き方が統一され、ロジックのレビューに集中できるようになる効果があります。
ちなみに、ESLintにもコードフォーマット機能があるため、ESLintと併せてPrettierを利用する場合はESLint側のフォーマットルールをOFFにする必要があります。幸い、PrettierとESLintのフォーマットルールがぶつからないようにするためのルールセット(config)が用意されていますので、そちらも併せて導入します。
Prettier (+ eslint-config-prettier) の導入
PrettierとESLintのPrettier configをインストールします。
typescript-node-base# --save-exact でバージョンを固定してdevインストール npm install -D --save-exact prettier eslint-config-prettier # Prettierのバージョン確認 ./node_modules/.bin/prettier --version #=> 2.0.5次に、Prettier用の設定ファイルをプロジェクトディレクトリ直下に作成します。
typescript-node-baseecho "{}"> .prettierrc.json.prettierrc.json{}
※
.prettierrc.json
は必要に応じて書き換えてくださいまた、prettierの対象外となるファイルを指定する
.prettierignore
をプロジェクトディレクトリ直下に作成します。typescript-node-basetouch .prettierignore # エディターで編集 vim .prettierignore.prettierignore# Ignore artifacts: /dist node_modules package.json package-lock.json tsconfig.json tsconfig.eslint.jsonこのままだと、ESLintのコードフォーマット機能とPrettierのコードフォーマット機能がコンフリクトしてしまうので、
.eslintrc.js
のextendsにprettier
とprettier/@typescript-eslint
の記述を追加します(追加する位置はextendsの最後の方になります)。.eslintrc.jsmodule.exports = { // ... extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended-requiring-type-checking', + 'prettier', + 'prettier/@typescript-eslint', ], // ... }これでPrettierの設定は完了です。
コラム: eslint-plugin-prettier について
インターネット上でESlintとPrettierの導入方法を調べると、
eslint-plugin-prettier
も一緒に入れる方法が紹介されていることがあります。いつからかはわかりませんが、 公式ドキュメントによると、eslint-plugin-prettier が 一般的には推奨されなくなっている ようです。
なぜ非推奨なのかというと、以下のような理由が挙げられています。
- エディターに赤い波線がたくさん表示され、煩わしくなる
- Prettierを直接実行するよりも遅くなる
- 物事が壊れる可能性がある間接層の1つになる
そのため、この記事では eslint-plugin-prettier を導入せず、eslintとは別にpretiterを実行する形を採用しております。
Prettierの実行
では、Prettierを実行してみましょう。
まず
src/index.ts
を以下のようにインデントなどがバラバラな状態に書き換えます。src/index.tsfunction hello(name:string):string{ return `Hello, ${name}!` } console.log(hello("TypeScript" ))そして、以下のコマンドでPrettierを実行します。
typescript-node-basenpx prettier --write src/index.ts
すると、以下のようにコードが修正されます。
src/index.tsfunction hello(name: string): string { return `Hello, ${name}!`; } console.log(hello("TypeScript"));きれいに整形されましたね。
Prettierのnpm-scripts設定
あとは、prettierを簡単に実行できるようにpackage.jsonのscriptsに追記します。
Prettier単体で実行する
format
と、eslint
/tsc
/prettier
を1度に実行するlint:fix
を追加しています。package.json{ ... "scripts": { "dev": "ts-node src/index.ts", "dev:watch": "ts-node-dev --respawn src/index.ts", "clean": "rimraf dist/*", "tsc": "tsc", "build": "npm-run-all clean tsc", "start": "node .", "check-types": "tsc --noEmit", "eslint": "eslint src/**/*.ts", "eslint:fix": "eslint src/**/*.ts --fix", + "format": "prettier --write 'src/**/*.{js,ts,json}'", - "lint": "npm-run-all eslint check-types" + "lint": "npm-run-all eslint check-types", + "lint:fix": "npm-run-all eslint:fix check-types format" }, ... }Prettierのみを実行する場合は以下のコマンドを実行します。
typescript-node-basenpm run format
eslint
とtsc
も併せて実行する場合は、以下のコマンドを実行します。typescript-node-basenpm run lint:fixこれでPrettierの導入完了です。
Git commit時に自動でlintを実行する(huskyとlint-staged)
これまでの手順でESLintとPrettierを導入しましたが、コードを修正するたびに
lint:fix
コマンドを手動で実行する必要がありました。
そのため、lintをかけていないコードを間違ってコミットしてしまうことがあります。これを防ぐため、git commit時に
esLint
/tsc
/prettier
を自動的に実行するようにhusky
とlint-staged
を導入します。huskyとは
https://github.com/typicode/husky
gitのcommit前やpush前などに特定のコマンドを実行するためのGit hooksを簡単に作成するためのツールです。後述のlint-stagedと組み合わせて使います。
lint-stagedとは
https://github.com/okonet/lint-staged
git add
でステージングに追加されたファイルに対して、指定したコマンドを実行します。huskyとlint-stagedの導入
huskyとlint-stagedは以下のコマンドを実行するとpackage.jsonに自動で設定が追加されます。
typescript-node-basenpx mrm lint-stagedpackage.json{ ... "devDependencies": { "@types/node": "^12.12.54", "@typescript-eslint/eslint-plugin": "^3.9.0", "@typescript-eslint/parser": "^3.9.0", "eslint": "^7.6.0", "eslint-config-prettier": "6.11.0", + "husky": "^4.2.5", + "lint-staged": "^10.2.11", "npm-run-all": "^4.1.5", "prettier": "2.0.5", "rimraf": "^3.0.2", "ts-node": "^8.10.2", "ts-node-dev": "^1.0.0-pre.56", "typescript": "^3.9.7" - } + }, + "husky": { + "hooks": { + "pre-commit": "lint-staged" + } + }, + "lint-staged": { + "*.js": "eslint --cache --fix", + "*.{js,ts,json}": "prettier --write" + } }そのままではTypeScriptファイルにおいて、ESLintとtscが実行されないので、
lint-stage
の部分を少し修正します。package.json{ ... "lint-staged": { - "*.js": "eslint --cache --fix", + "*.{js,ts}": "eslint --cache --fix", + "*.ts": "tsc --noEmit", "*.{js,ts,json}": "prettier --write" } }これで設定完了です。
husky & lint-staged を試す
それではhuskyとlint-stagedを試してみましょう。
まず
src/index.ts
を以下のように書き換えます。src/index.tsfunction hello(name: string): string { return `Hello, ${name}!`; } console.log(hello("TypeScript!!!!!") );そしてgit addを行い、その後git commitを実行します。
typescript-node-basegit add src/index.ts git commit -m "Update src/index.ts"実行結果husky > pre-commit (node v12.18.3) ✔ Preparing... ✔ Running tasks... ✔ Applying modifications... ✔ Cleaning up... [feature/husky-lint-staged f69684a] Update src/index.ts 1 file changed, 1 insertion(+), 1 deletion(-)
eslint
/tsc
/prettier
の各コマンドが実行されたのがわかります。そして
src/index.ts
を確認してみると、prettierによって自動整形されているのがわかります。typescript-node-basefunction hello(name: string): string { return `Hello, ${name}!`; } console.log(hello("TypeScript!!!!!"));
git log -p
で差分を確認してみましょう。typescript-node-basegit log -p
実行結果... --- a/src/index.ts +++ b/src/index.ts @@ -2,4 +2,4 @@ function hello(name: string): string { return `Hello, ${name}!`; } -console.log(hello("TypeScript")); +console.log(hello("TypeScript!!!!!"));prettierでコードフォーマットされた後にcommitされていますね。
これでlintをかけずにcommitされることを防ぐことができます。
設定は以上です。
あとはお好みでカスタマイズしましょう!
成果物
以上の手順を実行した完成形のソースコードは以下のリポジトリをご参照ください。
https://github.com/notakaos/typescript-node-base-with-eslint-prettier
参考
- typescript-eslint/README.md at master · typescript-eslint/typescript-eslint
- typescript-eslint/TYPED_LINTING.md at master · typescript-eslint/typescript-eslint
- TypeScript With Babel: A Beautiful Marriage
- VSCode + TypeScript + ESLint + Prettier + Husky + lint-staged (+ JavaScript Standard Style) でコードを防衛@2019秋(2019/12/30 更新) - Qiita
- "parserOptions.project" has been set for @typescript-eslint/parser - Stack Overflow
- Install · Prettier
- Integrating with Linters · Prettier
- Using ESLint and Prettier in a TypeScript Project - DEV
- VSCodeでESLint+typescript-eslint+Prettierを導入する v3.0.0 - Qiita
変更履歴
- 2020/8/12 記事公開
- 投稿日:2020-08-12T16:42:45+09:00
【共有用】Windows10PCにNode.jsをインストールする手順
本記事では、Windows10PCにNode.jsをインストールする手順を紹介いたします。
Node.jsとは
サーバーサイドで動かすことができるJavaScriptです。
JavaScriptは近年多くのWebサイトで活用されており
例えばカーソルを当てるとメニューが飛び出したり
クリックすると画像が拡大するような
動きのあるWebサイトを作成するのに不可欠な言語です。Node.jsはこのJavaScriptをサーバサイド(裏側の仕組み)で活用することができる仕組みになります。
公式では以下のように書かれています
Node.js はスケーラブルなネットワークアプリケーションを構築するために設計された非同期型のイベント駆動の JavaScript 環境です。 以下の「Hello World」の例では、たくさんの接続を同時に処理することができます。 各接続ごとにコールバックは発火され、何もすることがない場合、Node.js はスリープします。
これは OS のスレッドが採用されている一般的な同時実行モデルとは対照的です。 スレッドベースのネットワーキングは比較的非効率であり、使うのはとても困難です。 さらに Node.js にはロックがないので Node.js ユーザーはプロセスのデッドロックの悩みから開放されます。 ほとんどの Node.js の関数は I/O を直接実行しないため、プロセスをブロックしません。 ブロックしないのでスケーラブルなシステムを開発するのに Node.js はとても最適です。
出典:https://nodejs.org/ja/about/自分の中では最近の開発で選択することが多い仕組みの1つです
理由としては以下になります。
※ほかにもメリットは多くありますが大きく以下の3つをピックアップしています。
・開発環境として軽くてサクサク動くVS Codeを使って快適に開発ができる
・Node.jsを動かすことができるサーバを簡単に構築することができる
・Node.jsで使うことができるライブラリが豊富なので開発品質向上や工期の短縮が可能インストール手順
公式サイトのダウンロードページにアクセスします
https://nodejs.org/ja/download/LTSまたは最新版のWindowsの64bit(32bit版のWindows10PCはほとんど出回っていませんが32bit版を使用している方は32bitを指定)を選択し、ダウンロードします。
ダウンロードしたインストーラを起動し、インストールをすすめます。
インストール時の注意点は特にありませんが
インストール先を変えたい場合は、以下の設定の際にインストール先を変更してください。
特に変更しない場合はnextを選択してください
インストールのカスタマイズも強いこだわりがなければ何もせずnextを選択してください
※弊社ハンズオン等で動かす分にはデフォルトにしたままでnextを選択してください
chocolateyのインストールも基本は不要となりますのでチェックはいれずにnextを選択してください
※弊社ハンズオン等で動かす分には不要です
インストールの確認
ここに入力して検索から『cmd』を入力して、コマンドプロンプトを呼び出します
コマンドプロンプトにて『node -v』と入力して、バージョン情報が表示されればインストール完了です
※表示されるバージョン番号は下記キャプチャと異なる場合がありますがバージョン番号が確認できればインストールは完了していますので問題ありません
- 投稿日:2020-08-12T14:03:05+09:00
【Node.js 超入門】Node.jsとExpessを使ってCRUD処理できるサーバサイドの実装をする!
【Node.js 超入門】Node.jsとExpessを使ってCRUD処理できるサーバサイドの実装をする!
【Node.js 超入門】という参考書を読んで、Node.jsで実装した内容を備忘として書きます。
今回は、データベースを使って画面からユーザ情報を登録、更新などCRUD処理できるアプリケーションを作成します。
メインとしてNode.jsとExpressを使い、サーバサイドの処理を作ります。
データベースはMySQLを使います。大まかな流れとしては、
・環境構築
・コード実装
・動作確認続きはこちらの記事にまとめています!
https://masa-enjoy.com/nodejs-learning1
- 投稿日:2020-08-12T10:54:15+09:00
Alibaba Cloud ECSへのNode.jsのインストールと設定
このチュートリアルでは、Alibaba Cloud ECSインスタンスにNode.jsをインストールして設定します。
本ブログは英語版からの翻訳です。オリジナルはこちらからご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。
前提条件
- Alibaba Cloud Elastic Compute Service (ECS)を有効にし、有効な支払い方法を確認する必要があります。新規ユーザーの場合は、新規アカウントで300ドル~1200ドル相当のAlibaba Cloudクレジットを獲得できます。ECSインスタンスのセットアップ方法がわからない場合は、このチュートリアルまたはクイックスタートガイドを参照してください。ECSインスタンスには、少なくとも1GBのRAMと1つのCoreプロセッサが必要です。
- Alibaba Cloudから登録されたドメイン名。すでにAlibaba Cloudまたは他のホストからドメインを登録している場合は、そのドメインネームサーバーレコードを更新することができます。
- ドメイン名は、あなたのAlibaba Cloud ECSのIPアドレスを指している必要があります。
- Alibaba CloudのVNCコンソールまたはPCにインストールされているSSHクライアントにアクセスします。
- サーバーのホスト名を設定し、root権限のユーザーを作成します。
環境の設定
サーバーの設定
パッケージのインストールを進める前に、以下のコマンドを実行してUbuntuシステムをアップデートしてください。このコマンドを実行するには、root ではないユーザーから sudo 権限でログインすることを忘れないでください。
# sudo apt update && sudo apt upgradeソフトウェアプロパティ共通のインストール
Docker CEのインストールに対応したファイルを取得するためには、software-properties-commonパッケージが必要です。software-properties-commonパッケージをインストールするには、以下の手順に従います。
software-properties-commonをインストールするには、以下のコマンドを実行します。
# sudo apt-get install software-properties-common -yapt-transport-httpsのインストール
Docker CEのインストールにはapt-transport-httpsが必要です。apt-transport-httpsをインストールするには、以下の手順を実行します。
apt-transport-httpsをインストールするには、以下のコマンドを実行します。
# sudo apt-get install apt-transport-https -yca-certificatesのインストール
Docker CEのインストールにはca-certificatesが必要です。ca-certificatesをインストールするには、以下の手順で行います。
ca-certificatesをインストールするには、コマンドを実行します。
# sudo apt-get install ca-certificates -ycurlのインストール
Docker CEのインストールにはcurlが必要です。curlをインストールするには、以下の手順で行います。
curlをインストールするには、コマンドを実行します。
# sudo apt-get install curl -yDocker CEのインストール
Docker community editionをインストールするには、以下の手順で完了します。
以下のコマンドを実行して、Docker用のGPGキーを追加します。
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -以下のコマンドを実行して、GPGキーのフィンガープリントを確認します。
# sudo apt-key fingerprint 0EBFCD88ここで、以下のコマンドを実行してDockerリポジトリを追加します。
# sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable”以下のコマンドを実行してシステムをアップデートし、追加されたリポジトリをロードします。
# sudo apt update以下のコマンドを実行してDockerをインストールします。
# sudo apt install docker-ce以下のコマンドを実行して、ユーザ名をdockerグループに追加します。
# sudo adduser aareez docker現在のシェルセッションを閉じて新しいセッションを開始すると、dockerが実行できなくなり、パーミッションエラーが発生する可能性があります。
次に、以下のコマンドを実行して、dockerが正しく実行されているかどうかを確認します。
# docker run hello-worldDocker Composeのインストール
Docker composeをダウンロードしてインストールするには、以下の手順で行います。
以下のコマンドを実行して、最新版のdocker composeをダウンロードしてインストールします。
# sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose以下のコマンドを実行して、ファイルのパーミッションを設定します。
# sudo chmod +x /usr/local/bin/docker-compose以下のコマンドを実行して起動したコンテナの一覧を取得します。
# docker container ls —allポート808080を使用しているコンテナを停止します。そのためには、コンテナのIDを取得し、以下の8baab990c424に置き換えて、以下のコマンドを実行します。
# docker stop 8baab990c424Node.jsのインストールと設定
このチュートリアルでは、具体的にNode.jsの公式イメージを使ってDocker上にインストールしていきます。Node.jsをダウンロードしてインストールするには、以下のコマンドを実行して、公式のdockerリポジトリから最新のNodejsを引っ張ってくる必要があります。
# docker pull linode/server-node-jsここで以下のコマンドを実行してdockerイメージを実行します。
# docker run -d -p 80:3000 linode/server-node-jsこれで、アリババクラウドECSのIPアドレスまたはそのIPアドレスを指すドメイン名にアクセスして確認することができるようになりました。
http://your_domain.tld/test.htm
以下のページが表示されます。
ファイアウォールとポートの設定
ファイアウォールを有効にしている場合は、クラウドサーバーの Alibaba Cloud セキュリティグループで、ポート 80/tcp と 443/tcp の例外を追加するルールを定義する必要があります。ECSインスタンスの作成時にこれらのポートを有効にすることができますが、これらのポートのブロックを解除し忘れた場合は、このガイドの手順に従ってください:セキュリティグループルールの追加
アリババクラウドは日本に2つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
アリババクラウドジャパン公式ページ
- 投稿日:2020-08-12T06:53:50+09:00
【Deno】denonを利用してのscripts管理
背景
- Deno利用時に以下の点が気になったため、Node同様に可能なのか調査することに。
deno run --allow-net --allow-read server.ts
のような実行コマンドの長さを簡略化して、各種権限管理をしたい。- npm scriptsのように各環境や種類毎に管理できるようにしたい。
- Nodeでのnodemonのようなオートリロード環境の仕組みにしたい。
結果
denon
- 調査の結果、上記3つの要望が可能であるdenonを導入することに。
- denonとは、nodemonのdeno代替であり、柔軟かつ高機能に設定が可能なツール。
- 設定ファイルは、以下の3つの形式で記述することが可能。
- json:
denon.json
- typescript:
denon.config.ts
- yaml:
denon.yml
インストール
- 下記のコマンドで、プロジェクトフォルダにインストール
deno install --allow-read --allow-run --allow-write --allow-net -f -q --unstable https://deno.land/x/denon@2.3.2/denon.ts初期化
- 下記のコマンドで設定ファイルの雛形を作成する。
- ※Nodeであれば、
npm init
のようなもの。# 標準では、json形式(denon.json) denon init # typescript形式(denon.config.ts) denon init --typescript # yaml形式(denon.yml) denon init --yaml設定テンプレート
- 以下の点をふまえた設定テンプレートを記述する。
- 開発の流れで必須、また頻度が高いものをまとめる
- なるべく環境変数は記述しない。
- 多く記述せず、単純にする。
- 今回は、視認性や機能性をふまえて、YAMLでの方法を記述する。
- ※その他、denonの詳細な設定方法はこちらを参考にする。
denon.ymlscripts: dev: cmd: "deno run src/app.ts" desc: "run app.ts file" allow: ["env", "net", "read", "write", "plugin"] unstable: true build: cmd: "deno bundle src/app.ts > build/app.js" desc: "build app.ts file" lint: cmd: "deno lint src/" desc: "lint all ts file" unstable: true fmt: cmd: "deno fmt src/" desc: "format all ts file" watcher: exts: ["js", "jsx", "ts", "tsx", "json"] skip: ["*/.git/*"]実行方法
- 下記のコマンドのように実行。
# denon スクリプト名 denon dev # フォーマット denon fmt # ビルド denon build参考
- 投稿日:2020-08-12T00:19:57+09:00
【初心者向け】Vue+API Gateway+LambdaでサーバレスWebアプリを作った際に遭遇した問題
概要
「AWSを使って、サーバレスアプリを作りたい!」と思い実践したのですが、Lambda関連で結構な壁があったので備忘がてら残します。
ハマりポイントは以下3つ。
- LambdaのResponseは特定のJSON形式でないとNGな話
- API連携の際に、CROS Policyでエラーになった話
- APIに認証を噛ませる際は、accessTokenではなくidTokenを使用する話
LambdaのResponseは特定のJSON形式でないとNGな話
今回はフロントサイドはvueで作成、そこからAPIGatewayを通してLambdaのFunctionを呼び出すという構成でした。
このFunctionの返却の仕方は何でもよい訳ではなくJSONの形式が決まっています。参考:https://aws.amazon.com/jp/premiumsupport/knowledge-center/malformed-502-api-gateway/
以下は、Lambdaを通してTwitterに投稿する関数の例です
exports.handler = (event, context, callback) => { let date = new Date(); twitter_client.post('statuses/update', {status: 'テスト投稿。from lamda ' + date}, function(error, tweet, response){ if(error) { //エラーハンドリング } callback(null, JSON.stringify(response)); }); };関数単体はテスト時に動いても、上記のような正しい形式でないと、実際のフロントからの実行時には500エラーを返すので注意。
API連携の際に、CROS Policyでエラーになった話
「JSONを返す必要があるということはわかったぜ!これでオッケーや!」と思ったら、まだ駄目でした。
今度はフロント側でエラーになりました。。。ブラウザのF12コンソールでエラーの内容を確認すると
「Access to XMLHttpRequest at 'http:/~' from origin 'http://localhost:8080' has been blocked by CORS policy:
…」と書いてありました。
あぁーCROSね、なんかAPIGatewayで設定があった気がするなーと思いいろいろググります。※CROSについては以下の記事が参考になりました。
https://qiita.com/att55/items/2154a8aad8bf1409db2b結論から言うと、以下のように設定するのが正解でした。
レスポンスのヘッダーに
Access-Control-Allow-Headers (使用するHeadersの値を追加)
Access-Control-Allow-Origin (許可するリソースを追加)
Access-Control-Allow-Credentials (これはなくてもいいかも)
Access-Control-Allow-Methods (必要なメソッドを追加)
を追加します。
lambdaの関数のレスポンスに直接書いているやり方もありましたが、
調べて実際に動かしたところこれでも大丈夫。(ケースバイケースだが多分ほとんどの場合これがベターな気がする)APIに認証を噛ませる際は、accessTokenではなくidTokenを使用する話
これはハマったというほどではなかったが、少し勘違いがあったので記載。
上記の問題でAPI通信は問題なく通るようになったが、APIには認証をかけたほうがよい。認証のかけ方もいくつか方法があるが、今回はcognitoユーザプールを使った。
※cognitoを使ったログイン機能を実装していることが前提です。手順としては
1.APIgatewayのコンソールからAuthorizersを作成
2.使用するAPIに適用する
の2 STEEP(めちゃ簡単)
フロントのコードは以下のような感じで実装
App.vueimport { Auth } from 'aws-amplify' import axios from 'axios' let cognitoUser = await Auth.currentAuthenticatedUser() this.signedIn = true this.username = cognitoUser.username let token = cognitoUser.signInUserSession.idToken.jwtToken; console.log(cognitoUser.signInUserSession); …中略… APIfunction(){ axios .get('APIのURL', { headers: { Authorization: token } } ) .then(function (response) { // handle success console.log(response); alert("success"); alert(response); }) .catch(function (error) { // handle error console.log(error); alert("error"); alert(error); }) }signInUserSessionの中にはaccessTokenという似たプロパティもあるが、こっちではなくidTokenを使用した点に注意。
※accessTokenでも認証機能を作ることはできるかも知れませんが、詳細は調査しきれず…(だれか知っている人がいたら教えてください…)まとめ
AWSを使いこなすまでの道のりは遠い…
一方で使いこなすと非常に便利だということも実感できた。前進あるのみ。