Skip to content

Tauri Nix 打包注解

项目架构

Tauri 在 Nix 打包流程中是比较难以处理的框架之一。其一原因是 Tauri 使用 Javascript + Rust 两门语言,同时保持 npm/yarn/pnpm/bun/cargo 多种包管理器/构建工具兼容,混合了 Nodejs/Rust 的构建流程;这种复杂的构建方式自然引入了一定的理解难度。

常见 Tauri 项目的结构如下:

shell
 tree
 .
├── images
├── public
├── src # JS/TS frontend
   ├── components
   ├── css
   ├── lib
   ├── page
   ├── App.tsx
   └── main.tsx
├── src-tauri # Rust backend
   ├── icons
   ├── src
   ├── app
   └── main.rs
   ├── build.rs
   ├── Cargo.lock
   ├── Cargo.toml
   └── tauri.conf.json
├── package.json
└── <Lockfile>

对 Rust 项目构建熟悉的一眼就能看到 src-tauri/build.rs,这就是 Rust 后端部分的构建入口。

另外,src-tauri/tauri.conf.json 记录了 JS/TS 前端的构建流程/显示配置/应用元数据等信息:

json
{
  "build": {
    "beforeDevCommand": "yarn dev",
    "beforeBuildCommand": "yarn build",
    "devPath": "http://localhost:<port>",
    "distDir": "../dist"
  },
  "package": {
    "productName": "<name>",
    "version": "<version>"
  },
  "tauri": {
    "allowlist": { }, // permitted operation
    "windows": [ ], // window display
    "security": { },
    "updater": { },
    "bundle": { } // bundle release
  }
}

Nixify

Devshell 配置可参考 Tauri 官方教程

打包相对开发较为困难:涉及多个包管理器/语言;JS/TS 标准分立;node_modules 拖家带口...... 为此 Nixpkgs 提供了一系列 Hook 辅助构建流程,并且统一使用 cargo + cargo-tauri 作为构建入口。

打包示例如下:

nix
{
  lib,
  stdenv,
  rustPlatform,
  fetchNpmDeps,
  fetchYarnDeps,
  cargo-tauri,
  cargo-tauri_1,
  glib-networking,
  nodejs,
  npmHooks,
  yarnConfigHook,
  pnpm,
  openssl,
  pkg-config,
  webkitgtk_4_0,
  webkitgtk_4_1,
  webkitgtk_6_0,
  wrapGAppsHook3,
  wrapGAppsHook4,
}:

rustPlatform.buildRustPackage rec {
  # src ...

  cargoHash = "...";

  ## npm ##
  # npmDeps = fetchNpmDeps {
    # name = "${pname}-npm-deps-${version}";
    # inherit src;
    # hash = "...";
  # };
  
  ## yarn ##
  yarnOfflineCache = fetchYarnDeps {
    yarnLock = src + "/yarn.lock";
    hash = "...";
  };

  ## pnpm ##
  # pnpmDeps = pnpm.fetchDeps {
    # inherit (finalAttrs) pname version src;
    # hash = "...";
  # };

  nativeBuildInputs = [
    # Pull in our main hook (so that we can build with `cargo tauri build`)
    cargo-tauri.hook # Tauri latest (v2)
    # cargo-tauri_1.hook # Tauri v1

    # Node (can also be pinned by override)
    nodejs

    # Setup npm/yarn/pnpm (depend on lockfile)
    ## npm ##
    # npmHooks.npmConfigHook
    ## yarn ##
    yarnConfigHook
    ## pnpm ##
    # pnpm.configHook

    # Make sure we can find our libraries
    pkg-config
    wrapGAppsHook3 # GTK3
    # wrapGAppsHook4 # GTK4
  ];

  buildInputs =
    [ openssl ]
    ++ lib.optionals stdenv.hostPlatform.isLinux [
      glib-networking # Most Tauri apps need networking
      # [webkit-gtk ABI issue](https://webkit-gtk.webkit.narkive.com/xWwjSvhW/abi-compatibility-between-releases)
      ## Choose the compatible version among 4.0/4.1/6.0 ##
      # webkitgtk_4_0
      webkitgtk_4_1 
      # webkitgtk_6_0
    ]
    ++ lib.optionals stdenv.hostPlatform.isDarwin (
      with darwin.apple_sdk.frameworks;
      [
        AppKit
        CoreServices
        Security
        WebKit
      ]
    );

  # Set our Tauri source directory
  cargoRoot = "src-tauri";
  # And make sure we build there too
  buildAndTestSubdir = cargoRoot;

  # meta ...
}

某些开发不规范的 Tauri 应用打包可能极为困难(例如 clash-verge-rev