了解如何在自定义构建配置中创建和使用 EAS 构建功能。
EAS 构建功能是扩展自定义构建功能的好方法。你可以使用它们创建可重用的步骤,并用 JavaScript、TypeScript 或 Bash 编写逻辑(更多信息请参见 配置模式中的 command
)。本指南提供了在 TypeScript 中创建函数的演练。
¥EAS Build functions are a great way to extend the functionality of custom builds. You can use them to create reusable steps, and to write your logic in JavaScript, TypeScript, or Bash (more information in command
in the config schema). This guide provides a walkthrough of creating a function in TypeScript.
1
¥Initialize an EAS Build function module
创建 EAS 构建功能的最简单方法是使用 create-eas-build-function
CLI 工具。通过从 eas.json 文件所在的同一目录运行以下命令,你可以创建一个新的自定义 TypeScript 函数:
¥The easiest way to create an EAS Build function is to use the create-eas-build-function
CLI tool. By running the following command from the same directory as your eas.json file, you can create a new custom TypeScript function:
-
npx create-eas-build-function@latest ./.eas/build/myFunction
这会在 .eas/build 目录中创建一个名为 myFunction
的新模块。该模块将包含预先生成的模块配置和 src 目录,其中的 index.ts 文件包含默认的 TypeScript 函数模板。
¥This creates a new module called myFunction
in the .eas/build directory. The module will contain a pre-generated module configuration and the src directory with the index.ts file containing the default TypeScript function template.
// This file was autogenerated by `create-eas-build-function` command.
// Go to README.md to learn more about how to write your own custom build functions.
import { BuildStepContext } from '@expo/steps';
// interface FunctionInputs {
// // specify the type of the inputs value and whether they are required here
// // example: name: BuildStepInput<BuildStepInputValueTypeName.STRING, true>;
// }
// interface FunctionOutputs {
// // specify the function outputs and whether they are required here
// // example: name: BuildStepOutput<true>;
// }
async function myFunction(
ctx: BuildStepContext
// {
// inputs,
// outputs,
// env,
// }: {
// inputs: FunctionInputs;
// outputs: FunctionOutputs;
// env: BuildStepEnv;
// }
): Promise<void> {
ctx.logger.info('Hello from my TypeScript function!');
}
export default myFunction;
2
¥Compile the function
函数必须编译为单个 JavaScript 文件,该文件可以在不安装任何依赖的情况下运行。生成函数的默认 build
脚本使用 ncc 将函数及其所有依赖编译到单个文件中。如果你的计算机上没有全局安装 ncc
,请运行 npm install -g @vercel/ncc
来安装它。接下来,运行 .eas/build/myFunction 目录中的构建脚本:
¥Functions must be compiled to a single JavaScript file that can be run without installing any dependencies. The default build
script for generated functions uses ncc to compile your function into a single file with all its dependencies. If you don't have the ncc
installed globally on your machine, run npm install -g @vercel/ncc
to install it. Next, run the build script in the .eas/build/myFunction directory:
-
npm run build
此命令会触发放置在自定义功能模块的 package.json 文件中的 build
脚本。
¥This command triggers the build
script placed in the package.json file of your custom function module.
{
...
"scripts": {
...
"build": "ncc build ./src/index.ts -o build/ --minify --no-cache --no-source-map-register"
...
},
...
}
build
脚本生成 build/index.js。该文件必须作为项目存档的一部分上传到 EAS Build,以便构建器可以运行你的函数。确保该文件未被 .gitignore 文件或 .easignore 文件排除。
¥The build
script generates build/index.js. This file must be uploaded to EAS Build as a part of your project archive, so that the builder can run your function. Ensure that the file is not excluded by a .gitignore file or .easignore file.
3
¥Expose the function to the custom build config
注意:以下示例假设你已经设置了自定义构建工作流程并在 eas.json 中对其进行了配置。如果没有,请先参阅 开始定制构建,然后再继续。
¥Note: The following example assumes that you have already set up a custom build workflow and configured it in your eas.json. If not, see Get started with custom builds before proceeding.
假设你在 .eas/build 目录中有一个 config.yml 文件。它包含以下内容:
¥Let's assume that you have a config.yml file in the .eas/build directory. It contains the following content:
build:
name: My example config
steps:
- eas/checkout
- eas/install_node_modules
- run:
name: Finished
command: echo Finished
要将函数添加到配置中,你需要将以下行添加到 config.yml 文件中:
¥To add your function to the config, you need to add the following lines to the config.yml file:
build:
name: My example config
steps:
- eas/checkout
- eas/install_node_modules
- run:
name: Finished
command: echo Finished
functions:
my_function:
name: My function
path: ./myFunction
path
属性应该是从配置文件到函数目录的相对路径。在本例中,它只是 ./myFunction
。
¥The path
property should be a relative path from the config file to your function directory. In this case, it's just ./myFunction
.
现在,在 config.yml 文件中添加对 my_function
函数的调用:
¥Now, add a call to the my_function
function in the config.yml file:
build:
name: My example config
steps:
- eas/checkout
- eas/install_node_modules
- my_function
- run:
name: Finished
command: echo Finished
functions:
my_function:
name: My function
path: ./myFunction
4
¥Working on the function
对于更高级的示例,假设你想让一个函数计算两个数字的总和并将结果打印到控制台,然后从该函数输出该值。为此,请修改 config.yml 和 index.ts 文件,使函数接受名为 num1
和 num2
的两个输入,并将它们的总和作为名为 sum
的输出返回。
¥For a more advanced example, let's say you want to make a function calculate the sum of two numbers and print the result to the console, and then output that value from the function. To do this, modify the config.yml and index.ts files to make the function accept two inputs called num1
and num2
and return their sum as an output called sum
.
build:
name: My example config
steps:
- eas/checkout
- eas/install_node_modules
- my_function:
inputs:
num1: 1
num2: 2
id: sum_function
- run:
name: Print the sum
inputs:
sum: ${ steps.sum_function.sum }
command: echo ${ inputs.sum }
- run:
name: Finished
command: echo Finished
functions:
my_function:
name: My function
inputs:
- name: num1
type: number
- name: num2
type: number
outputs:
- name: sum
path: ./myFunction
// This file was autogenerated by `create-eas-build-function` command.
// Go to README.md to learn more about how to write your own custom build functions.
import {
BuildStepContext,
BuildStepInput,
BuildStepInputValueTypeName,
BuildStepOutput,
} from '@expo/steps';
interface FunctionInputs {
// first template argument is the type of the input value, second template argument is a boolean indicating if the input is required
num1: BuildStepInput<BuildStepInputValueTypeName.NUMBER, true>;
num2: BuildStepInput<BuildStepInputValueTypeName.NUMBER, true>;
}
interface FunctionOutputs {
// template argument is a boolean indicating if the output is required
sum: BuildStepOutput<true>;
}
async function myFunction(
ctx: BuildStepContext,
{
inputs,
outputs,
}: // env,
{
inputs: FunctionInputs;
outputs: FunctionOutputs;
// env: BuildStepEnv;
}
): Promise<void> {
ctx.logger.info(`num1: ${inputs.num1.value}`);
ctx.logger.info(`num2: ${inputs.num2.value}`);
const sum = inputs.num1.value + inputs.num2.value;
ctx.logger.info(`sum: ${sum}`);
outputs.sum.set(sum.toString()); // Currently, outputs must be strings. This will improve in the future.
}
export default myFunction;
信息 请记住每次更改函数时都要编译它:
npm run build
。¥Remember to compile your function each time you make changes to it:
npm run build
.
¥Summary
编写函数是使用你自己的逻辑扩展自定义构建功能的好方法。
¥Writing functions is a great way to extend the functionality of custom builds with your own logic.
EAS 构建功能是可重用的 - 你可以在多个自定义构建配置中使用它们。
¥EAS Build functions are reusable — you can use them in multiple custom build configurations.
对于通过编写 shell 脚本不容易完成的更高级用例来说,使用 EAS 构建函数是一个不错的选择。
¥Using EAS Build functions is a great option for more advanced use cases that are not easy to do by writing shell scripts.
内置函数 的大部分都是开源的,可以分叉或用作编写自己的函数的参考。
¥Most of the built-in functions are open-source and can be forked or used as a reference for writing your own functions.
查看示例存储库以获取更详细的示例:
¥Check out the example repository for more detailed examples:
自定义 EAS 构建示例,其中包括工作流程示例,例如设置函数、使用环境变量、上传工件等。