ci build status ci build status

archer

一个用于打包 Swift WebAssembly 产品的极简工具。从 Carton Fork 而来。

与原始的 Carton 不同,Archer 的核心思想是只做那些其他工具无法更好处理的事情。Archer 强调透明度、用户友好性以及易于集成到现有项目中。

  1. WebAssembly 入门
  2. archer init
  3. archer crush

要求

Archer 支持 Linux 和 macOS。我们为多个平台提供预构建的二进制文件。

平台 架构 下载
macOS 15 arm64 tar.gz
Ubuntu 24.04 arm64 tar.gz
Ubuntu 24.04 x86_64 tar.gz
Ubuntu 22.04 arm64 tar.gz
Ubuntu 22.04 x86_64 tar.gz

从上表中为您的平台下载正确的二进制文件,解压它,并将 archer 二进制文件添加到您的 PATH 中。预构建的 Linux 二进制文件不需要在系统上安装 Swift 运行时。

ESBuild 和 Binaryen

我们建议在您的系统上安装 esbuildbinaryen 工具。

# Linux
sudo apt install esbuild binaryen
# macOS
brew install esbuild binaryen

ESBuild 是一个流行的 TypeScript/JavaScript 编译器,必须安装才能构建 WebAssembly 项目的前端。

Binaryen 是一个 WebAssembly 优化器,它是可选的,但建议与 Archer 一起使用,因为它可以显着减小最终 WebAssembly 二进制文件的大小。

WebAssembly 入门

这些步骤并非 Archer 特有,本节是关于从 Swift 编译 WebAssembly 的通用指南。

安装 Swift WebAssembly SDK

如果您尚未安装,请安装 Swift WebAssembly SDK

swift sdk install \
    https://github.com/swiftwasm/swift/releases/download/swift-wasm-6.0.2-RELEASE/swift-wasm-6.0.2-RELEASE-wasm32-unknown-wasi.artifactbundle.zip \
    --checksum 6ffedb055cb9956395d9f435d03d53ebe9f6a8d45106b979d1b7f53358e1dcb4

重要提示:在 macOS 上,您必须使用 swift.org 提供的可下载工具链之一默认的 Xcode 工具链不支持 WebAssembly。 您可以(临时)通过运行 export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw /Library/Developer/Toolchains/$TOOLCHAIN_NAME.xctoolchain/Info.plist)swift 命令指向下载的工具链,其中 TOOLCHAIN_NAME 是一个字符串,例如 swift-6.0.3-RELEASE

设置 SwiftPM 项目

以下是一个简单的 SwiftPM 模板,您可以使用它来开始使用 WebAssembly。

📂 Sources
  - 📂 Hello
      - 🕊️ Hello.swift
🕊️ Package.swift

Package.swift

// swift-tools-version:6.0
import PackageDescription

let package:Package = .init(name: "WebAssembly Example",
    products: [
        .executable(name: "Hello", targets: ["Hello"]),
    ],
    dependencies: [
        .package(url: "https://github.com/swiftwasm/JavaScriptKit", from: "0.21.0"),
    ],
    targets: [
        .executableTarget(name: "Hello",
            dependencies: [
                .product(name: "JavaScriptKit", package: "JavaScriptKit"),
            ]),
    ])

Hello.swift

import JavaScriptKit

guard
case .object(let div) = JSObject.global.document.createElement("div")
else
{
    fatalError("Could not create elements")
}

div.innerHTML = .string("Hi Barbie!")

_ = JSObject.global.document.body.appendChild(div)

构建项目

使用以下命令构建项目,根据需要替换 SWIFTWASM_SDK

SWIFTWASM_SDK=swift-wasm-6.0.2-RELEASE

swift build -c release \
    --product Hello \
    --swift-sdk $SWIFTWASM_SDK \
    -Xswiftc -Xclang-linker -Xswiftc -mexec-model=reactor \
    -Xlinker --export=__main_argc_argv

是的,所有尾部的构建标志都是必要的。

archer init

USAGE: archer init [--wasm-path <wasm-path>] [--js-name <js-name>] [--js-runtime <js-runtime>] --bundle <bundle>

OPTIONS:
  -w, --wasm-path <wasm-path>
                          Where the browser should load the WebAssembly (wasm) binary from (default: main.wasm)
  -m, --js-name <js-name> What to name the generated JavaScript file (default: main.js)
  -J, --js-runtime <js-runtime>
                          Where to find the JavaScriptKit runtime (default:
                          .build/release/JavaScriptKit_JavaScriptKit.resources)
  -o, --bundle <bundle>   Where to write the generated resources to
  -h, --help              Show help information.

WebAssembly 捆绑包由将部署到云端并提供给客户端的资源组成。archer init 命令将为您构建一个最小化的 JavaScript 运行时,并将其写入您选择的目录。

RUNTIME_NAME="runtime.js"
WASM_NAME="main.wasm"

archer init -m $RUNTIME_NAME -w $WASM_NAME -o Bundle

您需要提供 WebAssembly 二进制文件 (main.wasm) 的预期 URL,以及 JavaScriptKit 运行时的路径,该运行时版本与您用于构建 WebAssembly 的 JavaScriptKit 版本相匹配。

在此阶段没有构建项目的要求,但获取正确运行时版本的最简单方法是使用 SwiftPM 构建项目(在 release 模式下)。

您可能还需要生成一个 HTML 存根用于预览 WebAssembly,尽管在更大的项目中,您可能会从其他地方获取它。

(
cat <<EOF
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebAssembly Example</title>
<script type="module" src="$RUNTIME_NAME"></script></head>
<body>
    <h1>WebAssembly Example</h1>
</body>
</html>
EOF
) > Bundle/index.html

archer crush

USAGE: archer crush [<wasm-file>] [--output <output>] [--Xwasm-opt <Xwasm-opt> ...] [--preserve-debug-info]

ARGUMENTS:
  <wasm-file>             Where to find the WebAssembly (wasm) binary to crush

OPTIONS:
  -o, --output <output>   Where to write the optimized WebAssembly (wasm) binary (default: main.wasm)
  --Xwasm-opt <Xwasm-opt> Extra flags to pass to the WebAssembly optimizer
  -g, --preserve-debug-info
                          Whether to preserve debug info or not
  -h, --help              Show help information.

archer crush 命令用于优化 WebAssembly 二进制文件。Swift 编译器的原始 .wasm 输出可以直接使用,但 archer crush 可以使其更小更快。

archer crush .build/release/Hello.wasm -o Bundle/$WASM_NAME

将 WebAssembly 文件添加到您的捆绑包后,您可以使用 esbuild 在浏览器中预览它。

esbuild --servedir=Bundle

许可证

Archer 采用 Apache 2.0 许可证。