(This repository is my own self-study document )
- 表題技術の基礎学習
- 自分用のリファレンス集の作成
下記のチュートリアルを参照させていただきました。
- GitHub : https://github.com/typeorm/typeorm
- 公式サイト : https://typeorm.io/#/
- マイグレーション : https://typeorm.io/#/migrations
- リレーション : https://typeorm.io/#/relations
- TypeORMを使用して、TypeScriptでMySQLのマイグレーション、接続を管理する - Qiita
- TypeORMでエンティティを定義する際のガイドライン - bitbank tech blog
チュートリアルの工程(適宜補完, 変更)
- ここではあくまで私自身向けにまとめています。
- (
npm
コマンドの部分はyarn
コマンドに置き換える 参考:npmとyarnのコマンド早見表 - Qiita)
package.json
の初期準備$ yarn init -y
(-y : 全て'yes'回答のオプション)
TypeScript
のインストール$ yarn add typescript --dev
TypeScript
の設定$ touch tsconfig.json
- 記事内の設定を適用
- メインアプリケーションのエンドポイントを作成
$ mkdir src
$ touch src/app.ts
-
TypeScript ESLint : https://github.com/typescript-eslint/typescript-eslint#getting-started--installation
-
$ yarn add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin --dev
- eslint : https://github.com/eslint/eslint
- ECMAScript/JavaScript のコードで見つかったパターンを識別してレポートするためのツール
- @typescript-eslint/parser : https://www.npmjs.com/package/@typescript-eslint/parser
- ESlintにTypeScriptの構文を理解させる
- @typescript-eslint/eslint-plugin : https://www.npmjs.com/package/@typescript-eslint/eslint-plugin
- TypeScriptのLintルールを提供する
- eslint : https://github.com/eslint/eslint
-
- 設定用ファイル
.eslintrc.js
の作成
- 設定用ファイル
-
- 解析の除外設定ファイル
.eslintignore
の作成
- 解析の除外設定ファイル
-
Prettier
のインストール$ yarn add prettier prettier/@typescript-eslint --dev
- Prettier : https://github.com/prettier/prettier
-
ESLintの設定にPrettierを追記
.eslintrc.js
のextends:
にprettier
とprettier/@typescript-eslint
を追記
-
整形の除外設定ファイル
.prettierignore
の作成
-
concurrently
,nodemon
,rimraf
,npm-run-all
インストール$ yarn add concurrently nodemon rimraf, npm-run-all --dev
- concurrently : https://github.com/kimmobrunfeldt/concurrently
- Watchモードの各コマンドを
concurrently
コマンドとして統合
- Watchモードの各コマンドを
- nodemon : https://github.com/remy/nodemon
- コードの変更を監視して、変更に応じてサーバーを再起動させる
- rimraf : https://github.com/isaacs/rimraf
- OSに依存せずnodeで
rm -rf
を実行する
- OSに依存せずnodeで
- npm-run-all : https://github.com/mysticatea/npm-run-all
- 複数のnpmスクリプトを並列または順次実行するCLIツール
- concurrently : https://github.com/kimmobrunfeldt/concurrently
-
package.json
に監視モード実行のスクリプトを追加"scripts": { "clean": "rimraf dist/*", "tsc": "tsc", "build": "npm-run-all clean tsc", "start": "concurrently \"tsc -w\" \"nodemon dist/js/app.js\"" },
-
コンパイルの出力フォルダを
src/dist/js
に設定-
taconfig.json
に出力先DirとルートDirの設定を追記"outDir": "dist/js", "rootDir": "src",
さらに下記も追記して、コンパイルに含めるものと除外するものを設定
"include": ["src/**/*"], "exclude": ["node_modules"]
監視が成功している際のログ
1:43:28 - Starting compilation in watch mode... [0] [1] [nodemon] 2.0.4 [1] [nodemon] to restart at any time, enter `rs` [1] [nodemon] watching path(s): *.* [1] [nodemon] watching extensions: js,mjs,json [1] [nodemon] starting `node dist/js/app.js` [1] [nodemon] clean exit - waiting for changes before restart [0] [0] 1:43:30 - Found 0 errors. Watching for file changes. [1] [nodemon] restarting due to changes... [1] [nodemon] starting `node dist/js/app.js` [1] Application is up and running [1] [nodemon] clean exit - waiting for changes before restart
-
Express
のインストールExpress
本体のインストール$ yarn add express
@types/express
のインストール$ yarn add @types/express --dev
src/app.ts
にCRUDの処理を記述
typeorm
,mysql
,reflect-metadata
のインストール$ yarn add typeorm mysql reflect-metadata --dev
- ※
reflect-metadata
やデコレータの概念は現時点で難解なため後日に回す
Userモデル
の作成$ mkdir src/entity
$ touch src/entity/User.ts
- 記述を編集
-
参考資料
-
空のマイグレーションファイルを作成
$ typeorm migration:generate -n CreateUser
$ typeorm migration:generate -n(名前の意) {付けたいファイル名}
- [ 注意 ] :
migration:create
だとSQL文の無い空のマイグレーションファイルが生成される
-
未実行の全てのマイグレーションファイルをDBへ反映させる
-
$ typeorm migration:run
## 実行後のDB mysql> show tables; +-----------------------+ | Tables_in_typeormtest | +-----------------------+ | migrations | | user | +-----------------------+ 2 rows in set (0.00 sec) mysql> describe user; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | userName | varchar(255) | NO | | NULL | | | profile | varchar(255) | NO | | NULL | | +----------+--------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec)
-
-
参考資料
- 公式 : https://typeorm.io/#/relations
- 日付カラムの扱いについて : 公式リポジトリのエンティティサンプル
-
最低限のアプリの想定
- リレーションの実装を演習するために、最低限のCRUDアプリケーションの作成場面を想定する。
- 調べたりや勉強したキーワードについて、着手歴を可視化、復習タイミングの管理をサポートするサービス。
-
- 概要
keyword
: 調べごとの単語や用語word
: 単語や用語を登録するmemo
: 単語/用語の説明や参考URL
stamp
:keyword
について勉強や調査をしたタイムスタンプstudy_log
:stamp
に備考を記入するbody
: 本文テキスト
- エンティティ同士の関係性
keyword
: 1対(0 or 多) :stamp
stamp
: 1対(0 or 1) :study_log
- 概要
-
作成日や更新日を扱えるようにする
- 各エンティティファイル内で、モジュール :
CreateDateColumn
,UpdateDateColumn
をインポート
- 各エンティティファイル内で、モジュール :
-
1対1
- One-to-one relations : https://typeorm.io/#/one-to-one-relations
-
1対多(多対1)
- Many-to-one / one-to-many relations : https://typeorm.io/#/many-to-one-one-to-many-relations
-
DBの最終形
mysql> show tables; +-----------------------+ | Tables_in_typeormtest | +-----------------------+ | keyword | | migrations | | stamp | | study_log | +-----------------------+ 4 rows in set (0.02 sec) mysql> describe keyword; +-------------+---------------+------+-----+----------------------+-------------------+ | Field | Type | Null | Key | Default | Extra | +-------------+---------------+------+-----+----------------------+-------------------+ | id | int | NO | PRI | NULL | auto_increment | | createdDate | datetime(6) | NO | | CURRENT_TIMESTAMP(6) | DEFAULT_GENERATED | | updatedDate | datetime(6) | NO | | CURRENT_TIMESTAMP(6) | DEFAULT_GENERATED | | memo | varchar(2000) | NO | | NULL | | | word | varchar(50) | NO | | NULL | | +-------------+---------------+------+-----+----------------------+-------------------+ 5 rows in set (0.03 sec) mysql> describe stamp; +-------------+-------------+------+-----+----------------------+-------------------+ | Field | Type | Null | Key | Default | Extra | +-------------+-------------+------+-----+----------------------+-------------------+ | id | int | NO | PRI | NULL | auto_increment | | createdDate | datetime(6) | NO | | CURRENT_TIMESTAMP(6) | DEFAULT_GENERATED | | updatedDate | datetime(6) | NO | | CURRENT_TIMESTAMP(6) | DEFAULT_GENERATED | | studyLogId | int | YES | UNI | NULL | | | keywordId | int | YES | MUL | NULL | | +-------------+-------------+------+-----+----------------------+-------------------+ 5 rows in set (0.00 sec) mysql> describe study_log; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | body | varchar(500) | NO | | NULL | | +-------+--------------+------+-----+---------+----------------+
-
コントローラーの作成
-
ライブラリ
routing-controllers
を使用する- リクエストを処理するアクションとしてメソッドを持つコントローラクラスを作成できる。
- 導入手順はInstallationから
-
$ yarn add routing-controllers --dev
-
$ yarn add class-transformer class-validator --dev
- class-transformer : https://github.com/typestack/class-transformer#class-transformer
- プレーンなオブジェクトをクラスのインスタンスに変換することができる
- class-validator : https://github.com/typestack/class-validator#class-validator
- デコレータと非デコレータベースのバリデーションを行う
- class-transformer : https://github.com/typestack/class-transformer#class-transformer
-
コントローラーファイル(
src/controllers/**.ts
)の作成
-
-
ルーティングの設定
src/app.ts
を編集createExpressServer
内で各コントローラーを呼び出してポート3000をリッスン
-
サーバーを起動して
+ /keyword
などURLを指定すると対応する文字列が出力される
-
資料
- Jest公式
- GitHub : https://github.com/facebook/jest
- jestjs.io
- ts-jest公式
- Jest - TypeScript Deep Dive
- Jest公式
-
ts-jest
のインストール-
Jest(オリジナル)の手順(今回非採用)
- How to test Express.js with Jest and Supertest | Through the binary
- TypeScript を使用する - Getting Started - jestjs.io
- Babelでは型検査が行われないため、型検査も含めたテストを含んだ
ts-jest
を導入する
- Babelでは型検査が行われないため、型検査も含めたテストを含んだ
-
ts-jest
の導入手順 -
パッケージのインストール
$ yarn add jest ts-jest @types/jest --dev
-
設定ファイルの生成
$ yarn ts-jest config:init
- オプションの設定ガイド
-
- 下記リンクの構成図を変更したもの
_TS_Express_MySQL_with_TypeORM
├── dist ── js // place of your transpiled JavaScript code
│ ├── controllers // place where your controllers are stored
│ ├── entity // place where your entities (database models) are stored
│ ├── migration // place where your migrations are stored
│ └── app.js // start point of your application
│
├── src // place of your TypeScript code
│ ├── controllers // place where your controllers are stored
│ │ ├── KeywordController.ts
│ │ ├── StampController.ts
│ │ └── StudyLogController.ts
│ ├── entity // place where your entities (database models) are stored
│ │ ├── Keyword.ts
│ │ ├── Stamp.ts
│ │ └── StudyLog.ts
│ ├── migration // place where your migrations are stored
│ └── app.ts // start point of your application
│
├── .eslintignore
├── .eslintrc.js
├── .gitignore // standard gitignore file
├── .prettierignore
├── jest.config.js
├── ormconfig.json // ORM and database connection configuration
├── package.json // node module dependencies
├── README.md // simple readme file
├── tsconfig.json // TypeScript compiler options
└── yarn.lock
[1] Require stack:
[1] - /Users/Taishi/Documents/TypeScript/_TS_Express_MySQL_with_TypeORM/dist/js/app.js
[nodemon] app crashed - waiting for file changes before starting...
- 要因&対処
$ yarn add express
の実行抜け -> OK
- まずMySQLサーバーが起動されていなかった
- sockファイルやらpidファイルの小さなエラーがあったが対処して起動
$ yarn start
でのエラーが変わった(おそらく接続はOK)
UnhandledPromiseRejectionWarning: Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server; consider upgrading MySQL client
- MySQL8.0系に特有のエラーらしい
- 手順に沿って対処後、エラーが変化
UnhandledPromiseRejectionWarning: Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'test'@'localhost' (using password: YES)
- mysql - Access denied for user 'test'@'localhost' (using password: YES) except root user - Stack Overflow
- 今回用のMySQLユーザーにrootユーザーからDBの操作権限を付与して当該DBを作成 -> OK (
$ yarn start
にて正常な接続を確認した)