嵌入外部二進制檔
您可能需要嵌入相依二進制檔,才能讓應用程式運作,或防止使用者安裝額外的相依性(例如 Node.js 或 Python)。我們將此二進制檔稱為sidecar
。
若要組合您選擇的二進制檔,您可以將externalBin
屬性新增到tauri.conf.json
中的tauri > bundle
物件。
在此處查看更多關於 tauri.conf.json 組態的資訊 here。
externalBin
預期會有一串字串清單,目標是具有絕對或相對路徑的二進制檔。
以下是一個範例來說明組態。這不是一個完整的tauri.conf.json
檔案
{
"tauri": {
"bundle": {
"externalBin": [
"/absolute/path/to/sidecar",
"relative/path/to/binary",
"binaries/my-sidecar"
]
},
"allowlist": {
"shell": {
"sidecar": true,
"scope": [
{ "name": "/absolute/path/to/sidecar", "sidecar": true },
{ "name": "relative/path/to/binary", "sidecar": true },
{ "name": "binaries/my-sidecar", "sidecar": true }
]
}
}
}
}
在指定的路徑上,必須存在一個具有相同名稱和-$TARGET_TRIPLE
字尾的二進制檔。例如,"externalBin": ["binaries/my-sidecar"]
需要在 Linux 上有一個src-tauri/binaries/my-sidecar-x86_64-unknown-linux-gnu
可執行檔。您可以透過查看rustc -Vv
指令所報告的host:
屬性,來找出目前的平台目標三元組。
如果grep
和cut
指令可用(它們應該在大部分 Unix 系統上可用),您可以使用以下指令直接擷取目標三元組
rustc -Vv | grep host | cut -f2 -d' '
在 Windows 上,您可以改用 PowerShell
rustc -Vv | Select-String "host:" | ForEach-Object {$_.Line.split(" ")[1]}
以下是一個 Node.js 程式碼,用於將目標三元組附加到二進制檔
const execa = require('execa')
const fs = require('fs')
let extension = ''
if (process.platform === 'win32') {
extension = '.exe'
}
async function main() {
const rustInfo = (await execa('rustc', ['-vV'])).stdout
const targetTriple = /host: (\S+)/g.exec(rustInfo)[1]
if (!targetTriple) {
console.error('Failed to determine platform target triple')
}
fs.renameSync(
`src-tauri/binaries/sidecar${extension}`,
`src-tauri/binaries/sidecar-${targetTriple}${extension}`
)
}
main().catch((e) => {
throw e
})
從 JavaScript 執行
在 JavaScript 程式碼中,匯入shell
模組上的Command
類別,並使用sidecar
靜態方法。
請注意,您必須設定允許清單,才能啟用shell > sidecar
,並設定shell > scope
中的所有二進制檔。
import { Command } from '@tauri-apps/api/shell'
// alternatively, use `window.__TAURI__.shell.Command`
// `binaries/my-sidecar` is the EXACT value specified on `tauri.conf.json > tauri > bundle > externalBin`
const command = Command.sidecar('binaries/my-sidecar')
const output = await command.execute()
從 Rust 執行
在 Rust 端,從 tauri::api::process
模組匯入 Command
結構
// `new_sidecar()` expects just the filename, NOT the whole path like in JavaScript
let (mut rx, mut child) = Command::new_sidecar("my-sidecar")
.expect("failed to create `my-sidecar` binary command")
.spawn()
.expect("Failed to spawn sidecar");
tauri::async_runtime::spawn(async move {
// read events such as stdout
while let Some(event) = rx.recv().await {
if let CommandEvent::Stdout(line) = event {
window
.emit("message", Some(format!("'{}'", line)))
.expect("failed to emit event");
// write to stdin
child.write("message from Rust\n".as_bytes()).unwrap();
}
}
});
請注意,您必須啟用 process-command-api Cargo 功能(一旦您變更設定,Tauri 的 CLI 會為您執行此操作)
# Cargo.toml
[dependencies]
tauri = { version = "1", features = ["process-command-api", ...] }
傳遞引數
您可以傳遞引數給 Sidecar 指令,就像執行一般 Command
一樣(請參閱 限制存取 Command API)。
首先,在 tauri.conf.json
中定義需要傳遞給 Sidecar 指令的引數
{
"tauri": {
"bundle": {
"externalBin": [
"/absolute/path/to/sidecar",
"relative/path/to/binary",
"binaries/my-sidecar"
]
},
"allowlist": {
"shell": {
"sidecar": true,
"scope": [
{
"name": "binaries/my-sidecar",
"sidecar": true,
"args": [
"arg1",
"-a",
"--arg2",
{
"validator": "\\S+"
}
]
}
]
}
}
}
}
然後,若要呼叫 Sidecar 指令,只需將 所有 引數作為陣列傳入
import { Command } from '@tauri-apps/api/shell'
// alternatively, use `window.__TAURI__.shell.Command`
// `binaries/my-sidecar` is the EXACT value specified on `tauri.conf.json > tauri > bundle > externalBin`
// notice that the args array matches EXACTLY what is specified on `tauri.conf.json`.
const command = Command.sidecar('binaries/my-sidecar', [
'arg1',
'-a',
'--arg2',
'any-string-that-matches-the-validator',
])
const output = await command.execute()
在 Sidecar 上使用 Node.js
Tauri Sidecar 範例展示如何使用 Sidecar API 在 Tauri 上執行 Node.js 應用程式。它使用 pkg 編譯 Node.js 程式碼,並使用上述指令碼執行它。