【2025年】素直にwindowsのpoetry環境を構築する

はじめに

PCを新しく購入したので、いろいろと環境構築をし直しているのだが、 Pythonは様々な環境選択肢があり、悩ましい。

普段私はpoetryを使っているので、今回はpoetry環境を構築することを前提としたうえで、 今回は公式ドキュメント見ながら素直にwindowsのpoetry環境構築をしていこうと思う。

前のPCではpyenvでpythonのバージョンも管理できるようにしていた気がするが、 私は特にライブラリ開発とかはしていないライトユーザーなので、ほとんどバージョンを切り替えることはなかった。 そのため、poetryで検索かけると必ずと言っていいほどpyenvと併用している記事が出てくるが、 特にpoetry公式ドキュメントにpyenvを勧められなかったら今回はpyenvなしで環境構築しようと思う。

結論

結論から言うと、今回以下の手順でpoetry環境を構築した。

  1. 公式サイトからpythonインストール
  2. pipでpipxインストール
  3. pipxでpoetryインストール

経緯

まず、poetryの公式ドキュメントを見てみる。

python-poetry.org

poetry-install

poetryをインストールする方法としてpipxが最初のタブになっていたため、 素直にpipxでインストールすることにした。

続いて、pipxの公式ドキュメントを見てみる。

pipx.pypa.io

pipx-install

pipxをインストールする方法として、scoopとpipの2つのが載っているが、 pythonに標準で付随しているpipでインストールすることにした。 また、ドキュメントにある通り、ここでpipxにpathを通してあげるらしい。

そして、ここまでで特にpyenvを勧める記述は出てこなかったため、python自体は素直に公式サイトpythonを落とすことにした。

手順

基本的には前章を逆に辿るのみ。

公式サイトからpythonインストーラをダウンロードして、インストールする。

現時点での最新バージョンである3.13をインストールしたうえで、 直近で3.12が必要な用があるため3.12もインストールした。(使いたいライブラリが3.13にまだ対応していない)

1つのバージョンしか使わない場合はややこしくなるのでそのバージョンだけインストールしましょう。 また、冒頭にもあるように、頻繁に切り替えたりする場合はpyenvとかを使った方が良いと思うのでケースバイケースで。

www.python.org

次にpipでpipxをインストールする。

py -3.13 -m pip install --user pipx

pipxにpathを通す。 warningメッセージで記載があったフォルダに移動してensurepathを実行。

cd ~\AppData\Roaming\Python\Python313\Scripts
.\pipx.exe ensurepath

次にpipxでpoetryをインストールする。

pipx install poetry

以上で環境構築完了。

ただ、私は、仮想環境はプロジェクトフォルダ内に作成されてほしい派なので以下の設定をする。

poetry config virtualenvs.in-project true

複数バージョンが入っている場合は、以下のようにpyproject.tomlのrequires-pythonを満たすバージョンを勝手に選んでくれるはず。 (おそらくpathが先頭のものから順に満たすか見てるため、「要件満たす最新のバージョン使いたい」のであればpathの順番は新しい順に並べといた方が良さそう)

> poetry install
The currently activated Python version 3.12.10 is not supported by the project (>=3.13).
Trying to find and use a compatible version. 
Using python.exe (3.13.7)
Creating virtualenv poetry-demo2 in C:\Users\xxx\workspace\poetry-demo2\.venv
Updating dependencies
Resolving dependencies... (0.1s)

Writing lock file

Installing the current project: poetry-demo2 (0.1.0)

さいごに

今回はできるだけ素直にpoetryの環境構築を行なった。 poetryで調べるとpyenvと併用している記事ばかり出てくるが、 今のところpyenvなしでも特に支障なさそう。 今後開発を進めるうえで何か問題があれば追記しようと思う。

【Everyday Next.js】8. daisyUI

daisyUI

今回は、Next.js の公式ドキュメントを離れて、daisyui を導入する。

daisyui.com

daisyUI とは

daisyUI は、Tailwind CSS をベースにしたコンポーネントライブラリである。

GitHub の tailwind タグでスター数が3番目に多いライブラリになっている。

1番目は、Tailwind CSS 本家。

2番目は、UI コンポーネントライブラリである Radix UI と、Tailwind CSS をベースとした「shadcn-ui」。

つまり、純粋な Tailwind CSSコンポーネントライブラリの中では現状最も有名ということになる。

導入方法

  1. daisyUI をインストール
npm i -D daisyui
  1. tailwind.config.ts に追加
// tailwind.config.ts
module.exports = {
  //...
  plugins: [require('daisyui')],
};

以上。

使い方

例えば、ただの Tailwind CSS で一般的なボタンを実装しようとすると、以下のようにとても長い class を書く必要がある。

(色つけてパディングつけてテキストのサイズ指定してホバー時色が濃くなるようにして…)

<button
  className="inline-block cursor-pointer rounded-md bg-gray-800 px-4 py-3 text-center text-sm font-semibold text-white transition duration-200 ease-in-out hover:bg-gray-900"
>
  Button
</button>

これが daisyUI を使用すると以下の通り。

<button class="btn btn-neutral">Button</button>

daisyUI のコンポーネントをベースに、Tailwind CSS ユーティリティクラスで一部変更も可能

<button class="btn w-64 rounded-full">Button</button>

基本的には、daisyUI のコンポーネントページで使いたいコンポーネントを探してコピペすれば OK。

daisyui.com

Button や Card や Checkbox や Drawer など、よく使う UI は大体揃っている。

おわりに

今回は、Next.js に daisyUI を導入した。 次回は、ダイナミックルーティングなど。

【Everyday Next.js】7. Linking and Navigating

Linking and Navigating

画面遷移の方法

nextjs.org

Next.js には、<a>タグを拡張した組み込みコンポーネント<Link>がある。

基本的には<a>タグと同じように使ってあげれば良い。

import Link from 'next/link';

export default function Page() {
  return <Link href='/dashboard'>Dashboard</Link>;
}
useRouter()

また、useRouter()フックを使って、ルートを変更することもできる。こちらはクライアントコンポーネントでしか使えない。基本的には<Link>コンポーネントの使用を推奨。

'use client';

import {useRouter} from 'next/navigation';

export default function Page() {
  const router = useRouter();

  return (
    <button type='button' onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  );
}

<Link>useRouter()を使うメリット

nextjs.org

<Link>などを使うことで、プリフェッチやキャッシュや部分レンダリングあたりをよしなにしてくれるらしい。

まだ experimental の機能ではあるが、ルーティングに対して型をつけてくれるStatically Typed Linksという機能がある。

next.config.jsに設定を追加することで有効になる。

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    typedRoutes: true,
  },
};

module.exports = nextConfig;

例えば、/ と/parent と/parent/child ページが存在するとき、Link の href に["/", "/parent", "/parent/child"]以外のパスを与えようとすると、エラーが出る。

なんなら入力補完が効く。

experimental ではあるが、便利な機能なのでぜひ使っていきたい。

おわりに

今回は、Next.js の画面遷移について見ていった。

次回は、ダイナミックルーティングなど。

【Everyday Next.js】6. Routing Detail

Routing

ページごとに page.tsx が必要

例えば、以下のようなディレクトリ構造だと、

app
├ layout.tsx
└ page.tsx
  ├ about
  │ └ page.tsx
  └ user
    ├ page.tsx
    └ post
      └ page.tsx
  • app/page.tsx -> /
  • app/about/page.tsx -> /about
  • app/user/page.tsx -> /user
  • app/user/post/page.tsx -> /user/post

となる。

Pages Router のように、

のようなファイルを作っても対象にならないので注意。

Root Layout は必須

app ディレクトリ直下のlayout.tsxは必須。

そして、以下のファイルのように、<html>タグと<body>タグを含む必要がある。

// app/layout.tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}

この Root Layout は、Pages Router の\app.tsx\document.tsx にあたるもののようだ。

Rayout と Template

Rayout も Template も、どちらもページをラップするものである。

2つの違いは、「画面遷移したときに再レンダリングが行われるかどうか」。

Rayout は再レンダリングが行われず、Template は再レンダリングが行われる。

使い分け基準は以下の技術記事がわかりやすい。

zenn.dev

<head>の編集

タイトルやメタデータなどの<head>要素は、layout.tsx や page.tsx で metadata オブジェクトや generateMetadata 関数をエクスポートすることで定義できる。

// app/page.tsx
import {Metadata} from 'next';

export const metadata: Metadata = {
  title: 'Next.js',
};

export default function Page() {
  return '...';
}

逆に、自分で Root Layout に<head>タグを追加すべきではない。上記のような Metadata API を使うようにすること。

おわりに

今日は、App Router での Routing についてもう少し詳細な仕様を見た。 明日は、Linking や Navigating を見ていく。

【Everyday Next.js】5. Routing Fundamentals

nextjs.org

Next.js Routing の基本

Next.js 13 から App Router が導入された。

前までの Pages Router と大きく仕様が変わっているため、ググって出てくる情報にはバージョンの差異がないか注意が必要。

といっても基本原理は変わらない。

Next.js の Routing は、ファイルシステムベースルーティングになっている。

以下の図のように、原則、app フォルダ下のフォルダ構成によって、URL パスが決定する。

https://nextjs.org/_next/image?url=%2Fdocs%2Flight%2Froute-segments-to-path-segments.png&w=1920&q=75&dpl=dpl_3KvQ7chUpCwD5geTFxau9SMj51uW

そして、そのフォルダの中に特定のファイル名を持つファイル群を設置することでそのページの中身を決定する。

ファイル名 説明
layout セグメントとその子の共有 UI
page ルートのユニークな UI とルートの一般公開
loading セグメントとその子の UI をロードする
not-found セグメントとその子の UI が見つからない
error セグメントとその子のためのエラー UI
global-error グローバルエラー UI
route サーバーサイド API エンドポイント
template 特殊化された再レンダリングされたレイアウト UI
default 並列ルートのフォールバック UI

この特定の役割を持ったファイル群は、以下のような階層でレンダリングされる。ネストされた Route の場合は、入れ子レンダリングされる。

https://nextjs.org/_next/image?url=%2Fdocs%2Flight%2Ffile-conventions-component-hierarchy.png&w=1920&q=75&dpl=dpl_3KvQ7chUpCwD5geTFxau9SMj51uW

https://nextjs.org/_next/image?url=%2Fdocs%2Flight%2Fnested-file-conventions-component-hierarchy.png&w=1920&q=75&dpl=dpl_3KvQ7chUpCwD5geTFxau9SMj51uW

試してみる

parent フォルダ、child フォルダに layout.tsx、page.tsx を作って、どのようにレンダリングされるかを実際に試してみる。

// app/parent/layout.tsx
export default function ParentLayout({children}: {children: React.ReactNode}) {
  return (
    <div>
      親レイアウトbegin
      {children}
      親レイアウトend
    </div>
  );
}
// app/parent/page.tsx
export default function Parent() {
  return <div>これは親ページです。</div>;
}
// app/parent/child/layout.tsx
export default function ChildLayout({children}: {children: React.ReactNode}) {
  return (
    <div>
      子レイアウトbegin
      {children}
      子レイアウトend
    </div>
  );
}
// app/parent/child/page.tsx
export default function Child() {
  return <div>これは子ページです。</div>;
}

レイアウトの中にページ、そしてネストされている場合は入れ子のようにレンダリングされていることがわかる。

おわりに

今回は、Next.js App Router の基本原理を理解した。 次回は、App Router の扱い方をもう少し詳しく見ていく。

【Everyday Next.js】4. 脇道 (ANSI Escape Sequences)

前回の記事で、eslint エラーメッセージが文字化け?してると書いたが、

[33m[STARTED][39m Preparing lint-staged...

この、[33mの部分は、調べてみるとどうやらANSI Escape Sequencesらしい。

en.wikipedia.org

qiita.com

これをANSI Escape Sequencesをサポートしているターミナルなどでは、その範囲の文字色を変えられたりするらしいが、今回のダイアログではそのカラーコードがそのまま表示されてしまっているだけだったようだ。

【Everyday Next.js】3. husky / lint-staged

lint 自動実行の必要性

前回も説明した通り、nextjs で build するときは自動で lint も走るようである。

例えば以下のコード。

'use client';

import React, {useState} from 'react';

export default function Home() {
  const isTrue = Math.random() > 0.5;

  if (isTrue) {
    const [count, setCount] = useState(0);
  }

  return <div>Hello, world!</div>;
}

build 自体はできるはずなのだが、React フックを条件付きで呼び出すと ESLint エラーを起こす。

そのため、build しようとすると以下のように lint エラーで build も失敗する。

ということは、少なくとも push をするときに eslint エラーが起きてしまうようなコードだとまずい。

では、「push や commit をする前に毎回npm run lintを実行するようにしましょうね!」とすれば良いかというと、やはり人間なので忘れてしまうこともあるし、面倒である。

したがって、push や commit をする前に「自動で」npm run lintが実行されるようにしたいわけである。

husky / lint-staged

ここで、husky と lint-staged の登場。

husky と lint-staged を使えば、「コミット前にステージされているファイルに lint を自動で走らせる」ことができる。

nextjs.org

github.com

github.com

それぞれの公式ドキュメント通りに設定を進める。

パッケージインストール

npm i -D husky lint-staged

lint-staged 設定ファイル

公式ドキュメントに載っている通り、Next.js で lint-staged を動かしたい場合は以下の lint-staged 設定ファイルが必要。

// .lintstagedrc.js
const path = require('path')

const buildEslintCommand = (filenames) =>
  `next lint --fix --file ${filenames.map((f) => path.relative(process.cwd(), f)).join(' --file ')}`

module.exports = {
  '*.{js,jsx,ts,tsx}': [buildEslintCommand],
}

husky install

npm pkg set scripts.prepare="husky install"
npm run prepare

husky をセットアップするために、husky installの実行が必要である。

複数人で開発したりしないのであれば、単純husky installを実行するだけでも良いのだが、上記は npm scripts に"prepare": "husky install"を追加した上で、npm run prepareを実行してhusky installを走らせている。

npm run prepareは少々特殊なスクリプトで、npm installが実行されたときなどに自動実行される。

つまり、あなた以外がリポジトリを clone して開発するとなったときに、わざわざhusky installを実行してもらわなくても、勝手に実行してくれるのだ。

hook を追加

npx husky add .husky/pre-commit "npx lint-staged"

「コミット前にnpx lint-stagedを husky で自動実行するための設定を追加しなさい」というコマンド。

動作確認

本当に動作するか、わざと eslint エラーが起きるコードをコミットしようとしてみる。 コミットは VSCodeGUI で行ってみた。

狙い通り、コミットに失敗した。(なぜか文字化けしているが…)

おわりに

今回は、コミット前 lint 自動実行のために、husky と lint-staged を導入した。

次回は文字化け解消?