项目打包

179 阅读8分钟

打包

恭喜!你已经成功构建了第一个功能齐全的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

dog-app-ios-dxh8993abe2dd57ca7.gif

太棒了——我们的应用程序可以无缝运行,无需任何修改。

Android 测试

在 Android 开发环境中设置开发环境需要一定时间,因此请务必阅读移动工具指南。

  • 安装 Android NDK 和 SDK
  • 设置 JAVA_HOMEANDROID_HOMENDK_HOME,并解决 PATH 问题以使用模拟器工具
  • 安装并配置 Android 模拟器
  • 安装 Android rustup 目标(aarch64-linux-androidarmv7-linux-androideabii686-linux-androidx86_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

android-dogapp-dxh5dd16b883c89551f.gif

桌面端测试

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