Skip to content
Tauri 中文网

嵌入附加文件

你可能需要在你的应用包中包含其他文件,这些文件不是你前端(你的 frontendDist)的直接组成部分,或者太大而无法内联到二进制文件中。我们将这些文件称为 resources

¥You may need to include additional files in your application bundle that aren’t part of your frontend (your frontendDist) directly or which are too big to be inlined into the binary. We call these files resources.

¥Configuration

要打包你选择的文件,请将 resources 属性添加到 tauri.conf.json 文件中的 bundle 对象。

¥To bundle the files of your choice, add the resources property to the bundle object in your tauri.conf.json file.

要包含文件列表:

¥To include a list of files:

tauri.conf.json
{
"bundle": {
"resources": [
"./path/to/some-file.txt",
"/absolute/path/to/textfile.txt",
"../relative/path/to/jsonfile.json",
"some-folder/",
"resources/**/*.md"
]
}
}

打包后的文件将位于 $RESOURCES/ 中,并保留原始目录结构,例如:./path/to/some-file.txt -> $RESOURCE/path/to/some-file.txt

¥The bundled files will be in $RESOURCES/ with the original directory structure preserved, for example: ./path/to/some-file.txt -> $RESOURCE/path/to/some-file.txt

要精确控制文件复制到的位置,请使用映射:

¥To fine control where the files will get copied to, use a map instead:

tauri.conf.json
{
"bundle": {
"resources": {
"/absolute/path/to/textfile.txt": "resources/textfile.txt",
"relative/path/to/jsonfile.json": "resources/jsonfile.json",
"resources/": "",
"docs/**/*md": "website-docs/"
}
}
}

要了解 $RESOURCE 在各个平台上的解析位置,请参阅 resource_dir 的文档。

¥To learn about where $RESOURCE resolves to on each platforms, see the documentation of resource_dir

Source path syntax

在以下解释中,“目标资源目录” 要么是对象表示法中冒号后的值,要么是数组表示法中原始文件路径的重建。

¥In the following explanations “target resource directory” is either the value after the colon in the object notation, or a reconstruction of the original file paths in the array notation.

  • "dir/file.txt":将 file.txt 文件复制到目标资源目录中。

    ¥"dir/file.txt": copies the file.txt file into the target resource directory.

  • "dir/":将所有文件和目录递归复制到目标资源目录中。如果你还想保留文件和目录的文件系统结构,请使用此选项。

    ¥"dir/": copies all files and directories recursively into the target resource directory. Use this if you also want to preserve the file system structure of your files and directories.

  • "dir/*":将 dir 目录中的所有文件非递归地(子目录将被忽略)复制到目标资源目录中。

    ¥"dir/*": copies all files in the dir directory non-recursively (sub-directories will be ignored) into the target resource directory.

  • "dir/**:抛出错误,因为 ** 仅匹配目录,因此找不到文件。

    ¥"dir/**: throws an error because ** only matches directories and therefore no files can be found.

  • "dir/**/*":将 dir 目录中的所有文件递归地(dir/ 中的所有文件和所有子目录中的所有文件)复制到目标资源目录中。

    ¥"dir/**/*": copies all files in the dir directory recursively (all files in dir/ and all files in all sub-directories) into the target resource directory.

  • "dir/**/**:抛出错误,因为 ** 仅匹配目录,因此找不到文件。

    ¥"dir/**/**: throws an error because ** only matches directories and therefore no files can be found.

¥Resolve resource file paths

要解析资源文件的路径(而不是手动计算路径),请使用以下 API。

¥To resolve the path for a resource file, instead of manually calculating the path, use the following APIs

在 Rust 方面,你需要一个 PathResolver 实例,该实例可以从 AppAppHandle 获取,然后调用 PathResolver::resolve

¥On the Rust side, you need an instance of the PathResolver which you can get from App and AppHandle, then call PathResolver::resolve:

tauri::Builder::default()
.setup(|app| {
let resource_path = app.path().resolve("lang/de.json", BaseDirectory::Resource)?;
Ok(())
})

要在命令中使用:

¥To use it in a command:

#[tauri::command]
fn hello(handle: tauri::AppHandle) {
let resource_path = handle.path().resolve("lang/de.json", BaseDirectory::Resource)?;
}

¥Path syntax

API 调用中的路径可以是解析为 $RESOURCE/folder/json_file.json 的普通相对路径(例如 folder/json_file.json),也可以是解析为 $RESOURCE/_up_/relative/folder/toml_file.toml 的路径(例如 ../relative/folder/toml_file.toml)。这些 API 使用与你编写 tauri.conf.json > bundle > resources 相同的规则,例如:

¥The path in the API calls can be either a normal relative path like folder/json_file.json that resolves to $RESOURCE/folder/json_file.json, or a paths like ../relative/folder/toml_file.toml that resolves to $RESOURCE/_up_/relative/folder/toml_file.toml, these APIs use the same rules as you write tauri.conf.json > bundle > resources, for example:

tauri.conf.json
{
"bundle": {
"resources": ["folder/json_file.json", "../relative/folder/toml_file.toml"]
}
}
let json_path = app.path().resolve("folder/json_file.json", BaseDirectory::Resource)?;
let toml_path = app.path().resolve("../relative/folder/toml_file.toml", BaseDirectory::Resource)?;

目前,资源作为 assets 存储在 APK 中,因此这些 API 的返回值不是普通的文件系统路径,我们在此使用一个特殊的 URI 前缀 asset://localhost/,它可以与 fs 插件 一起使用,这样你就可以通过 FsExt::fs 读取文件,如下所示:

¥Currently the resources are stored in the APK as assets so the return value of those APIs are not normal file system paths, we use a special URI prefix asset://localhost/ here that can be used with the fs plugin, with that, you can read the files through FsExt::fs like this:

let resource_path = app.path().resolve("lang/de.json", BaseDirectory::Resource).unwrap();
let json = app.fs().read_to_string(&resource_path);

如果你希望或必须将资源文件放在真实的文件系统上,请通过 fs 插件 手动复制内容。

¥If you want or must have the resource files to be on a real file system, copy the contents out manually through the fs plugin

¥Reading resource files

在此示例中,我们希望像这样打包额外的 i18n json 文件:

¥In this example we want to bundle additional i18n json files like this:

.
├── src-tauri/
│ ├── tauri.conf.json
│ ├── lang/
│ │ ├── de.json
│ │ └── en.json
│ └── ...
└── ...
tauri.conf.json
{
"bundle": {
"resources": ["lang/*"]
}
}
lang/de.json
{
"hello": "Guten Tag!",
"bye": "Auf Wiedersehen!"
}

在 Rust 方面,你需要一个 PathResolver 实例,你可以从 AppAppHandle 中获取该实例:

¥On the Rust side, you need an instance of the PathResolver which you can get from App and AppHandle:

tauri::Builder::default()
.setup(|app| {
// The path specified must follow the same syntax as defined in
// `tauri.conf.json > bundle > resources`
let resource_path = app.path().resolve("lang/de.json", BaseDirectory::Resource)?;
let json = std::fs::read_to_string(&resource_path).unwrap();
// Or when dealing with Android, use the file system plugin instead
// let json = app.fs().read_to_string(&resource_path);
let lang_de: serde_json::Value = serde_json::from_str(json).unwrap();
// This will print 'Guten Tag!' to the terminal
println!("{}", lang_de.get("hello").unwrap());
Ok(())
})
#[tauri::command]
fn hello(handle: tauri::AppHandle) -> String {
let resource_path = handle.path().resolve("lang/de.json", BaseDirectory::Resource)?;
let json = std::fs::read_to_string(&resource_path).unwrap();
// Or when dealing with Android, use the file system plugin instead
// let json = handle.fs().read_to_string(&resource_path);
let lang_de: serde_json::Value = serde_json::from_str(json).unwrap();
lang_de.get("hello").unwrap()
}

对于 JavaScript 端,你可以使用类似上述命令并通过 await invoke('hello') 调用,也可以使用 fs 插件 访问文件。

¥For the JavaScript side, you can either use a command like the one above and call it through await invoke('hello') or access the files using the fs plugin.

使用 fs 插件 时,除了 基本设置 之外,你还需要配置访问控制列表以启用所需的任何插件 API 以及访问 $RESOURCE 文件夹的权限:

¥When using the fs plugin, in addition to the basic setup, you’ll also need to configure the access control list to enable any plugin APIs you need as well as the permissions to access the $RESOURCE folder:

src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"fs:allow-read-text-file",
"fs:allow-resource-read-recursive"
]
}

:::note 注意

以下我们使用 fs:allow-resource-read-recursive 来允许对完整的 $RESOURCE 文件夹、文件和子目录进行完全递归读取访问。有关更多信息,请阅读 范围权限 以了解其他选项,或阅读 范围 以了解更细粒度的控制。

¥Here we use fs:allow-resource-read-recursive to allow for full recursive read access to the complete $RESOURCE folder, files, and subdirectories. For more information, read Scope Permissions for other options, or Scopes for more fine-grained control.

:::

import { resolveResource } from '@tauri-apps/api/path';
import { readTextFile } from '@tauri-apps/plugin-fs';
const resourcePath = await resolveResource('lang/de.json');
const langDe = JSON.parse(await readTextFile(resourcePath));
console.log(langDe.hello); // This will print 'Guten Tag!' to the devtools console

¥Permissions

由于我们在使用列表时将相对路径中的 ../ 替换为 _up_,将绝对路径中的根目录替换为 _root_,因此这些文件将位于资源目​​录内的子文件夹中。为了在 Tauri 的 权限系统 中允许这些路径,请使用 $RESOURCE/**/* 来允许递归访问这些文件。

¥Since we replace ../ to _up_ in relative paths and the root to _root_ in abosolute paths when using a list, those files will be in sub folders inside the resource directory, to allow those paths in Tauri’s permission system, use $RESOURCE/**/* to allow recursive access to those files

¥Examples

打包文件如下:

¥With a file bundled like this:

tauri.conf.json
{
"bundle": {
"resources": ["../relative/path/to/jsonfile.json"]
}
}

要与 fs 插件 一起使用:

¥To use it with the fs plugin:

src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
"fs:allow-stat",
"fs:allow-read-text-file",
"fs:allow-resource-read-recursive",
{
"identifier": "fs:scope",
"allow": ["$RESOURCE/**/*"],
"deny": ["$RESOURCE/secret.txt"]
}
]
}

要与 opener 插件 一起使用:

¥To use it with the opener plugin:

src-tauri/capabilities/default.json
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "main-capability",
"description": "Capability for the main window",
"windows": ["main"],
"permissions": [
"core:default",
{
"identifier": "opener:allow-open-path",
"allow": [
{
"path": "$RESOURCE/**/*"
}
]
}
]
}

Tauri v2.9 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站