👏

Dev ContainerでFlask+Tailwind CSSの開発環境を構築する

2023/09/14に公開

はじめに

こんにちは、D2Cデータサイエンティストの吉岡です。

最近、webアプリケーションのプロトタイプを作成することがありました。
データサイエンティストが管理する可能性があるため、言語はPythonを指定されておりそれ以上のフレームワークに対する指定はありませんでした。そこで利用経験があるFlaskと興味のあったTailwind CSSを利用することにしたのですが、Flask+Tailwind CSSでの日本語記事があまりなかったため、備忘録を兼ねて記事にしようと思います。

なお、本記事はあくまで環境構築をメインに解説し、各フレームワークの使い方を深く説明することはありません。

Dev Container, Flask, Tailwind CSSについて

Dev Containerとは?

Dev ContainerとはVSCodeの拡張機能の一つで、Dockerコンテナの中に開発環境を用意することで必要なライブラリなどを閉じ込め、コンテナ内で完結させることができる機能です。

Dev Containerを利用すると以下のようなメリットがあります。

  • 開発者による開発環境の差異がなくなる
  • ローカルマシンの環境に影響を与えず開発環境を構築できる
  • 新しい開発者が参入した際に、開発環境をすぐに用意できる

Flaskとは?

FlaskはPythonフレームワークの一つです。
他のPythonフレームワークと比較すると、必要最小限の機能のみでまとまっており、そのため学習コストが小さいというメリットが存在します。

Tailwind CSSとは?

Tailwind CSSはCSSフレームワークのひとつです。
公式で「utility-first」なCSSフレームワークを謳っており、自分でCSSを書くことなくデザインを完成させることができます。

Tailwind CSSでは、すべてのデザインをクラスで指定します。
例えば背景色を赤色、文字色を白色にしたい場合は以下のようになります。

<p class="bg-red-500 text-white">Hello World</p>

メリットとしては、

  • CSSファイルを編集することがなくなる
  • クラス名を考える手間を省ける
  • 管理しなくてはならないファイル数が減る

といったことがあげられます。

構築手順

前提条件

  • VSCodeがインストールされている
  • VSCodeにRemote DevelopmentのExtentionがインストールされている
  • dockerコンテナが実行できる環境が整っている

完成系のディレクトリ構造

tailwind_on_flask
├── .devcontainer
│   ├── devcontainer.json
│   └── postCreateCommand.sh
├── app.py
├── node_modules
│   └── (多いの省略)
├── package-lock.json
├── package.json
├── requirements.txt
├── static
│   ├── css
│   │   └── main.css
│   └── src
│       └── input.css
├── tailwind.config.js
└── templates

手順

0.プロジェクトフォルダの作成

まずはプロジェクトファイルを作ります。
名前はなんでも良いですが、今回はtailwind_on_flaskとしました。
このディレクトリをVSCodeにて開いておきましょう。

1.Dev Containerの設定

次にDev Containerの設定を行います。
以下のようにファイルを設置し、内容を記述してください。

tailwind_on_flask
├── .devcontainer
│   ├── devcontainer.json
│   └── postCreateCommand.sh
├── package.json
└── requirements.txt
devcontainer.json
{
	"name": "Python 3",
	"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
	"features": {
		"ghcr.io/devcontainers/features/node:1": {}
	},
	"postCreateCommand": "/bin/sh .devcontainer/postCreateCommand.sh",
	"customizations": {
		"vscode": {
			"extensions": [
				"bradlc.vscode-tailwindcss"
			]
		}
	}
}
postCreateCommand.sh
pip install --user -r requirements.txt
npm install
npx tailwindcss init
package.json
{
    "devDependencies": {
      "tailwindcss": "^3.3.3"
    }
}
requirements.txt
flask==2.3.3

ファイルの設置が終わったら、VSCodeのコマンドパレットからDev Containers: Rebuild Containerを選択してDev Containerを起動します。

コンテナ内にはすでにFlaskとTailwind CSSがインストールされた状態になっており、以下のようなディレクトリ構成となっているはずです。

tailwind_on_flask
├── .devcontainer
│   ├── devcontainer.json
│   └── postCreateCommand.sh
├── node_modules
│   └── (多いの省略)
├── package-lock.json
├── package.json
├── requirements.txt
└── tailwind.config.js

2.Flask用のディレクトリの配置

Falskで利用するディレクトリを配置しておきます。

tailwind_on_flask
├── static
│   ├── css
│   └── src
└── templates

それぞれのディレクトリの役割を簡単に説明すると以下のようになります。

static

  • 静的ファイル(css, (フロントの)js, 画像など)の格納場所

static/css

  • Tailwind CSSの出力先ディレクトリ

static/src

  • Tailwind CSSの設定ファイルの格納先

templates

  • HTMLファイルの格納場所

3.Tailwind CSSの初期設定

まず、Tailwind CSSの読み込み範囲を指定します。tailwind.config.jsを以下のように編集してください。

tailwind.config.js
 /** @type {import('tailwindcss').Config} */
 module.exports = {
-  content: [],
+  content: [
+    "./templates/**/*.{html,htm}",
+    "./static/**/*.js",
+    "./**/*.py"
+  ],
   theme: {
     extend: {},
   },
   plugins: [],
 }

次に、static/src/input.cssを作成して以下の内容を入力します。

static/src/input.css
@tailwind base;
@tailwind components;
@tailwind utilities;

これにて環境構築は完了です!

4.CSSファイルのビルド

htmlファイルから読み込むためのcssファイルをビルドするにはターミナルにてプロジェクトファイル直下で以下のコマンドを実行します。

npx tailwindcss -i ./static/src/input.css -o ./static/css/main.css

これでstatic/css/main.cssが出力されます。
htmlからは以下のようにしてこのファイルだけを読み込めばデザインが適用されます。

hoge.html
<link rel="stylesheet" href="static/css/main.css" type="text/css">

ビルドコマンドは他のファイルを編集するたびに実行する必要があります。
代わりに以下のコマンドを利用することで、実行中は他のファイルが編集されるたびにmain.cssが更新されます。

npx tailwindcss -i ./static/src/input.css -o ./static/css/main.css --watch

5.webサーバーの起動

プロジェクトファイル直下にapp.pyを作成し、そこに以下のように入力してください。

app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    return "Hello World!"
    
if __name__ == "__main__":
    app.run(debug=True)

その後ターミナルから以下のコマンドを実行すると5000番ポートにサーバーが立ち上がります。

python ./app.py

さらに、VSCodeが勝手に5000番ポートに対してトンネリングしてくれるので、ローカルのブラウザからhttp://localhost:5000にアクセスするとサーバーに接続できます。

VSCodeではターミナルを複数同時に立ち上げて置けるので、Tailwind CSSのwatch用とFlaskのサーバーホスト用で二つのターミナルを立ち上げ続けておくと便利です。

以上で環境構築は終わりです!
これ以降は、プロジェクトフォルダをVSCodeで開き、Dev Containerを起動するだけで同じ環境に入ることができます。

実際に使ってみる

まずはhello worldを表示してみましょう。
app.pyを以下のように編集します。

app.py
from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    html="""<link rel="stylesheet" href="static/css/main.css" type="text/css">
    <p class="bg-red-100">Hello World</p> """
    return html

if __name__=="__main__":
    app.run(debug=True)

やっていることは、Tailwind CSSのビルドされたcssファイルの読み込みと、Hello Worldの背景色を薄赤色にするクラスを付与しているだけです。

次にターミナルで次のコマンドを実行します。

npx tailwindcss -i ./static/src/input.css -o ./static/css/main.css
python ./app.py

その後、ローカルのブラウザからhttp://localhost:5000にアクセスします。

きちんとTailwind CSSのデザインも適用されていますね。

次はhtmlファイルを表示してみましょう。
templates/index.htmlというファイルを作成して以下のように記述します。

templates/index.html
<!DOCTYPE html>
<html lang="jp">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>D2C m-tech</title>
</head>

<link rel="stylesheet" href="static/css/main.css" type="text/css">
<body>
    <div class="flex justify-center">
        <div class="max-w-sm rounded overflow-hidden shadow-lg">
            <div class="px-6 py-4">
                <div class="font-bold text-xl mb-2">Tailwind On CSS</div>
                <p class="text-gray-700 text-base">
                    こんにちは、D2Cデータサイエンティストの吉岡です。<br>
                    最近、webアプリケーションのプロトタイプを作成することがありました。<br>
                    利用するフレームワーク等は任されていたため、利用経験があるFlaskと興味のあったTailwind CSSを利用することにしたのですが、
		    Flask+Tailwind CSSでの日本語記事があまりなかったため、備忘録を兼ねて記事にしようと思います。<br>
                </p>
            </div>
            <div class="px-6 pt-4 pb-2">
                <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#flask</span>
                <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#tailwind</span>
                <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2">#devcontainer</span>
            </div>
        </div>
    </div>
</body>
</html>

Hello Worldの時と同様にビルドしてブラウザから覗いてみましょう。

他にも、javascriptへの記載やFlask搭載のJinja2テンプレートを利用した書き方でも問題なくTailwind CSSを利用できます。

まとめ

今回はDev Containerを用いたFlask+Tailwind CSSの環境構築について説明しました。
データサイエンティストにとって身近なPythonでwebサーバーをホストできるFlaskと、cssを記載せずともリッチなデザインを実現できるTailwind CSSの組み合わせはプロトタイプ環境としてかなり適していると感じています。
皆さんも、サクッとwebアプリを立てたい場合はこの組み合わせをためしてみてはいかがでしょうか?

最後までお読みいただき、ありがとうございました。

参考

https://code.visualstudio.com/docs/devcontainers/containers
https://msiz07-flask-docs-ja.readthedocs.io/ja/latest/
https://tailwindcss.com/
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack
https://v1.tailwindcss.com/components/cards

D2C m-tech

Discussion