在你的服务器上托管更新


本文档于 2022 年 8 月存档,不会收到任何进一步更新。请改用 EAS 更新。了解更多

¥This doc was archived in August 2022 and will not receive any further updates. Please use EAS Update instead. Learn more

通常,当启用更新时,你的应用将从 Expo 的 CDN 获取包含 JavaScript 包和资源的更新。然而,在某些情况下,你可能希望将 JS 包和资源托管在你自己的服务器上。例如,在 AWS 和 Google Cloud 上屏蔽 Expo CDN 提供商的国家/地区,更新速度缓慢或无法使用。在这些情况下,你可以在自己的服务器上托管更新,以更好地适合你的用例。

¥Normally, when updates are enabled, your app will fetch updates comprising JavaScript bundles and assets from Expo's CDN. However, there will be situations when you will want to host your JS bundles and assets on your own servers. For example, updates are slow or unusable in countries that have blocked Expo's CDN providers on AWS and Google Cloud. In these cases, you can host your updates on your own servers to better suit your use cases.

为简单起见,本文的其余部分将提及托管 Android 平台的更新,但你可以随时将 Android 更换为 iOS,一切仍然正确。

¥For simplicity, the rest of this article will refer to hosting an update for the Android platform, but you could swap out Android for iOS at any point and everything would still be true.

导出更新

¥Exporting the update

首先,你需要导出更新的所有静态文件,以便可以通过 CDN 提供它们。为此,请在项目目录中运行 expo export --public-url <server-endpoint>,它将把应用的所有静态文件输出到名为 dist 的目录中。在本指南中,我们将使用 https://expo.github.io/self-hosting-example 作为示例服务器端点。资源和打包文件由其内容的 MD5 哈希值命名。你的输出目录现在应该如下所示:

¥First, you'll need to export all the static files of your update so they can be served from your CDN. To do this, run expo export --public-url <server-endpoint> in your project directory and it will output all your app's static files to a directory named dist. In this guide, we will use https://expo.github.io/self-hosting-example as our example server endpoint. Asset and bundle files are named by the MD5 hash of their content. Your output directory should look something like this now:

.
android-index.json
ios-index.json
assets
  1eccbc4c41d49fd81840aef3eaabe862
bundles
  android-01ee6e3ab3e8c16a4d926c91808d5320.js
  ios-ee8206cc754d3f7aa9123b7f909d94ea.js

托管你的静态文件

¥Hosting your static files

导出更新的静态文件后,你可以将内容托管在你自己的服务器上。例如,在 dist 输出目录中,托管自己的文件的一种简单方法是将内容推送到 GitHub。你可以启用 GitHub 页面 以使你的应用可在 https://username.github.io/project-name 等基本 URL 上使用。要将文件托管在 GitHub 上,你需要执行以下操作:

¥Once you have exported your update's static files, you can host the contents on your own server. For example, in your dist output directory, an easy way to host your own files is to push the contents to GitHub. You can enable GitHub Pages to make your app available at a base URL like https://username.github.io/project-name. To host your files on GitHub, you'd do something like this:

Terminal
# run this from your project directory
expo export --public-url https://expo.github.io/self-hosting-example

# commit output directory contents to your repo
cd dist
git init && git remote add origin git@github.com:expo/self-hosting-example.git
git add * && git commit -m "Update my app with this JS bundle"
git push origin master

要设置 QR 码来查看托管更新,或者如果你想在本地托管文件,请按照下面 '开发中加载二维码/URL' 部分中的说明进行操作。

¥To setup a QR code to view your hosted update, or if you want to host your files locally, follow the instructions below in the 'Loading QR Code/URL in Development' section.

HTTP 标头

¥HTTP headers

在某些托管服务(例如 AWSFirebase)上,你需要将 JavaScript 文件的标头 "Content-Type" 显式设置为 "application/javascript",以便 updates 正常工作。否则 Updates.checkForUpdateAsync() 将失败并出现错误 "无法获取新的更新"。

¥On some hosting services such as AWS and Firebase, you'll need to explicitly set the header "Content-Type" of JavaScript files as "application/javascript" so that updates work correctly. Otherwise Updates.checkForUpdateAsync() will fail with the error "Failed to fetch new update".

下面是 firebase.json 配置的示例,其中 部署目标 名为 "native"。

¥Here's an example of firebase.json configuration, with a deploy target named "native".

{
  "hosting": [
    {
      "target": "native",
      "public": "dist",
+      "headers": [
+        {
+          "source": "**/*.js",
+          "headers": [
+            {
+              "key": "Content-Type",
+              "value": "application/javascript"
+            }
+          ]
        }
      ]
    }
  ]
}
Terminal
# export your app locally
expo export --public-url https://my-app-native.firebaseapp.com/

# deploy the app to firebase
firebase deploy --only hosting:native -m "Deploy my app"

构建独立应用

¥Building the standalone app

要配置独立二进制文件以从服务器提取更新,你需要定义将托管 index.json 文件的 URL。使用 EAS Build 时,只需将 updates.url property in app.json 设置为指向该 url。

¥To configure your standalone binary to pull updates from your server, you'll need to define the URL where you will host your index.json file. When using EAS Build, just set the updates.url property in app.json to point to that url.

开发中加载二维码/URL

¥Loading QR Code/URL in Development

你还可以将托管在你自己的服务器上的更新作为 QR 代码/URL 加载到 Expo 移动客户端中以进行开发。

¥You can also load an update hosted on your own servers as a QR code/URL into the Expo mobile client for development purposes.

二维码:

¥QR code:

你将用于转换为二维码的 URI 将使用 exps/exp 协议进行深度链接。expsexp 都深度链接到移动应用并分别使用 HTTPS 和 HTTP 执行请求。你可以使用在线 QR 代码生成器从输入 URI 创建你自己的 QR 代码。

¥The URI you'll use to convert to QR code will be deeplinked using the exps/exp protocol. Both exps and exp deeplink into the mobile app and perform a request using HTTPS and HTTP respectively. You can create your own QR code using an online QR code generator from the input URI.

以下是如何使用远程服务器执行此操作的示例:

¥Here's an example of how you'd do this with a remote server:

网址:exps://expo.github.io/self-hosting-example/android-index.json

¥URI: exps://expo.github.io/self-hosting-example/android-index.json

二维码:从 https://www.qr-code-generator.com/ 等网站生成 URI

¥QR code: Generate the URI from a website like https://www.qr-code-generator.com/

以下是如何从本地主机执行此操作的示例:

¥Here's an example of how you'd do this from localhost:

在开发模式下运行 expo export,然后在输出目录中启动一个简单的 HTTP 服务器:

¥Run expo export in dev mode and then start a simple HTTP server in your output directory:

Terminal
# Find your local IP address with `ipconfig getifaddr en0`# export static app files
expo export --public-url http://`ipconfig getifaddr en0`:8000 --dev

# cd into your output directory
cd dist

# run a simple http server from output directory
python -m SimpleHTTPServer 8000

网址:exp://192.xxx.xxx.xxx:8000/android-index.json(使用 ipconfig getifaddr en0 等命令查找你的本地 IP)

¥URI: exp://192.xxx.xxx.xxx:8000/android-index.json (find your local IP with a command like ipconfig getifaddr en0)

二维码:使用你的 URI 从 https://www.qr-code-generator.com/ 等网站生成 QR 码

¥QR code: Generate a QR code using your URI from a website like https://www.qr-code-generator.com/

URL

如果你通过传入 URL 字符串将更新加载到开发版本中,则需要传入指向 JSON 清单文件的 URL。

¥If you are loading in your update into a development build by passing in a URL string, you will need to pass in an URL pointing to your JSON manifest file.

以下是来自远程服务器的 URL 示例:https://expo.github.io/self-hosting-example/android-index.json

¥Here is an example URL from a remote server: https://expo.github.io/self-hosting-example/android-index.json

以下是来自 localhost 的示例 URL:http://localhost:8000/android-index.json

¥Here is an example URL from localhost: http://localhost:8000/android-index.json

高级主题

¥Advanced topics

调试

¥Debugging

当 Expo CLI 打包你的更新时,缩小功能始终处于启用状态。要查看更新的原始源代码以进行调试,你可以生成源映射。这是一个示例工作流程:

¥When Expo CLI bundles your update, minification is always enabled. To see the original source code of your update for debugging purposes, you can generate source maps. Here is an example workflow:

  1. 运行 expo export --dump-sourcemap --public-url <your-url>。这还将导出包目录中的包源映射。

    ¥Run expo export --dump-sourcemap --public-url <your-url>. This will also export your bundle sourcemaps in the bundles directory.

  2. 还将在输出目录的根目录下创建一个 debug.html 文件。

    ¥A debug.html file will also be created at the root of your output directory.

  3. 在 Chrome 中,打开 debug.html 并导航到 Source 选项卡。在左侧选项卡中应该有一个资源浏览器,其中有一个红色文件夹,其中包含从包中重建的源代码。

    ¥In Chrome, open up debug.html and navigate to the Source tab. In the left tab there should be a resource explorer with a red folder containing the reconstructed source code from your bundle.

Debugging Source Code

资源托管

¥Asset hosting

默认情况下,所有资源均从从 public-url 解析的 assets 路径(例如 https://expo.github.io/self-hosting-example/assets)托管。你可以在 android-index.jsonassetUrlOverride 字段中覆盖此行为。所有相对 URL 都将从 public-url 解析。

¥By default, all assets are hosted from an assets path resolving from your public-url (for example, https://expo.github.io/self-hosting-example/assets). You can override this behavior in the assetUrlOverride field of your android-index.json. All relative URL's will be resolved from the public-url.

特殊字段

¥Special fields

index.json 文件中的大多数字段与 app.json 中的相同。以下是 index.json 中一些值得注意的字段:

¥Most of the fields in the index.json files are the same as in app.json. Here are some fields that are notable in index.json:

  • revisionIdcommitTimepublishedTime:这些字段由 expo export 生成,用于确定是否应进行更新。

    ¥revisionId, commitTime, publishedTime: These fields are generated by expo export and used to determine whether or not an update should occur.

  • bundleUrl:这指向托管应用包的路径。它们还用于确定是否应该进行更新。

    ¥bundleUrl: This points to the path where the app's bundles are hosted. They are also used to determined whether or not an update should occur.

  • slug:这不应该改变。你的应用的命名空间为 slug,更改此字段将导致 Expo SDK 组件(例如 Filesystem)出现未定义的行为。

    ¥slug: This should not be changed. Your app is namespaced by slug, and changing this field will result in undefined behavior in the Expo SDK components such as Filesystem.

  • assetUrlOverride:托管资源的路径。默认情况下它是 ./assets,它是相对于你最初传入的基本 public-url 值进行解析的。

    ¥assetUrlOverride: The path which assets are hosted from. It is by default ./assets, which is resolved relative to the base public-url value you initially passed in.

Expo 中文网 - 粤ICP备13048890号