在Flask应用中使用Tailwind3,无需手动(重新)生成css



我目前正在尝试使用tailwindcss 3.0.23建立一个flask项目。对于模板,我使用jinja。此外,还使用了yarn。在之前开发前端组件的项目中,我习惯了使用内联HTML类自动采用样式。当我自己完成本教程时,我才意识到我必须重新运行npx tailwindcss -i ./static/src/style.css -o ./static/css/main.css来生成我在style.css中定义的顺风css类的最新版本。由于我现在是一个懒惰的开发人员,我想以一种引入两件事的方式配置项目。

#1自动生成最新的css

这应该允许我添加顺风类,在保存我的.css文件并重新加载我的localhost:3000/index页面后自动应用。

#2内联顺风html类的样式

如前所述,我需要将所有顺风类放入style.css文件中,该文件类似于以下代码片段,以定义一个类todo-text,然后在templates/index.html中使用它。相反,我会更灵活,也能够像这样为我现有的index.html添加顺风类。<p class="text-xl font-mono font-bold">text</p>
@tailwind base;
@tailwind components;
.todo-text {
  @apply text-xl font-mono font-bold;
}
@tailwind utilities;

我已经读过关于顺风的just-in-time engine,但我不太确定如何配置我的项目,以便它使用tailwind 3.0.23工作。我进一步不想使用CDN作为解决方案,我会感谢任何人也会添加一些关于内部工作的解释,为什么我目前的过程如此繁琐,此外,nodejs在整个主题中扮演的角色。最后,我听说过Flask Assets包,但我不确定这是否能解决我的问题。


配置:我的tailwind.config.js看起来像这样:

module.exports = {
  content: ["./templates/*.{html,js,jsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};

更新:作为"为什么节点?node的作用是什么?"我想参考一下这篇文章。但是,我想鼓励您添加更详细的来源,以更好地理解使用nodejs的背景。

我遇到了-watch标志,它在发生更改后自动重新生成最新的.css

所以只要打开一个新的终端并运行npx tailwindcss -i ./static/src/input.css -o ./static/dist/output.css --watch来激活模板文件更改后的自动更新。

希望有帮助!

我最近遇到了同样的问题,决定让编译器自动启动。经过一番研究,我找到了一种方法来插入一个子进程,当flask服务器关闭时,它会自动被删除。

编译器被配置为只在调试模式(flask --debug run)下启动。

代码运行的假设:

  • 顺风安装了npm
  • 你的npm package.jsontailwind.config.js位于flask app folder的父文件夹
  • 你定义命令运行tailwindcss(例如npx tailwindcss -i {src} -o {dst} --minify --watch)在你的package.json文件作为scripts的子。

package.json

{
    "dependencies": {. . .},
    "scripts": {
        "watch": "npx tailwindcss -i ./app/static/src/main.css -o ./app/static/dist/main.min.css --minify --watch"
    }
}

app/utils/compiler.py

import atexit
import json
import os
import shlex
import subprocess
from pathlib import Path
from typing import Optional
import flask
import werkzeug

class TailwindCompiler:
    proc: Optional[subprocess.Popen] = None
    def __init__(
        self,
        app: flask.Flask,
        npm_script_name: str,
        debugmode_only: bool = True,
    ):
        """Start subprocess to compile TailwindCSS on-the-fly on change.
        Prerequisites: flask app is run in debug mode & second instance started
        by `werkzeug` is running (this second instance is needed in debug mode
        to watch for changes). This ensures that the subprocess is only started
        once.
        """
        self.app = app
        debugmode = app.config["DEBUG"]
        is_reloader = werkzeug.serving.is_running_from_reloader()
        if debugmode and is_reloader:
            self.run(npm_script_name)
        elif not debugmode and not debugmode_only:
            self.run(npm_script_name)
        else:
            pass
    def run(self, npm_script_name):
        """Run TailwindCSS Compiler as subprocess.
        Store the current working dir and assume that tailwind, configs,
        etc. are in the apps parent dir. Change the working directory to the
        parent dir. Get the command for running tailwind from the package.json.
        Start the subprocess. Then change back to the original working dir.
        Finally register the subprocess so that it can be shut down on exit.
        Parameters
        ----------
        npm_script_name : str
            The script that should be run must be defined in a `package.json`
            file as a child of the `scripts` key like so:
              "scripts": {
                "watch": "npx tailwindcss -i ./app/static/src/main.css -o ./app/static/dist/main.min.css --minify --watch"
                }
        """
        print("=== Starting TailwindCSS Compiler ===")
        cwd = os.getcwd()
        app_parent_dir = str(Path(self.app.root_path).parent)
        os.chdir(app_parent_dir)
        with open("package.json") as f:
            package = json.load(f)
            try:
                cmd = shlex.split(package["scripts"][npm_script_name])
            except KeyError:
                raise ValueError(
                    f"No script with name '{npm_script_name}' "
                    "found in `package.json`."
                )
        TailwindCompiler.proc = subprocess.Popen(cmd)
        os.chdir(cwd)
        atexit.register(TailwindCompiler.terminate_on_exit)
    @classmethod
    def terminate_on_exit(cls):
        print("=== Closing TailwindCSS Compiler ===")
        TailwindCompiler.proc.terminate()

它现在很容易使用!在创建app对象之后初始化类。

app.py

from app import create_app
from app.utils import TailwindCompiler
app = create_app()
# Run TailwindCSS as subprocess; watch for changes; build css on-the-fly
TailwindCompiler(app, npm_script_name="watch", debugmode_only=True)

编译器的输出显示在普通的flask服务器日志之间。

flask --debug run

 * Serving Flask app 'wsgi.py'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit
 * Restarting with stat
=== Starting TailwindCSS Compiler ===
 * Debugger is active!
 * Debugger PIN: 143-120-061
Rebuilding...
Done in 168ms.
127.0.0.1 - - [05/Dec/2022 11:48:21] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [05/Dec/2022 11:48:21] "GET /static/dist/main.min.css HTTP/1.1" 200 -
. . .
^C=== Closing TailwindCSS Compiler ===

最新更新