ts-nodeをIDEでデバッグ実行
ts-node は TypeScript ファイルをコンパイルせずにそのまま実行できるライブラリ。
開発環境でお世話になるが、デバッグ実行するやり方の日本語情報がなかったので書いておく。
基本的なこと
node コマンドの option として --inspect
をつければデバッグ実行になる。--require
をつけることで node_modules のライブラリを読み込むことができる。
$ node --inspect --require ts-node/register src/main.ts Debugger listening on ws://127.0.0.1:9229/690c42e8-c2d4-407a-b768-6c5270241775 For help, see: https://nodejs.org/en/docs/inspector
これで WebSocket の ws://127.0.0.1:9229
で待ち受けてるので、IDE 等からアタッチすることでデバッギングできる状態になっているというわけ。
ts-node のインストール
$ npm install ts-node -D
$ yarn add ts-node -D
WebStorm でのやり方
実行
--inspect --require ts-node/register
して実行する ts ファイルを指定するだけ。
Jest でテスト
--inspect --require ts-node/register
して実行するテストファイルを指定するだけ。
結果
TypeORMの@CreateDateColumnの精度を0にする
TypeORM では Rails の ActiveRecord と同じようにプライマリキーの id
カラムをオートインクリメントさせたり、INSERT 時に created_at
カラム、UPDATE 時に updated_at
カラムを自動更新したりできる。
Entity クラス
import {CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn} from 'typeorm'; @Entity('samples') export class Sample { @PrimaryGeneratedColumn() id: number; @CreateDateColumn({name: 'created_at'}) createdAt: Date; @UpdateDateColumn({name: 'updated_at'}) updatedAt: Date; }
ActiveRecord との違い
ActiveRecord では DATETIME の精度がデフォルトの 0 となり、値としては 2018-01-01 00:00:00
のようになる。
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
id | int(11) | NO | PRI | NULL | auto_increment |
created_at | datetime | NO | NULL | ||
updated_at | datetime | NO | NULL |
TypeORM は DATETIME の精度が 6 となり、値としては 2018-01-01 00:00:00.000000
のようにマイクロ秒まで扱う設定となる。
Field | Type | Null | Key | Default | Extra |
---|---|---|---|---|---|
id | int(11) | NO | PRI | NULL | auto_increment |
created_at | datetime(6) | NO | CURRENT_TIMESTAMP(6) | ||
updated_at | datetime(6) | NO | CURRENT_TIMESTAMP(6) |
精度を 0 にする
要件次第ではあるがマイクロ秒どころかミリ秒すらいらなかったので ActiveRecord と同じように精度 0 にしたい。
@CreateDateColumn({name: 'created_at', precision: 0, default: () => 'NOW()'}) createdAt: Date; @UpdateDateColumn({name: 'updated_at', precision: 0, default: () => 'NOW()'}) updatedAt: Date;
precision
で精度を 0 指定する。これだけだとデフォルト値が CURRENT_TIMESTAMP(6)
となってしまいエラーになるので、公式 FAQ に書いてあるやり方でデフォルト値も書き換える。
Mac環境でgRPCのC++コードをDockerつかって生成
🖼 背景
Protocol Buffers のコード生成だけなら Homebrew でインストール可能な protoc
コマンドさえあればいいが、
$ brew install protobuf $ protoc --version libprotoc 3.6.0
gRPC コードを生成するなら grpc_cpp_plugin
が必要となる。
$ which grpc_cpp_plugin /usr/local/bin/grpc_cpp_plugin
残念なことに Homebrew
や go get
ではインストールできず、Mac で make build
, make install
しなければならない。
WARNING: After installing with make install there is no easy way to uninstall, which can cause issues if you later want to remove the grpc and/or protobuf installation or upgrade to a newer version.
make
を使う方式だと公式ドキュメントにも「一度インストールしてしまえば削除するのは難しいからアップグレードのときとか困るよ」と書いてある…。
🌿 環境を汚さずに Docker でコード生成を行う
上のやり方を試したところ確かに C++ コードの生成はできたが、イケてないので Docker を使ってコード生成することにする。
前提として下記のようなディレクトリ構成にした。protobuf
ディレクトリにいろんな .proto
ファイルが配置されていて、codegen
ディレクトリに生成コードを出力。Dockerfile とスクリプトは tools
ディレクトリに置いた。
project ├── protobuf │ └── rpc │ ├── auth │ │ └── auth.proto │ ├── rpc.proto │ ├── setting │ │ └── language.proto │ └── user │ └── user.proto ├── codegen │ └── .gitkeep └── tools └── Dockerfile │ └── gen_grpc_cpp.sh
🐳 Dockerfile
gRPC 公式が C++ 用の Docker イメージを公開しているのでそれを使う。
docker run
すると bash
が起動するので protoc
と grpc_cpp_plugin
が使えることがわかる。
$ docker run -it --rm grpc/cxx root@55d8450a784e:/# protoc --version libprotoc 3.5.0 root@55d8450a784e:/# which grpc_cpp_plugin /usr/local/bin/grpc_cpp_plugin
この Docker イメージを利用した Docker ファイルが下記。
ホストの ./protobuf
ディレクトリをコンテナの /workspace/protobuf
ディレクトリへすべてコピーし、コンパイルを実行している。gRPC コードを生成する場合は --grpc_out
オプションを使う必要がある。
末尾で対象ファイルを指定しているが **/*.proto
で再帰的に配下のディレクトリすべてを対象に加えてほしいところだけど、そうは動作してくれないので、階層数に応じて複数ディレクトリを愚直に指定している。
🐚 tools/gen_grpc_cpp.sh
上記の Docker イメージを使うシェルスクリプトを書いた。流れとしては、
- Docker ビルド
- Docker 実行
- コンテナのファイルをホストにコピー
- 後始末
3番のコンテナ内のファイルをホスト(Mac)にコピーするには docker cp を使うしかないため、このシェルスクリプトが必要となる。もしこのコピーが Dockerfile に記述できるようになれば Docker 実行だけでコード生成&コピーできるようになるが、今の所できないようだ。