かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Mac ファイルコピーする時にゴニョゴニョ変更したい

チーム作業してると開発が進むにつれて追加や変更が頻発する環境変数の扱いが悩ましいです。
.env.sample のようなキーだけ書かれたファイルを git 管理することが多いのですが、これをリネームする際にファイルに書かれている内容をゴニョゴニョしたい事があったのでメモ

CONS cp でコピーはコピーするだけ

$ cp .env.sample .env

.env.sample.env というファイル名でコピー。コピーなので内容の変更はできない

sed でファイルの中身を変更したり削除したりできる

sed -e 処理内容 でファイルの変更ができ、-e 区切りで処理を連続して行うことができる

  • sed -e 's/xxx/ZZZ/g' ... xxx を全て ZZZ に置き換える
  • sed -e 1,3d … 1行目〜3行目までを削除
  • sed -e 's/xxx/ZZZ/g' -e '/^$/dxxx を全て ZZZ に置き換えて、空行を削除する

e.g.

下記のような .env.sample があり、1〜2行目を削除して http://localhost:4000https://my-api.com に置換、空行を削除して .env として出力したい

# コメントです

HOST=http://localhost:3000
API=http://localhost:4000
API_FOR_ADMIN=http://localhost:4000/admin

# Token を取得して設定してください

SECRET_TOKEN=

👇

$ cat .env.sample | sed -e 1,2d -e 's/http:\/\/localhost:4000/https:\/\/my-api.com/g' -e '/^$/d' > .env

👇 .env

HOST=http://localhost:3000
API=https://my-api.com
API_FOR_ADMIN=https://my-api.com/admin
# Token を取得して設定してください
SECRET_TOKEN=

₍ ᐢ. ̫ .ᐢ ₎ すごい!

📝 sed での空白行とコメント行の削除

よく使いそうなので

  • 空白行の削除 … sed -e '/^\s*$/d'
  • # から始まるコメント行の削除 … sed -e '/^\s*#/d'

空白行とコメント行をまとめて削除

$ sed -e '/^\s*$/d' -e '/^\s*#/d'

正規表現は自信がないけど

  • 空白行の削除 /^\s*$/d^\s* は先頭に空白がいくらあってもで $ が行末なので、空白だけの行にマッチ。最後の dsed の削除コマンド
  • コメント行の削除 /^\s*#/d^\s* で行頭のスペースを許容して # なので # から始まるコメント行にマッチ。最後の dsed の削除コマンド

grep -v を使ってもコメント行を削除できる

  • grep -v … マッチした箇所を除外

e.g. .env.sample# から始まるコメント行と空白行を削除して .env として出力

$ cat .env.sample | grep -v -e '^\s*#' -e '^\s*$' > .env

₍ ᐢ. ̫ .ᐢ ₎👌

grepsed| (パイプ) で連結できる

e.g.
下記 .env.sample のコメント行と空白行を削除して http://localhost:4000https://my-api.com に置換したい

# env.sample
# コメントです

HOST=http://localhost:3000
API=http://localhost:4000
API_FOR_ADMIN=http://localhost:4000/admin

# Token を取得して設定してください

SECRET_TOKEN=
  

👇 grep でコメント行と空白行を削除して sed で置換する

$ cat .env.sample | grep -v -e '^\s*#' -e '^\s*$' | sed -e 's/http:\/\/localhost:4000/https:\/\/my-api.com/g' > .env

👇 .env

HOST=http://localhost:3000
API=https://my-api.com
API_FOR_ADMIN=https://my-api.com/admin
SECRET_TOKEN=

₍ ᐢ. ̫ .ᐢ ₎👌

完 全
理 解


[参考]

ts-node で path alias が効かないにハマる

TypeScript な Express を ts-node で動かしてて tsconfig.json に path alias を設定したんだけどエラーになってなんもわからん。ってなったのでメモ

環境
  • typescript: ^4.5.4
  • ts-node: ^10.4.0
  • ts-node-dev: ^1.1.8

結論

tsconfig-paths を使って ts-node 実行時に -r tsconfig-paths/register オプションを渡してあげれば OK

package.json (entry point が src/index.ts の場合)

{
  "scripts": {
    "start": "ts-node -r tsconfig-paths/register src/index.ts",
    "dev": "ts-node-dev -r tsconfig-paths/register src/index.ts",
    "build": "tsc"
  }
}

tsconfig.json

{
  "compilerOptions": {
    // …
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    }
}

/src 内のファイルを @/ で import できるようにパスエイリアスを設定した

npm script

package.json

{
  "scripts": {
    "start": "ts-node src/index.ts",
    // … 
  }
}

ts-node で path alias が効かなくてエラーになる

$ npm run start
> server@1.0.0 start
> ts-node src/index.ts
[ERROR] 23:53:57 Error: Cannot find module '@/data/xxx'

パスエイリアスを使っている module のところでエラーになる
なんもわからん…

ts-node は単体では path alias に対応してないっぽい

That's the node.js error - TypeScript is working fine, but node will never be able to resolve an alias like that unless TypeScript emits code that rewrites paths.
cf. tsconfig.json/paths not working with ts-node · Issue #138 · TypeStrong/ts-node · GitHub

tsconfig-paths を使う

ts-node -r tsconfig-paths/register として呼び出せば ts-node でも path alias が効くようになるっぽい!

$ npm i -D tsconfig-paths

package.json を書き換える

{
  "scripts": {
-   "start": "ts-node src/index.ts",
+   "start": "ts-node -r tsconfig-paths/register src/index.ts",
    // … 
  }

再実行

$ npm run start
> server@1.0.0 start
> ts-node src/index.ts

Start on port 4000.

₍ ᐢ. ̫ .ᐢ ₎👌 解☆決

tsconfig.json に設定する方法もある

typescript-transform-paths を使えば設定を tsconfig.json にまとめられて npm script で -r tsconfig-paths/register オプションを渡さなくてもOKになる

cf. tsconfig.json/paths not working with ts-node · Issue #138 · TypeStrong/ts-node · GitHub

$ npm i -D typescript-transform-paths

package.json

{
  "scripts": {
-   "start": "ts-node -r tsconfig-paths/register src/index.ts",
+   "start": "ts-node src/index.ts",
    // … 
  }

tsconfig.json

{
+ "ts-node": {
+  "transpileOnly": true,
+  "require": [
+   "typescript-transform-paths/register",
+   "tsconfig-paths/register"
+   ]
+ },         
  "compilerOptions": {
    // …

👇

$ npm run start
> server@1.0.0 start
> ts-node src/index.ts

Start on port 4000.

₍ ᐢ. ̫ .ᐢ ₎👌


ts-node-dev での path alias

ts-node では開発時にファイルを監視してのホットリロードができません。以前は nodemon を使ってたのですが ts-node-dev の方が高速でナウでヤングらしいので導入してみました。

$ npm i -D ts-node-dev

ts-node-dev もデフォルトではパスエイリアスが効かない

ts-node-dev も ts-node と同様でデフォルトでは tsconfig.json に書かれているパスエイリアスが効かないので実行時に -r tsconfig-paths/register オプションを渡してあげる必要があります

package.json

{
  "scripts": {
   "start": "ts-node -r tsconfig-paths/register src/index.ts",
   "dev": "ts-node-dev -r tsconfig-paths/register src/index.ts"
    // … 
  }
}

👇

$ npm run dev
> server@1.0.0 dev
> ts-node-dev -r tsconfig-paths/register src/index.ts

[INFO] 00:55:03 ts-node-dev ver. 1.1.8 (using ts-node ver. 9.1.1, typescript ver. 4.5.4)
Start on port 4000.

src/index.ts や import しているファイルを変更した際に自動的に再起動されればOK
₍ ᐢ. ̫ .ᐢ ₎👌👌👌

⚠ ts-node-dev では typescript-transform-paths を使って tsconfig.json にまとめる方法がうまく動作しない

ts-node と同じように tsconfig.json にパスエイリアスの設定をまとめられるかと思ったけど、うまく動作させられなかった

tsconfig.jsonts-node-dev のセクションを追加

{
  "ts-node": {
    // …
  },
+ "ts-node-dev": {
+  "transpileOnly": true,
+  "require": [
+   "typescript-transform-paths/register",
+   "tsconfig-paths/register"
+   ]
+ },         
  "compilerOptions": {
    // …

package.json の npm script からオプションを削除

{
  "scripts": {
   "start": "ts-node  src/index.ts",
-  "dev": "ts-node-dev -r tsconfig-paths/register src/index.ts"
+  "dev": "ts-node-dev src/index.ts"
    // … 
  }

👇 パスエイリアスが解決できない

$ npm run dev
> server@1.0.0 dev
> ts-node-dev src/index.ts

[INFO] 01:01:28 ts-node-dev ver. 1.1.8 (using ts-node ver. 9.1.1, typescript ver. 4.5.4)
Error: Cannot find module '@/data/xxxx'[ERROR] 01:01:32 Error: Cannot find module '@/data/xxxx'

typescript-transform-pathsts-node-dev のセクションを作れないっぽいです。
もしかしたら tsconfig.jsoncompilerOptions 内で設定すればうまく動作させられるかもですが、そこまでは調べませんでした。

所感

typescript-transform-paths を使うとパスエイリアスの解決関連を tsconfig.json にまとめられて npm script の見た目はシンプルになるけど、開発で使うだろう ts-node-dev でいい感じに動作させられなかったし、パッケージも増えてしまうのでシンプルに ts-node, ts-node-dev 両方に -r tsconfig-paths/register オプションを渡してしまうのが良さそうだと思いました。

package.json

{
  "scripts": {
   "start": "ts-node -r tsconfig-paths/register src/index.ts",
   "dev": "ts-node-dev -r tsconfig-paths/register src/index.ts"
    // … 
  }
}

おわり。


[参考]

銀河

銀河

Amazon

Git submodule が最新に更新されない件

$ git submodule update

update やし最新に更新されるやろ…っておもったら最新にならなかった。diff をみたら最新でないコミットハッシュからチェックアウトされていました。
なんもわからん…

全 submodule を強制的にする

$ git submodule foreach git pull origin main

submodule を foreach で回して全リポジトリgit pull origin main をする方法。
楽だけど、特定の submodule だけ最新にしたいとか、main じゃないブランチから取ってきたいって場合に困る

update には --remote オプションが必要だった

--remote オプションを付けると git fetch した上で pull してくれるっぽい。
オプション付けないときのアップデート is 何…

git submodule update コマンドには submodule のパスを渡すと、該当の submodule だけにコマンドを実行できるので、特定の submodule を最新にしたい時は次のようなコマンドを実行すれば OK っぽい

$ git submodule update --remote <submodule path>

おわり

Git submodule ムズすぎる…


[参考]

なんでもあるな…