Python, Djangoをきちんと使いたい_02: Poetry でパッケージ管理

皆さまこんにちは、ウチイダです。

Python開発環境を整えるメモ、今回はパッケージ管理の仕組みをやっていきます。

前回はpythonランタイムのバージョン管理のためにpyenv を導入しました。

ウチイダの作業環境は以下です。

  • Windows 11 21H2
  • WSL2 Ubuntu20.04
  • GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)

以降の内容は、この環境にPython/Djangoの開発環境を導入していく手順メモとなります。

Python のパッケージ管理ツール

公式かつ最大手のpip

パッケージ管理ツールは公式からpip が提供されていますが、どうやら依存解決に難があるようなのです。

pip install しても、composer やnpmみたいに lock ファイルとかできないですしね…

あと、依存解決でインストールされたパッケージが、他からの依存がなくなっても削除されなかったりするようです。

ウチイダは基本的に公式のツールを使っていきたいスタンスですが、これはさすがに不安が残ります。

Pipenv, Poetry, Pyflow

というわけで、ほかの言語のパッケージ管理ツール機能を持ったサードバーティのツールを調べてみました。

Pipenv, Poetry, Pyflow の3つが有力っぽいです。Pipenv が先にリリースされて、そのあとにPoetry、 Pyflow の順番でリリースされています。

いろいろ調べたのですが、タイトルの通りPoetry を使ってみることにしました。

https://python-poetry.org/

比較は今回の趣旨ではないので、ごく簡単に理由を書いておくことにします。

  • PEPで策定されてる形式の設定ファイル(pyproject.toml)ひとつで管理できる方式
  • pyproject.toml が使えるのがPoetry とPyflow
  • Pyflow はまだ安定してないっぽい(バージョン1になってない)

選定が妥当かどうかはわかりません。技術選定の審美眼ほしい。

インストール

# 1. インストール用のスクリプトを読み込んで実行
$ curl -sSL https://install.python-poetry.org | python3 -
Retrieving Poetry metadata

# Welcome to Poetry!

This will download and install the latest version of Poetry,
a dependency and package manager for Python.

It will add the `poetry` command to Poetry's bin directory, located at:

/home/y-uchiida/.local/bin

You can uninstall at any time by executing this script with the --uninstall option,
and these changes will be reverted.

Installing Poetry (1.2.2): Done

Poetry (1.2.2) is installed now. Great!

To get started you need Poetry's bin directory (/home/y-uchiida/.local/bin) in your `PATH`
environment variable.

Add `export PATH="/home/y-uchiida/.local/bin:$PATH"` to your shell configuration file.

Alternatively, you can call Poetry explicitly with `/home/y-uchiida/.local/bin/poetry`.

You can test that everything is set up by executing:

`poetry --version`

# 2. パスが通っていなければ、以下を追加
$ echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc

# 3. poetry が実行できれば完了!
$ poetry --version

Poetry のアップデート

インストールした直後なので不要ですが、未来の自分のためにメモ。

poetry self update で更新します。

$ poetry self update
Updating Poetry version ...

Using version ^1.2.2 for poetry

Updating dependencies
Resolving dependencies... Downloading https://files.pythonhosted.org/packages/d1/20/4c2ea55d6547460a93dce9112599953be1c9Resolving dependencies... Downloading https://files.pythonhosted.org/packages/1d/38/fa96a426e0c0e68aabc68e896584b83ad1eeResolving dependencies... Downloading https://files.pythonhosted.org/packages/76/cb/6bbd2b10170ed991cf64e8c8b85e01f2fb38Resolving dependencies... (25.9s)

Writing lock file

No dependencies to install or update

Poetry のアンインストール

インストールしたばかりなのでこちらも不要ですが、未来の自分のためにメモ。

インストールのコマンドの最後に –uninstall オプションをつけるだけです。削除のためのモードも含めてるんですね。

$ curl -sSL https://install.python-poetry.org | python3 - --uninstall
Removing Poetry (1.2.2)

Poetry でプロジェクトを作る

空のプロジェクトを作るなら、poetry new <プロジェクト名>、

既存のディレクトリに作成する場合はpoetry init です。

# 新しくプロジェクト用のディレクトリを作る場合
$ poetry new porty_new_sample
Created package porty_new_sample in porty_new_sample

# 既存のディレクトリにプロジェクトを追加する場合
$ poetry init

Poerty で仮想環境を作る

Poetry はPythonのバージョン管理こそできませんが、仮想環境を作成することができます。

Python の公式ツールとなったvenv でも仮想環境は作れますが、仮想環境を起動してからスクリプトを実行しないといけないのですこし面倒です。

poetry は、そのCLIから仮想環境のランタイムで指定のスクリプトが実行できるので、開発中のコマンド実行が少し楽になるかもしれません。コマンド実行ごとのタイプ量が増えるので、一長一短かも。

仮想環境の作成先を設定

デフォルトの設定では、Poetryの仮想環境は$HOMEディレクトリ配下の専用ディレクトリに作成されます。

どの仮想環境が実行されているのかわかりづらくなるので、プロジェクトのディレクトリ内にあったほうがいいな…と思います。

というわけで、プロジェクトディレクトリ内に仮想環境が作成されるように、設定をしておきます。

$ poetry config virtualenvs.in-project true

これで、仮想環境は各プロジェクトのディレクトリ内に作成されます。

デフォルトでは.venv というディレクトリ名のようです。

仮想環境を作成・実行する

現在のターミナルで仮想環境に入るときは poetry shell、

仮想環境でコマンドを実行する場合はpoetry run <実行するコマンド>です。

# 仮想環境に入る
poetry_venv_test$ poetry shell
Spawning shell within /home/y-uchiida/poetry_venv_test/.venv
. /home/y-uchiida/poetry_venv_test/.venv/bin/activate
poetry_venv_test$ . /home/y-uchiida/poetry_venv_test/.venv/bin/activate
(poetry-venv-test-py3.11) :poetry_venv_test$

# 出る時はexit (deactivate でもOK)
(poetry-venv-test-py3.11) :poetry_venv_test$ exit

パッケージのインストール

では本題、パッケージのインストールです。

ためしにDhango 3.2 をインストールしてみます。

# パッケージを追加
$ poetry add django==3.2
Creating virtualenv poetry-add-pachage-sample in /home/y-uchiida/poetry_add_pachage_sample/.venv

Updating dependencies
Resolving dependencies... (0.1s)

Writing lock file

Package operations: 4 installs, 0 updates, 0 removals

  • Installing asgiref (3.5.2)
  • Installing pytz (2022.6)
  • Installing sqlparse (0.4.3)
  • Installing django (3.2)

# poetry.lock ができてる!
$ ll
total 28
drwxr-xr-x 5 y-uchiida y-uchiida 4096 Nov 22 16:02 ./
drwxr-xr-x 5 y-uchiida y-uchiida 4096 Nov 22 16:01 ../
drwxr-xr-x 4 y-uchiida y-uchiida 4096 Nov 22 16:02 .venv/
-rw-r--r-- 1 y-uchiida y-uchiida    0 Nov 22 15:42 README.md
-rw-r--r-- 1 y-uchiida y-uchiida 2131 Nov 22 16:02 poetry.lock
drwxr-xr-x 2 y-uchiida y-uchiida 4096 Nov 22 15:42 poetry_add_pachage_sample/
-rw-r--r-- 1 y-uchiida y-uchiida  356 Nov 22 16:02 pyproject.toml
drwxr-xr-x 2 y-uchiida y-uchiida 4096 Nov 22 15:42 tests/

poetry.lock の中身は長いので載せませんが、テキストファイルになっているので普通に読めます。

[[package]] と [package.dependencies] がセットになって、依存関係を表現しているようです。

Poetry にタスク実行機能はないのか

さて、ここまでくると、開発中に利用できるタスクランナーの機能が欲しくなってきます。

結論から言うと、Poetry はタスクランナーの機能は付いていません。

poetry run でそういうことができないのか調べてみたのですが、どうも目的が違うようです。

別のツールを使うか、Makefileなどでショートハンドを作ったりするのがよさそうです。

まとめ

今回はPoetry を利用してパッケージの依存関係ができるようにしてきました。

ウチイダはとても便利だと思ったのですが、公式の強さか、最も利用されているのはpipのようです。

依存関係が管理できないとなんだか不安なのは、Node.js やPHP での経験があるからこそでしょうか…

いずれにしても、効率的なチーム開発にはあったほうがよいでしょうし、導入している例も結構多いようなので、触っておいて損はないかなと思います。

以上です。あなたのお役に立てればうれしいです。

Python, Django をきちんと使いたい 01: Pythonのバージョン管理のためにpyenv を導入【Win11/WSL2-Ubuntu】

皆さまこんにちは、ウチイダです。

Python/Djangoの案件にかかわることになりそうで、改めて勉強しなおそうと思っています。

Djangoはチームの開発で使ったことがなかったので、これを機に周辺ツールの知識もまとめておくことにしました。

ウチイダの作業環境は以下です。

  • Windows 11 21H2
  • WSL2 Ubuntu20.04
  • GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)

以降の内容は、この環境にPython/Djangoの開発環境を導入していく手順メモとなります。

まずはPythonのバージョン管理ツールから

何はともあれ、ランタイムのバージョン管理を入れることにします。

Node.js のnodenv やvolta とか、PHP のphobrew みたいなものを探してみます。

調べたところ、pyenv がよくつかわれているようです。

https://github.com/pyenv/pyenv

anyenv にも含まれているツールです。rbenv をフォークしてPython 用にしたものだとのこと。

メンテナンスも継続されてるようなので、pyenvを使うことにしました。

インストールする

未来の自分が別の環境でコピペ利用できるように、なるべく汎用的なやり方にしておきます。

GitHubのREADMEに情報がまとまっているので、これに沿って進めれば大丈夫そうです。

https://github.com/pyenv/pyenv#basic-github-checkout

GitHub のリポジトリをクローンする方法で進めます。

READMEに書いてあるのそのままですが、実行するコマンドと出力結果例は以下です。

以下のコマンドをコピペで大丈夫だと思うのですが、いくつか留意すべき点があります。

# 1. リポジトリをclone する
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
Cloning into '/home/y-uchiida/.pyenv'...
remote: Enumerating objects: 22214, done.
remote: Counting objects: 100% (282/282), done.
remote: Compressing objects: 100% (154/154), done.
remote: Total 22214 (delta 141), reused 237 (delta 112), pack-reused 21932
Receiving objects: 100% (22214/22214), 4.49 MiB | 4.40 MiB/s, done.
Resolving deltas: 100% (15003/15003), done.

# 2. 高速化のためのBash拡張のコンパイル(やらなくてもOK)
$ cd ~/.pyenv && src/configure && make -C src
make: Entering directory '/home/y-uchiida/.pyenv/src'
gcc -fPIC     -c -o realpath.o realpath.c
gcc -shared -Wl,-soname,../libexec/pyenv-realpath.dylib  -o ../libexec/pyenv-realpath.dylib realpath.o
make: Leaving directory '/home/y-uchiida/.pyenv/src'

# 3-1. ~/.bashrc にpyenv の設定を追加(pyenv がデータを保存するディレクトリを指定)
$ echo "#setting for pyenv" >> ~/.bashrc
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc

# 3-2. 同じ内容を、 ~/.bash_plofile にも追加する
$ echo "#setting for pyenv" >> ~/.bash_profile
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile

# 4. 設定を読み込み
$ source ~/.bashrc

# .5 pyenv が実行できれば完了!
$ pyenv -v
pyenv 2.3.6-15-g13d85686

補足・留意点

1. Bash 設定ファイルについて

上記コマンドの中で、.bashrc と.bash_profile にpyenv の設定を追加していますが、READMEによると$HOMEにあるbashの設定ファイル全部に書いとくと安心、とのことです。

ウチイダは自身の$HOME ディレクトリに上記の2つだけしか存在してなかったので、これだけ設定しています。

人によっては .profile とか、.bash_login があるかもしれないので、その場合は同じように追記しておくとよさそうです。

2. $BASH_ENV 環境変数について

$BASH_ENV が .bashrc に設定されてる場合の注意点が記載されてます。

この場合、eval “$(pyenv init -) を .bashrc に記述しておくと、pyenv が無限ループを起こしてしまうとのこと…

echo $BASH_ENV で設定値を確認して、もし.bashrc になっていたら、eval の行は .bashrc から取り除いておきます。

pyenv でPythonをインストール

いくつかの罠を越えてpyenv をインストールできたら、さっそく使っていきましょう。

# 1. インストール可能なバージョンの一覧を表示
$ pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4.0
# ... 以下略

# 2. バージョンを指定してインストール(3.10.x)
$ pyenv install 3.10
Downloading Python-3.10.8.tar.xz...
-> https://www.python.org/ftp/python/3.10.8/Python-3.10.8.tar.xz
Installing Python-3.10.8...
Installed Python-3.10.8 to /home/y-uchiida/.pyenv/versions/3.10.8

# 3. デフォルトで動作するバージョンを設定
$ pyenv global 3.10
$ python --version
Python 3.10.8

# 4. 現在のディレクトリで動作するバージョンを指定
$ pyenv local 3.10

pyenv local は、実行したディレクトリに.python-version というファイルを作って、そこに利用するバージョンを書き込んでいます。

.python-version ディレクトリ階層をみて、直近の上位ディレクトリの.python-version に記載されたバージョンを使ってくれます。

そのほかの使い方は、pyenv –help を実行すると詳しく出てきます。

まとめ

pyenv を導入して、バージョン切り替えできるようにしました。

これで万が一、複数バージョンが必要になった場合も安心です。

それにしても、Pythonってサポート期間長いんですね…どのバージョンも5年ある…

ライブラリも、過去バージョンのサポートを長めに続けているようなので、意外とプロジェクトごとに厳密にバージョン分けする機会ってないのかも…と感じてます。

本当にきっちりやるなら、Dockerとか仮想マシン使うでしょうし…

とはいえ、pythonに限らないですが、OSの公式リポジトリだと最新バージョンをインストールできない場合も多いです。

気軽に最新バージョンに追従できるようにしておくのは悪くなんじゃないかと思います。

以上です。あなたのお役に立てればうれしいです。

firebase init で Firestore のエラー:Realtime DBを設定したら直った

皆さまこんにちは、ウチイダです。

最近はFirebase を勉強中です。スマホ対応のWebアプリの開発速度が高まりそうでわくわくしています。

開発もどんどん進んでいるのか、謎のエラーやドキュメントに書いてない事象にぶつかっては、調べ物をしているので、なかなかスムーズに進んでいませんが…

そんな中で、よくわからないエラーに遭遇したのでメモしておきます。

開発環境

  • Windows 11 21H2
  • WSL2 Ubuntu20.04
  • Node.js v16.18.1
  • npm 8.19.2
  • firebase CLI v11.16.0

事象

Firebase CLI で、firebase のプロジェクト設定の初期化をしたところ、以下のようなエラーが。

$ firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

# ... 中略

=== Firestore Setup

Error: It looks like you haven't used Cloud Firestore in this project before. Go to https://console.firebase.google.com/project/xxxxxxx/firestore to create your Cloud Firestore database.

「Firestore のデータベースが作成されていない」とのことですが、設定画面上では作成済みになっています。

作成直後だから、CLIから読み取るのにタイムラグがあるのかな、と思って数分置いてみたものの改善せず。

対策:Realtime Database を作成する

いろいろ調べているうちに、Firestore を設定していても、プロジェクト上で設定が認識されない場合があるらしいことがわかってきました。

たとえば、SDK用のconfig 設定値にDatabase URLがないとか…

その対策として、Realtime Databaseをプロジェクトに作成する、ということが書かれていました。

参考:【Firebase】databaseURLが見当たらない?

https://engineering.webstudio168.jp/2022/02/firebase%E3%81%A7databaseurl%E3%81%8C%E8%A6%8B%E5%BD%93%E3%81%9F%E3%82%89%E3%81%AA%E3%81%84%EF%BC%9F/

もしやと思って、使う予定はないけどRealtime Databaseを作成してみたら、改善しました。

$ firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

# ... 中略

=== Firestore Setup
# エラーが消えて、先に進んだ
Firestore Security Rules allow you to define how and when to allow
requests. You can keep these rules in your project directory
and publish them with firebase deploy.

FireStore とRealtime Databaseは、用途の違う別物だと思ってたのですが、なんらかの設定が共有されているのでしょうか…

よくわからないけど、調べても原因がわからなかったので、Firestore を使うときはRealtime Database も一緒に有効化することにしようと思います…

以上です。あなたのお役に立てればうれしいです。

Vite で自動ビルドしたい – build に –watch オプションをつける

皆さまこんにちは、ウチイダです。

React とともに、firebase を本格的に触り始めています。

React + firebase で開発速度を上げて、小規模の開発を効率化できないかな~と試行錯誤しています。

firebase の エミュレータがとても充実しているということを最近知りました。便利です。

今回はその中で調べたことをメモしておきます。

firebase hosting のエミュレータが修正を反映しない

ソースコードを修正して、hosting エミュレータのURLを開いても変更が反映されません。

よくよく考えれば当たり前なんですけど、「hosting のエミュレータ」なので、ビルド済みの静的ファイルを読み込んでいるんですよね。

hosting のエミュレータで修正内容を反映するには、ソースコード修正後は一度ビルドしてデプロイ用のファイルも更新しないといけません。

Vite でローカル環境を動かしていたので、つい忘れていました。

Vite のビルドを自動で実行する

とはいえ、毎回手動でビルドのコマンドを実行するのは面倒です…

ソースコードを修正して保存したら、自動でビルドを実行してもらいたいです。

というわけで結論から。以下のコマンドで、Vite(の内部で動いてるRollup)を、watch モードで実行することができます。

$ npx vite build --watch
vite v3.2.2 building for production...

watching for file changes...

build started...
✓ 974 modules transformed.
# ... 省略 ...
built in 7582ms.

公式サイトには言及が少ないですが、

vite build --watch で rollup のウォッチャを有効にすることができます。

本番環境用のビルド | Vite

と書いてありました。

https://ja.vitejs.dev/guide/build.html#ファイル変更時のリビルド

Vite コマンドのヘルプにも、オプションの一覧に載っていました。

$ npx vite build --help
vite/3.2.2

Usage:
  $ vite build [root]

Options:
# ... 省略 ...
  -w, --watch                   [boolean] rebuilds when modules have changed on disk 
  -c, --config <file>           [string] use specified config file 
  --base <path>                 [string] public base path (default: /) 
  -l, --logLevel <level>        [string] info | warn | error | silent 
  --clearScreen                 [boolean] allow/disable clear screen when logging 
  -d, --debug [feat]            [string | boolean] show debug logs 
  -f, --filter <filter>         [string] filter debug logs 
  -m, --mode <mode>             [string] set env mode 
  -h, --help                    Display this message

npm script にも、build:watch として 登録しておきました。

{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "build:watch": "vite build --watch",
    "preview": "vite preview"
  },
}

まとめ

ビルド処理には少し時間かかってしまいますが、毎回手でコマンド実行するよりははるかにいいですね。

基本的にはHMRが使えるVite サーバ上で作業して、hosting エミュレータ上で動作確認・微調整をする際にwatch モードで自動ビルドさせようと思います。

以上です。あなたのお役に立てれば幸いです。

Vite で作ったアプリで環境変数を扱いたい – .env にVITE_をつけて記述する

皆様こんにちは、ウチイダです。

ここしばらくReact をキャッチアップしています。

数年前にすこしだけやってみたときは全くできなかったのですが、Vue とかAngular 挟んだら雰囲気がわかるようになりました。

その間にReact 自体も理解しやすくなってきてるのかなと思います。

hooks使わないコードとか、クラスコンポーネントのライフタイムサイクルとかはいまでもよくわからないです。以前はもっと難しかったんだろうな…

さて、今回はViteで環境変数を使う場合のTipsです。

vite における環境変数の取り扱い

  • vite は、デフォルトでvite.config.ts と同じ階層にある.env ファイルのうち、VITE_ から始まる環境変数を読み込みされる
  • 読み込みするファイルのディレクトリは、vite.config.ts のenvDir プロパティで設定できる
  • アプリケーション内からこの環境変数を利用する場合は、import.meta.env. と記述する
  • process.env からは利用できないので注意!
# 以下の変数はVite で読み込みされ、参照できる
VITE_VAR_TEST='this is available'

# VITE_ で始まらない変数は読み込みされない
UNAVAILABLE_VAR_IN_VITE='this is unable'

参考

わかりやすい日本語でバッチリ公式ドキュメントに書いてあります。

Vite の公式ドキュメントはわかりやすいのでおすすめ、が最も有益なTipsだったかもしれません。

以上です。あなたのお役に立てればうれしいです。

ESLint の初期設定時、Airbnb のスタイルガイドが選択肢に表示されない – 手動インストールする

みなさんこんにちは、ウチイダです。

最近フロントエンドをきちんと学ぼうと思って、Reactのキャッチアップを進めています。

せっかくなのでTypeScriptで開発するようにしているのですが、その際の環境構築でつまづくことがあったので書き留めておきます。

環境

  • Windows 11 21H2
  • WSL2 Ubuntu20.04
  • Node.js v18.12.0
  • npm 8.19.3

事象:Airbnbのスタイルガイドを選択できない

JavaScriptのスタイルガイドとしてポピュラーなものに、Airbnb が作成しているものがあります。

これをESLintでのチェックに利用しようと思いました。

ESLint を導入する際、以下のコンフィグファイルの初期化コマンド を実行します。

$ npm init @eslint/config 

手順を説明しているページなどを見ると、スタイルガイドの選択時にAirbnbが出てくるようだったのですが、ウチイダの環境だとそれが表示されませんでした。

選択肢が2つしか表示されない

原因:AirbnbのスタイルガイドがTypeScriptに対応していないため

初期設定を行うコマンド eslint-config で行われた修正が原因でした。

ここで、TypeScriptに標準で対応していないスタイルガイドを表示しないように変更されていました。

https://github.com/eslint/create-config/pull/33

自分の作業手順漏れを疑っていたのですが、仕様変更だったんですね。。。

ちなみに、これは最近参加しているコミュニティの方が調べて教えてくれました。感謝!

対応:手動でAirbnbのスタイルガイドを追加する

自動でインストールしてくれないのは仕方ないので、とりあえずeslintrc の生成を済ませて、あとからAirbnbのスタイルガイドを読み込ませるように設定していきます。

1. eslintrc を生成する

スタイルガイドでStandard を選択して、設定を進めます。

次に「依存パッケージをインストールするか」を聞かれるので、no を選んでおきます。

Standardのスタイルガイドのパッケージを後から削除するのであれば、yes でもよいです。

$ npm init @eslint/config
✔ How would you like to use ESLint? · style

✔ What type of modules does your project use? · esm

✔ Which framework does your project use? · react

✔ Does your project use TypeScript? · No / Yes

✔ Where does your code run? · browser

✔ How would you like to define a style for your project? · guide

✔ Which style guide do you want to follow? · standard-with-typescript

✔ What format do you want your config file to be in? · JavaScript

Checking peerDependencies of eslint-config-standard-with-typescript@latest
Local ESLint installation not found.
The config that you've selected requires the following dependencies:

eslint-plugin-react@latest eslint-config-standard-with-typescript@latest @typescript-eslint/eslint-plugin@^5.0.0 eslint@^8.0.1 eslint-plugin-import@^2.25.2 eslint-plugin-n@^15.0.0 eslint-plugin-promise@^6.0.0 typescript@*

✔ Would you like to install them now? · No / Yes

A config file was generated, but the config file itself may not follow your linting rules.
Successfully created .eslintrc.cjs file in /home/y-uchiida/develop/eslint_airbnb_none

2. Airbnb のスタイルガイドのパッケージを追加する

npm で、スタイルガイドのパッケージを導入します。

Airbnb のTypeScript のスタイルガイドは本家の設定の拡張なので、本家も含めてインストールします。

$ npm install --save-dev eslint-config-airbnb eslint-config-airbnb-typescript

3. eslintrc にスタイルガイドを読み込ませる

eslintrc を編集して、Airbnb のスタイルガイドを読み込みさせます。

    "extends": [
        "plugin:react/recommended",
        // "standard-with-typescript" // standard スタイルガイドは使わないので消す
        'airbnb', // 追加
        'airbnb-typescript' // 追加
    ],

ちなみに、Reactのプロジェクトかそうでないかによって、利用するパッケージが違うので注意が必要です。

詳しくはGitHubのREADMEをご確認ください…

https://github.com/iamturns/eslint-config-airbnb-typescript#setup

まとめ

ESLintの初期設定を自分でやったことがなかった&比較的最近の変更で、見つかる情報と齟齬があった(Airbnbが出てくると書いてあるものが多かった)ことでハマってしまいました。

ツールチェイン周りのキャッチアップは大変です…

ちなみに、ウチイダと同じ疑問を持った人がGitHubでissueを立てていました。

やり方を覚えてしまえばなんてことはないですが、手作業インストールするのちょっとだけ面倒ですね…

上記のissueの中で、「将来的に –config オプションを実装する予定があるので、それができたら簡単になるよ」といった旨のコメントがついていました。

https://github.com/eslint/create-config/issues/35#issuecomment-1216457480

早く利用できるようになるといいですね。

それでは以上となります。あなたのお役に立てれば幸いです。

何度も調べちゃう英単語:e.g.

こんにちは、ウチイダです。

厳密には英単語じゃないのですが、今回は e.g. について。

たまに英文の中で見かける略記号e.g. 。

読み飛ばしても意味が通るので気にしないことが多いのですが、ふと気になっては何度か調べているのでメモしておきます。

ラテン語の exampli gratia からきているのだそう。日本語では「例えば」などが該当する言葉です。

英語にすると for example でしょうか。

原語の意味はまた忘れてしまいそうですが、とりあえず「読み飛ばしても意味は通る」ということを確認できました。

Laravel Sail のプロジェクトを新規作成する際にDocker is not running. – Docker Desktop 再起動で改善

こんにちは、ウチイダです。

今日は、以前からたびたび発生しては時間を地味に奪っていくエラーについて。

Laravel Sail のプロジェクトを作成する際に、以下のようなエラーが出ます。

$ curl -s "https://laravel.build/laravel_app" | bash
Docker is not running.

そもそも、WSLからdocker コマンドが使えません。ソケットが開いてない?

$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

WSLの再起動をやってみても、解消したりしなかったり、だったのです。

しかし、最近試してみた方法で、すぐに直せることが分かったのでメモしておきます。

タスクバーからDockerのアイコンを右クリック > Restart する

以上です。

DockerDesktopを再起動するだけ

WSLを止めて起動しなおしたり、WSL側のDocker デーモンの動作を確認したりしてましたが、全然関係なかったみたいです。

発生する原因はわからないままなのですが、すぐに解消できるようになったので、しばらくこの方法で対応したいと思います。

以上、あなたのお役に立てれば幸いです。

住所の文字列から都道府県を抜き出すPHPの実装例

こんばんは、ウチイダです。

住所のテキストしかない状況で、都道府県を抜き出す処理を作ったとき、意外にもちょっとてこずったのでメモしておきます。

    /**
     * 住所から都道府県を切り出す
     * 要素0に都道府県、要素1に市区町村以下の住所を格納した配列を返す
     * @param string $address
     */
    function separateAddressPref(string $address)
    {
        $array = [];
        preg_match('/^(京都府|.*?[都道府県])(.*$)/u', $address, $array);
        $ret = [];
        if (count($array) > 0) {
            $ret[] = $array[1];
            $ret[] = $array[2];
        } else {
            $ret[] = '';
            $ret[] = $address;
        }
        return $ret;
    }

住所がある場合、たいてい郵便番号などもあるので、その場合は郵便番号から都道府県を取ってくる方が楽だと思います。

今回は郵便番号がない状況だったので、住所の文字列から取り出す仕様になりました。

てこずりポイントは、コード見ても明らかなように「京都府」という特殊パターンの存在です。

「都」と「府」が両方含まれているので、京都府だけ一塊の文字列として扱うようにしています。

以上です。

あなたのお役に立てれば幸いです。

Laravelのqueue をcron で動かすときの設定 — レンタルサーバ会社さんにお叱りを受けたので修正した

こんばんは、ウチイダです。

結構前なのですが、しょうもないヤラカシをしたので、自戒を込めて記事にしておきます。

冒頭、まずはお詫びを。エックスサーバーさん、その節は大変失礼いたしました🙇

何があったのか

それは、エックスサーバー上でLaravelのアプリケーションを運用するお仕事でした。

そこそこ本格的なアプリケーションで、外部サービスのAPIへのリクエストなどの重い処理が走るので、ジョブ・キューを使うことにしました。

本来ならドキュメントにもある通り、supervisor などを使ってワーカープロセスをデーモン化したいところです。

しかし、さしものエックスサーバといえども、supervisor は利用できないようでした。

そこで、cron を使ってワーカープロセスを定期的に起動するようにしました。

実際に記述していたcron エントリは以下のような感じです。ディレクトリのパスだけ、ダミーのものに変えています。

* * * * * cd path/to/laravel_project && /opt/php-8.1/bin/php artisan queue:work --max-time=36000 --timeout=36000 --env=production >> /dev/null 2>&1

設定後しばらくしたら、エックスサーバーのサポートからメールで連絡がありました。

要旨としては、契約しているサーバーが高負荷になっており、cron で実行されてるプロセスが原因なので早急に対策せよというものでした。

慌ててエラーログを確認したところ、DBとのコネクションリソースも使い果たしていました…

[2022-07-31 12:40:51] production.ERROR: SQLSTATE[HY000] [1226] User 'my_user' has exceeded the 'max_user_connections' resource (current value: 100) // ...以下略

サポートから指摘があった通り、CPU負荷も高くなっていただろうと思います。

何がいけなかったのか

冷静にcron設定を見直してみたところ、いくつか問題点に気づきました。

  • 重い処理が渡されたときのために –max-time と –timeout を 36000秒(10時間!)というめちゃ大きな値にしている
  • –stop-when-empty オプションをつけていないので、–max-time オプションで指定している秒数、ワーカープロセスが残り続ける
  • cron の起動は最短間隔(1分ごと)にしてあるため、新しいワーカープロセスが頻繁に生成される

つまり、古いプロセスが消えることなく、新しいプロセスを次々に作ってしまう設定だったということです。

ちょっと落ち着いて考えればわかりますね…あほすぎる…

cron エントリの修正

今回の原因は、古いワーカープロセスが終了せず、時間の経過とともに増え続けてしまうことでした。

というわけで、以下のようにcronエントリを修正しました。

*/5 * * * * cd path/to/laravel_project && /opt/php-8.1/bin/php artisan queue:work --max-time=300 --timeout=36000 --env=production >> /dev/null 2>&1

修正したのは以下の点です。

  • cron の実行周期を、1分から5分に変更
  • –max-time=300 に指定して、ワーカープロセスの生存時間を5分に設定
  • –timeout は、日に1回のバッチ処理が数時間かかるものがあるので、36000のままにしておく

5分毎にワーカープロセスがcronによって生成され、次の生成までワーカープロセスが少なくとも1つ存在するようにしました。

処理に5分以上かかるジョブが送られると、一時的に2つ以上のワーカープロセスが存在することになります。

そんなに重い処理が頻繁に発生するアプリケーションではなかったので、問題にはならないはずです。

これでも負荷が上がってしまうようなら、VPSとかクラウド環境に移行することをクライアントに提案するつもりです。

ちなみに、Laravel の日本語ドキュメントにも、queue コマンドの使い方は詳しく書いてあります。RTFM!!

https://readouble.com/laravel/9.x/ja/queues.html#running-the-queue-worker

まとめ

あらためまして、エックスサーバーさん、および同一サーバーを利用していた方、ご迷惑おかけしました。

ドキュメントをちゃんと読むことと、ローカルでの動作テストをきちんと行うことを改めて心に刻みました。

この記事を見ているみなさんはこんなアホなミスはしないと思いますが、ヤラカシ事例としてお知りおきください。

以上、あなたのお役に立てれば幸いです。