アプリケーションを開発していて、複数の環境から成り立っているアプリケーションのローカル開発サーバをいちいち手動で立ち上げるのは面倒ですよね。
そこで PowerShell を使って複数のローカルサーバを一気に立ち上げたいと思います。
バージョンは以下です
> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.5007
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.5007
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
内容
今回は以下のWebアプリケーションの開発を例にします。
(実際にはあんまりないと思うのですが、例なので許して...)
- Next.js でフロントエンドを構築している
- Python/Flask で2つバックエンドを構築している
- Virtualenv を使って個別の仮想環境を作っている
# ディレクトリ構成
- my-project/ # 全体 プロジェクトルート
|
+- dev-setup.ps1 # 今回作成する ps1
|
+- next-project/ # next.js プロジェクトルート
+- flask-1/ # flask (1) プロジェクトルート
+- flask-2/ # flask (2) プロジェクトルート
+- env-flask-1/ # flask (1) の 仮想環境
+- env-flask-2/ # flask (2) の 仮想環境
もちろんcliで動くものであればこれ以外の例にも応用できるので参考にしてください。
方針
以下のような方針でいきます。
- 複数の window で powershell を立ち上げる
- PowerShell の
Start-Process
cmdlet を使うと複数のプロセスを作れる
- PowerShell の
- 各 window で開発サーバを立ち上げる
-
powershell
コマンドに文字列としてサーバを立ち上げるコマンドを渡す
-
=> Start-Process powershell "サーバを立ち上げる文字列"
でサーバを一気に立ち上げよう!
PowerShell を使わないと...?
普通に立ち上げようとすると以下のようになると思います
# next.js
> cd my-project/next-project; pnpm run dev;
# flask (1)
> cd my-project; ./env-flask-1/Scripts/activate; cd flask-1; python ./app.py
# flask (2)
> cd my-project; ./env-flask-2/Scripts/activate; cd flask-2; python ./app.py
今回はこれが
> cd my-project; ./dev-setup.ps1
これだけで動くようにします!
コードと解説
コード
さて先にコードです。
# dev-setup.ps1
$rootDir = $PSScriptRoot; # dev-setup.ps1 が置かれているディレクトリの絶対パスを取得
function createCmdStr { # それぞれの powershell に渡すコマンドを返す関数を作ります。
param ( # 引数としてそれぞれのプロジェクトの名前(=envのsuffix) を取ります
[validateSet("next-project","flask-1", "flask-2")]$project
)
$cmdstr = "-noexit " # `-noexit` を付けることで即終了しなくなります。今回の例では不要ですが、サーバ以外なら必要になることがあります。
$cmdstr = "$cmdstr cd $rootDir" # 全体のルートディレクトリへ
# next なら
if($project -eq "next-project"){
$cmdstr = "${cmdstr}; cd ${project}; pnpm run dev" # pnpm で立ち上げ(これはお好きなように)
return $cmdstr
}
# flask なら
$cmdstr = "${cmdstr}; ${rootDir}\env-${project}\Scripts\activate.ps1; cd $project; python ./app.py;" # お好きなように
# 余談だが、terminal でやるときは `activate` でもOKだが、スクリプト内だと `activate.ps1` でなくてはならない
return $cmdstr
}
# Statrt-Process で powershell を立ち上げ => 別 window に
# flask1
$cmdstr = createCmdStr("flask-1")
start-process powershell "${cmdstr}"
# flask2
$cmdstr = createCmdStr("flask-2");
Start-Process powershell "${cmdstr}"
# next
$cmdstr = createCmdStr("next-project")
Start-Process powershell "${cmdstr}"
解説
上から順に
-
$PSScriptRoot
でそのスクリプトファイルが置かれている絶対パスを取得 できます。- 今回
dev-setup.ps1
を全体ルートの直下に置くことで全体ルートの絶対パスを取得しています。
- 今回
-
処理を共通化するために実行文字列を作る関数を作りました
-
powershell の関数では引数を取るのに
param()
を使うことが出来ますが、ここで[ValidateSeet("a","b","c")]$val
とすることで引数を限定できます。ですが今回は全く関係ありません。(自己満足。ただし見やすくはなる) -
powershell.exe
は-noexit
を付けることで即終了しなくなります。前述のとおり(サーバがlistenし続けて終了しないので)今回の例では不要ですが、サーバ以外なら必要になることがあります。-
-noexit
は渡すコマンドの前に置く必要があります。 - PowerShell 上で powershell を実行してもわかりにくいですが、
-noexit
を付けないと確かに即元のシェルに戻ってしまいます。例えばpowershell cd c:/
などとするとわかると思います。> (pwd).path C:\Users\XXX > powershell cd C:/ # noexit つけないと > (pwd).path # すぐ戻ってしまう。 C:\Users\XXX > powershell -noexit cd C:/ # noexit つけると > (pwd).path # とどまる! C:\
-
-
実はここでは書いていませんが、本来
powershell.exe
に実行コマンドを渡すには-command
パラメタの引数として文字列やスクリプトブロックで渡す必要があります。しかしなぜか書かなくても動きます。この挙動は公式ドキュメントにはないので謎です。よくわかりません。Start-Process
経由でなくても同様です。 -
先ほど取得した
dev-setup.ps1
のディレクトリに cd した後各プロジェクトのディレクトリに cd しましょう。もしくは virtualenv を activate しましょう。- 書いた通り virtualenv の activate は
Scripts/activate.ps1
にする必要があります。Start-Process
経由だと ps1 を補完してくれないようです。
- 書いた通り virtualenv の activate は
-
Start-Process
を使うことで引数に指定したプログラムをプロセスとして実行できます。-
Start-Process powershell
で PowerShell を別ウィンドウで開きます。 - 書式は
Start-Process [-FilePath] <string> [[-ArgumentList] <string[]>] ...
です。プロセスに引数を渡す場合は明示的に書くと-ArgumentList <string[]>
ですが-ArgumentList
は省略可能です。 - alias は
start
です。 - 余談ですが
Start "<URL>"
とすることでデフォルトブラウザでリンクを開けます。
-
無事に開くことが出来ました。
追記(2024-11-14)
どうやら Next.js を立ち上げた際に、いつまでも Ready
から進まないことがあるようです。その時は Ctrl+c
を押してみてください。
再現するときとしないときがありました。理由は残念ながら不明です。
終わりに
自分の力量不足のせいか、Powershell って明確でない挙動をすることが多いように感じます(上記の-command
とか)。
ですが確実に我々の Windows 生活を便利にしてくれるものです!ぜひ皆さんもつかいましょう!!!
参考文献
-
"【Start-Process】PowerShellで別プロセスを起動させる方法 | チェシャわら". https://cheshire-wara.com/powershell/ps-cmdlets/system-service/start-process/. (Cited on: 2024-11-10).
-
"スクリプトフォルダーの取得 | MURA". https://www.vwnet.jp/windows/PowerShell/pwd.htm
-
"about_PowerShell_exe - PowerShell | Microsoft Learn". https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_powershell_exe?view=powershell-5.1. (Cited on: 2024-11-10).
-
"Start-Process (Microsoft.PowerShell.Management) - PowerShell | Microsoft Learn". https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.management/start-process?view=powershell-7.4. (Cited on: 2024-11-10).