TypeScript 函数
了解如何在自定义构建配置中创建和使用 EAS 构建功能。
EAS Build 功能是扩展自定义构建功能的好方法。你可以使用它们创建可重用的步骤,并使用 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
初始化 EAS 构建功能模块
🌐 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 的新模块。该模块将包含一个预生成的模块配置以及带有默认 TypeScript 函数模板的 src 目录和 index.ts 文件。
🌐 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 中进行了配置。如果尚未设置,请在继续之前参考 开始使用自定义构建。
假设你在 .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。
概括
🌐 Summary
- 编写函数是使用你自己的逻辑扩展自定义构建功能的好方法。
- EAS 构建功能是可重用的 - 你可以在多个自定义构建配置中使用它们。
- 对于通过编写 shell 脚本不容易完成的更高级用例来说,使用 EAS 构建函数是一个不错的选择。
- 大多数内置函数都是开源的,可以被分叉或作为编写自己函数的参考。
查看 示例仓库 以获取更详细的示例:
🌐 Check out the example repository for more detailed examples:
一个自定义 EAS 构建示例,其中包含自定义构建的示例,如设置函数、使用环境变量、上传工件等。