2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Powershell で複数のローカル開発サーバを一気に立ち上げる

Last updated at Posted at 2024-11-09

アプリケーションを開発していて、複数の環境から成り立っているアプリケーションのローカル開発サーバをいちいち手動で立ち上げるのは面倒ですよね。

そこで 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 を使うと複数のプロセスを作れる
  • 各 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 を補完してくれないようです。
  • Start-Process を使うことで引数に指定したプログラムをプロセスとして実行できます。

    • Start-Process powershell で PowerShell を別ウィンドウで開きます
    • 書式は Start-Process [-FilePath] <string> [[-ArgumentList] <string[]>] ... です。プロセスに引数を渡す場合は明示的に書くと -ArgumentList <string[]> ですが-ArgumentListは省略可能です。
    • alias は start です。
    • 余談ですが Start "<URL>" とすることでデフォルトブラウザでリンクを開けます。

image.png

無事に開くことが出来ました。

追記(2024-11-14)

どうやら Next.js を立ち上げた際に、いつまでも Ready から進まないことがあるようです。その時は Ctrl+c を押してみてください。

再現するときとしないときがありました。理由は残念ながら不明です。

終わりに

自分の力量不足のせいか、Powershell って明確でない挙動をすることが多いように感じます(上記の-command とか)。
ですが確実に我々の Windows 生活を便利にしてくれるものです!ぜひ皆さんもつかいましょう!!!

参考文献

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?