打包
恭喜!你已经成功构建了第一个功能齐全的Dioxus应用程序,其中包含路由、异步数据获取、服务器函数和数据库!这真是令人惊叹,仅仅花了短短几分钟时间。
现在让我们将你的应用程序打包为多个平台版本,并准备好进行部署。
桌面和移动设备的测试
到目前为止,我们一直在简单的网页浏览器中测试我们的应用程序。现在让我们实际构建并测试应用程序在移动平台上的运行情况。
在Dioxus 0.6中,dx终于支持在Android和iOS上运行dx serve
在iOS上进行测试
要测试iOS,您的开发环境需要配置为能够构建iOS应用程序。这涉及以下几个步骤:
- 确保您在运行macOS的设备上进行开发
- 安装XCode
- 下载最新的iOS SDK和模拟器包
- 安装 iOS Rust 工具链(
aarch64-apple-ios aarch64-apple-ios-sim)
这是一个多步骤过程,需要创建 Apple 开发者账户。在您希望对应用进行签名之前,无需支付任何费用。对应用进行签名是部署到 Apple App Store 以及在您的 iOS 设备上进行测试的必要条件。
如果所有内容都安装正确,您应该能够打开模拟器应用:
open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app
如果模拟器应用程序打开但未显示任何设备,您可能需要手动选择特定设备。请使用 xcrun 命令行工具来查看已安装的设备列表。
xcrun simctl list
识别可用设备。我们将模拟一部 iPhone 15 Pro Max:
xcrun simctl boot "iPhone 15 Pro Max"
模拟器启动后,我们可以运行 dx serve --platform ios。
太棒了——我们的应用程序可以无缝运行,无需任何修改。
Android 测试
在 Android 开发环境中设置开发环境需要一定时间,因此请务必阅读移动工具指南。
- 安装 Android NDK 和 SDK
- 设置
JAVA_HOME、ANDROID_HOME、NDK_HOME,并解决 PATH 问题以使用模拟器工具 - 安装并配置 Android 模拟器
- 安装 Android rustup 目标(
aarch64-linux-android、armv7-linux-androideabi、i686-linux-android、x86_64-linux-android)
让我们启动一个模拟器。我们可以使用模拟器命令,如果设置正确,该命令应在您的 PATH 中。我们将使用我们的 Pixel_6_API_34 模拟器,但您可以使用任何已配置的设备。
emulator -avd Pixel_6_API_34 -netdelay none -netspeed full
如果我们尝试在 Android 平台上进行构建,会发现应用无法成功构建。这可不好!
12:45:39 [cargo] Could not find directory of OpenSSL installation, and this `-sys` crate cannot
12:45:39 [cargo] proceed without this knowledge. If OpenSSL is installed and this crate had
12:45:39 [cargo] trouble finding it, you can set the `OPENSSL_DIR` environment variable for the
12:45:39 [cargo] compilation process.
12:45:39 [cargo] Make sure you also have the development packages of openssl installed.
12:45:39 [cargo] For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.
12:45:39 [cargo] If you're in a situation where you think the directory *should* be found
12:45:39 [cargo] automatically, please open a bug at https://github.com/sfackler/rust-openssl
12:45:39 [cargo] and include information about your system as well as this message.
12:45:39 [cargo] $HOST = aarch64-apple-darwin
12:45:39 [cargo] $TARGET = aarch64-linux-android
12:45:39 [cargo] openssl-sys = 0.9.104
目前,rust-openssl 无法正确为 Android 目标进行交叉编译。为了解决这个问题,我们需要将 openssl 仓库添加到我们的 Cargo.toml 文件中,然后启用其vendored功能。这将从源代码构建 OpenSSL,而不是尝试从 Android NDK 中读取它并失败。
我们只会在针对 Android 时启用 vendored 功能。
[target.'cfg(target_os = "android")'.dependencies]
openssl = { version = "0.10", features = ["vendored"] }
未来,Dioxus 可能会默认添加 OpenSSL 的 vendored 功能,以消除此错误。我们在此进行说明,因为理解并非所有 Rust 依赖项都能在 iOS 和 Android 上直接使用非常重要。遗憾的是,移动端的 Rust 生态系统仍处于早期阶段,您需要掌握解决此类问题的方法。
让我们再试一次!
dx serve --platform android
桌面端测试
HotDog 同样支持 macOS、Windows 和 Linux 系统!我们可以使用 dx serve --platform desktop 命令将应用程序以桌面应用程序的形式运行。
打包用于网页
在完成对服务器和客户端应用的修改后,我们可以构建可直接分发的打包文件。
我们将遵循与 dx serve 相同的流程,但使用 dx bundle 命令。首先,让我们构建应用的网页版本。
dx bundle --platform web
在构建过程中,我们应从命令行界面(CLI)收到一系列INFO日志,最终会得到它生成的公共文件夹的路径。让我们进入其公共目录,然后查看其父目录('cd ..)(即 web文件夹)。
❯ tree -L 3 --gitignore
.
├── public
│ ├── assets
│ │ ├── favicon.ico
│ │ ├── header.svg
│ │ ├── main-14aa55e73f669f3e.css
│ │ ├── main.css
│ │ └── screenshot.png
│ ├── index.html
│ └── wasm
│ ├── hot_dog.js
│ ├── hot_dog.js.br
│ ├── hot_dog_bg.wasm
│ ├── hot_dog_bg.wasm.br
│ └── snippets
└── server
dx 创建了一个包含我们的资源、index.html 以及各种 JavaScript 片段的公共文件夹。与公共文件夹并列的是一个服务器二进制文件。当我们部署网页资源时,也需要部署服务器,因为它提供了我们的服务器功能。
我们可以手动运行服务器,只需执行它即可。如果你使用的是默认的 dioxus::launch 设置,那么服务器将读取 IP 和 PORT 环境变量来提供服务。
📣 如果你计划在容器(如 Docker)中运行服务器,则需要将默认的 127.0.0.1 地址覆盖为 IP=0.0.0.0,以监听外部连接。
桌面和移动应用的打包
要将桌面和移动应用打包以进行部署,我们将再次使用 dx bundle。截至目前,dx bundle 仅支持为原生平台和架构构建桌面应用。遗憾的是,您无法从 Windows 构建 macOS 应用,也无法从 Mac 构建 Linux 应用等。我们建议使用持续集成矩阵(如 Github Actions)在多个不同容器中对您的应用进行“跨平台构建”。
在打包可安装应用时,有多种分发格式可供选择。我们可以使用 dx bundle 中的 --package-types 标志指定这些格式。Dioxus 支持打包多种包类型:
- macOS: .app, .dmg
- Linux: .appimage, .rpm, .deb
- Windows: .msi, .exe
- iOS: .ipa
- Android: .apk
您可以像这样指定包类型:
dx bundle --platform desktop \
--package-types "macos" \
--package-types "dmg"
请注意,并非所有包类型都与每个平台兼容——例如,仅当指定 --platform desktop 时才能构建 .exe 文件。
我们应在终端中看到输出结果:
18.252s INFO Bundled app successfully!
18.252s INFO App produced 2 outputs:
18.252s INFO app - [/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/macos/HotDog.app]
18.252s INFO dmg - [/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/dmg/HotDog_0.1.0_aarch64.dmg]
通常,您可以无需通过应用商店即可分发桌面应用。然而,某些平台(如 macOS)可能要求您对应用进行签名和公证,以确保用户打开应用时被视为“安全”。
在分发移动应用时,您必须对应用进行签名和公证。目前,Dioxus 尚未提供内置工具支持此功能,因此您需要通过查阅第三方文档自行解决签名问题。
Tauri提供了关于签名过程的文档:
- macO
- iOS
- Android
- Window
- Linux
自定义您的包
在发布应用程序之前,您可能希望配置应用程序图标的外观、其拥有的权限以及其他详细信息。我们的dx包工具可以帮助您以多种方式配置包。
要配置我们的包,我们将使用我们的Dioxus.toml并修改包部分。
[application]
name = "docsite"
[bundle]
identifier = "com.dioxuslabs"
publisher = "DioxusLabs"
icon = ["assets/icon.png"]
要查看所有选项的完整列表,请参阅包部分的参考页面。
使用 JSON 模式自动化 dx 包
在 Dioxus 0.6 中还新增了 dx 的 JSON 输出模式。这使得可以使用支持 JSON 解析的工具(如 jq)来解析 CLI 的输出,这些工具提供了对 JSON 解析的标准输入/标准输出支持。
此模式对人类用户不太友好,但包含的信息比标准跟踪输出更多。
{"timestamp":" 9.927s","level":"INFO","message":"Bundled app successfully!","target":"dx::cli::bundle"}
{"timestamp":" 9.927s","level":"INFO","message":"App produced 2 outputs:","target":"dx::cli::bundle"}
{"timestamp":" 9.927s","level":"DEBUG","message":"Bundling produced bundles: [\n Bundle {\n package_type: MacOsBundle,\n bundle_paths: [\n \"/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/macos/HotDog.app\",\n ],\n },\n Bundle {\n package_type: Dmg,\n bundle_paths: [\n \"/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/dmg/HotDog_0.1.0_aarch64.dmg\",\n ],\n },\n]","target":"dx::cli::bundle"}
{"timestamp":" 9.927s","level":"INFO","message":"app - [/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/macos/HotDog.app]","target":"dx::cli::bundle"}
{"timestamp":" 9.927s","level":"INFO","message":"dmg - [/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/dmg/HotDog_0.1.0_aarch64.dmg]","target":"dx::cli::bundle"}
{"timestamp":" 9.927s","level":"DEBUG","json":"{\"BundleOutput\":{\"bundles\":[\"/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/macos/HotDog.app\",\"/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/dmg/HotDog_0.1.0_aarch64.dmg\"]}}","target":"dx"}
JSON 模式与所有 dx 命令兼容。然而,它在与 dx build 和 dx bundle 命令配合使用时最为有用。命令行界面(CLI)始终确保最后输出的行是命令的结果。要从 dx bundle 命令中收集包列表,我们可以使用 tail -1 和简单的 jq 命令。
dx bundle --platform desktop \
--json-output \
--verbose \
| tail -1 \
| jq -r '.json | fromjson | .BundleOutput.bundles []'
这将返回包的列表:
/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/macos/HotDog.app
/Users/jonkelley/Development/Tinkering/06-demos/hot_dog/target/dx/hot_dog/bundle/macos/bundle/dmg/HotDog_0.1.0_aarch64.dmg