---
title: 三方 CDN 资源使用
summary: "介绍如何接入三方 CDN，通过 cdnImage.json 配置多区域 CDN 地址映射以减少包体积。"
tags: [三方CDN配置, 外部CDN接入, 多区域cdnImage.json, getCdnUrl]
questions:
  - 使用三方 CDN 功能有哪些版本要求？
  - 如何配置 cdnImage.json 文件实现多区域 CDN 地址映射？
  - getCdnUrl 方法如何使用？
  - 三方 CDN 支持哪些区域标识？
  - 三方 CDN 和涂鸦 CDN 可以同时使用吗？
  - 当某个区域的 CDN 地址不存在时会如何处理？
  - 如何在 React 组件中使用 CDN 资源？
---

## 三方 CDN 资源使用

### 版本限制

- 基础库版本需 `>=2.26.0`
- @ray-js/ray 版本需 `>=1.6.10`
- 开发者工具版本需 `>=0.8.4`
- **不可与涂鸦 CDN 功能同时使用**

### 功能描述

为了减少小程序包体积，Ray 提供了 CDN 资源使用功能。开发者可以将项目中的静态资源(如图片、音频等)上传到 CDN，运行时会自动替换为对应的 CDN 地址。

### 上传 CDN

开发者需要自行选择 CDN 服务商并上传资源。以下是一些主流的 CDN 服务商供参考：

- [腾讯云 CDN](https://cloud.tencent.com/product/cdn)
- [阿里云 CDN](https://www.aliyun.com/product/cdn)
- [AWS CloudFront](https://aws.amazon.com/cn/cloudfront/)
- [Cloudflare CDN](https://www.cloudflare.com/cdn/)

### 配置 CDN

在项目中增加, 并增加一份 `cdnImage.json` 文件, 参考如下目录结构：

```
├── package.json
├── project.tuya.json
└── src
    └── cdn
        └──cdnImage.json
```

`cdnImage.json` 需要配置每个区域对应的 CDN 地址，例如：

需配置的多区标识：

- AY：中国区
- AZ：美国区
- EU：欧洲区
- IN：印度区
- UE：美东
- WE：西欧
- RU：俄罗斯

```json
{
  // 中国区
  "AY": {
    "/cdn/logo.png": "https://images.tuyacn.com/smart/miniapp/static/1664528993779f7997c9a.png",
    "/cdn/1.png": "https://images.tuyacn.com/smart/miniapp/static/1670384599c63a79781fd.png"
  },
  // 美国区
  "AZ": {
    "/cdn/logo.png": "https://usimagesd1448c85ulz2o4.cdn5th.com/smart/miniapp/static/1664528993779f7997c9a.png",
    "/cdn/1.png": "https://usimagesd1448c85ulz2o4.cdn5th.com/smart/miniapp/static/1670384599c63a79781fd.png"
  },
  // 欧洲区
  "EU": {
    "/cdn/logo.png": "https://euimagesd2h2yqnfpu4gl5.cdn5th.com/smart/miniapp/static/1664528993779f7997c9a.png",
    "/cdn/1.png": "https://euimagesd2h2yqnfpu4gl5.cdn5th.com/smart/miniapp/static/1670384599c63a79781fd.png"
  },
  // 印度区
  "IN": {
    "/cdn/logo.png": "https://inimagesd1jqokb9wptk2t.cdn5th.com/smart/miniapp/static/1664528993779f7997c9a.png",
    "/cdn/1.png": "https://inimagesd1jqokb9wptk2t.cdn5th.com/smart/miniapp/static/1670384599c63a79781fd.png"
  },
  // 美东
  "UE": {
    "/cdn/logo.png": "https://usimagesd1448c85ulz2o4.cdn5th.com/smart/miniapp/static/1664528993779f7997c9a.png",
    "/cdn/1.png": "https://usimagesd1448c85ulz2o4.cdn5th.com/smart/miniapp/static/1670384599c63a79781fd.png"
  },
  // 西欧
  "WE": {
    "/cdn/logo.png": "https://d2h2yqnfpu4gl5.cdn5th.com/smart/miniapp/static/1664528993779f7997c9a.png",
    "/cdn/1.png": "https://d2h2yqnfpu4gl5.cdn5th.com/smart/miniapp/static/1670384599c63a79781fd.png"
  },
  // 俄罗斯
  "RU": {
    "/cdn/logo.png": "https://euimagesd2h2yqnfpu4gl5.cdn5th.com/smart/miniapp/static/1664528993779f7997c9a.png",
    "/cdn/1.png": "https://euimagesd2h2yqnfpu4gl5.cdn5th.com/smart/miniapp/static/1670384599c63a79781fd.png"
  }
}
```

**注意：**

1.  上述配置的 CDN 地址，需要与上传的 CDN 地址一致，否则会导致 CDN 资源替换失败。
2.  欧洲区（EU）的 CDN 地址为兜底地址，当其他区域 CDN 地址不存在时，会使用欧洲区的 CDN 地址。

### 项目中使用

ray 提供了 `getCdnUrl` 方法，你可以图片会根据当前区域自动替换为对应的 CDN 地址。

```tsx
import { getCdnUrl } from '@ray-js/ray'
import React from 'react'
import { Image, View, Text } from '@ray-js/ray'
import cdnImage from '@/cdn/cdnImage.json'

const imageStyles = {
  base: {
    display: 'block',
  },
  logo: {
    width: 100,
    height: 100,
    marginBottom: 20,
    borderRadius: 8,
    boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
  },
  banner: {
    width: 200,
    height: 200,
    borderRadius: 12,
    boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
    border: '1px solid #eee',
  },
}

export default function Home() {
  // 预先处理CDN URL,避免重复调用
  const logoUrl = getCdnUrl('/cdn/logo.png', cdnImage)
  const bannerUrl = getCdnUrl('/cdn/1.png', cdnImage)

  return (
    <View>
      <Text>Hello CDN</Text>
      <Image src={logoUrl} style={{ ...imageStyles.base, ...imageStyles.logo }} />
      <Image src={bannerUrl} style={{ ...imageStyles.base, ...imageStyles.banner }} />
    </View>
  )
}
```
