将应用程序发布到静态网站
简介
Flet CLI 提供了 flet build web
和 flet publish
命令,允许将 Flet 应用程序发布到独立的静态网站(SPA),该网站完全在浏览器中运行,使用 Pyodide,不需要服务器端代码。
Pyodide 是 CPython 到 WebAssembly(WASM)的端口,这是一项新兴技术,具有某些限制。
本机 Python 包(与“纯”Python 包不同)是部分用 C、Rust 或其他语言编写的包。示例包包括 numpy
、cryptography
、lxml
、pydantic
。
Pyodide 附带了一个庞大的内置包列表。然而,要使用 PyPI 上的 Python 包,必须是纯 Python 包或提供了 Emscripten 编译的 wheel。
异步和线程
发布到静态网站的 Flet 应用程序可以使用同步和异步事件处理程序和方法。
Pyodide 是一个 WebAssembly 应用程序,不支持线程。整个 Flet 都在单个线程中运行,所有同步和异步控制事件处理程序都在同一个线程中运行。如果您的应用程序具有 CPU 密集型逻辑(例如计算 Fibonacci 😄)或“睡眠”以使 UI 更美观,它可能会“挂起”UI。考虑将该逻辑移到服务器并通过 Web API 调用。使用 asyncio.sleep
在异步方法中是 OK 的。
flet build web
将 Flet 应用程序发布到静态网站。
这是发布静态网站的推荐方法。
前提条件
Flutter SDK 必须安装在计算机上,以便 flet build web
命令生效。
构建网站
要将 Flet 应用程序发布到静态网站,请从 Flet 应用程序的根目录运行以下命令:
flet build web
静态网站将被发布到 ./build/web
目录。
测试网站
您可以使用 Python 的内置 http.server
模块测试发布的 Flet 应用程序:
python -m http.server --directory build/web
在浏览器中打开 http://localhost:8000
以检查发布的应用程序。
打包资产
一旦网站被发布,所有来自 assets
目录的文件将被复制到网站的根目录。
这允许覆盖例如 favicon.png
或 manifest.json
等内容。
URL 策略
Flet 应用程序支持两种配置 URL 基于路由的方式:
- path(默认) - 路径被读取和写入没有哈希。例如,
fletapp.dev/path/to/view
。 - hash - 路径被读取和写入到哈希片段中。例如,
fletapp.dev/#/path/to/view
。
如果托管提供商支持单页应用程序(SPA)渲染,您可以留下默认的“path”URL 策略,因为它提供了漂亮的 URL。
然而,如果托管提供商(如 GitHub Pages)不支持 SPA 模式,则需要使用“hash”URL 策略发布应用程序。
使用 --route-url-strategy
选项更改 URL 策略。
Web 渲染器
您可以将默认的“canvaskit”Web 渲染器(更多关于渲染器的信息)更改为“html”:
flet build web --web-renderer html
彩色 Emoji
要减少应用程序的大小,默认的“CanvasKit”渲染器不使用彩色 Emoji,因为彩色 Emoji 字体文件约 8 MB。
您可以使用 --use-color-emoji
标志选择彩色 Emoji:
flet build web --use-color-emoji
或者,切换到“html”渲染器,它使用浏览器字体。
在子目录中托管网站
多个 Flet 应用程序可以在同一个域名下托管,每个应用程序在其自己的子目录中。
要使发布的 Flet 应用程序在子目录中工作,您需要使用 --base-url
选项:
flet build web --base-url <sub-directory>
例如,如果应用程序的 URL 是 https://mywebsite.com/myapp
,则必须使用 --base-url myapp
发布。
flet publish
将 Flet 应用程序发布到静态网站的替代方法。
与 flet build web
命令相比,不需要在计算机上安装 Flutter SDK。
然而,与 flet build web
命令相比,使用 flet publish
命令生成的静态网站加载速度较慢,因为所有 Python 依赖项现在都是在运行时使用 micropip 安装的,而不是预先打包的。flet build web
也检测到 Pyodide 中的本机 Python 包,例如 bcrypt
、html5lib
、numpy
等,并从 Pyodide 包注册表中安装它们。
发布应用程序到静态网站
运行以下命令将 Flet 应用程序发布到独立的静态网站:
flet publish <your-flet-app.py>
静态网站将被发布到 ./dist
目录。
命令可选参数:
--pre
- 允许 micropip 安装预发布 Python 包。-a ASSETS_DIR
,--assets ASSETS_DIR
- 资产目录的路径。--app-title APP_TITLE
- 应用程序标题。--app-description APP_DESCRIPTION
- 应用程序描述。--base-url BASE_URL
- 基础 URL。--web-renderer {canvaskit,html}
- Web 渲染器。--route-url-strategy {path,hash}
- URL 路由策略。
测试网站
您可以使用 Python 的内置 http.server
模块测试发布的 Flet 应用程序:
python -m http.server --directory dist
在浏览器中打开 http://localhost:8000
以检查发布的应用程序。
加载包
您可以在应用程序启动时加载自定义包从 PyPI,方法是将它们列在 requirements.txt
中。requirements.txt
必须在与 <your-flet-app.py>
同一目录下创建。
每行 requirements.txt
都包含一个包名,后跟可选的版本说明符。
要安装自定义包,Pyodide 使用 micropip - 一个轻量级的 pip 版本,适用于浏览器。
您可以直接在 Flet 应用程序中使用 Micropip API:
import sys
if sys.platform == "emscripten": # 检查是否在 Pyodide 环境中运行
import micropip
await micropip.install("regex")
预发布 Python 包
您可以允许加载预发布版本的 PyPI 包,方法是将 --pre
选项添加到 flet publish
命令:
flet publish <your-flet-app.py> --pre
资产
如果您的应用程序需要资产(图像、字体等),您可以使用 --assets <directory>
选项将它们复制到网站目录:
flet publish <your-flet-app.py> --assets assets
如果您在应用程序目录中有 assets
目录,并且不指定 --assets
选项,则 assets
的内容将与 Python 应用程序一起打包,而不是复制到 dist
。
URL 策略
Flet 应用程序支持两种配置 URL 基于路由的方式:
- Path(默认) - 路径被读取和写入没有哈希。例如,
fletapp.dev/path/to/view
。 - Hash - 路径被读取和写入到哈希片段中。例如,
fletapp.dev/#/path/to/view
。
如果托管提供商支持单页应用程序(SPA)渲染,您可以留下默认的“path”URL 策略,因为它提供了漂亮的 URL。
然而,如果托管提供商(如 GitHub Pages)不支持 SPA 模式,则需要使用“hash”URL 策略发布应用程序。
要指定“hash”URL 策略,请使用 --route-url-strategy
选项:
flet publish <your-flet-app.py> --route-url-strategy hash
Web 渲染器
您可以将默认的“canvaskit”Web 渲染器更改为“html”:
flet publish <your-flet-app.py> --web-renderer html
彩色表情符号
为了减少应用程序大小,默认的 "CanvasKit" 渲染器不使用彩色表情符号,因为包含彩色表情符号的字体文件大约有 8 MB。
但是,您可以通过 --use-color-emoji
标志选择使用彩色表情符号:
flet publish <your-flet-app.py> --use-color-emoji
或者,切换到使用浏览器字体的 html
渲染器。
在子目录中托管网站
多个 Flet 应用程序可以托管在一个域上,每个应用程序在自己的子目录中。
要使发布的 Flet 应用程序在子目录中工作,必须使用 --base-url
选项发布它:
flet publish <your-flet-app.py> --base-url <sub-directory>
例如,如果应用程序的 URL 是 https://mywebsite.com/myapp
,则必须使用 --base-url myapp
发布。