应用制作

最后更新:2026年7月3日

要将自己制作的 Web 应用作为 Market App 上架到应用市场,首先需要构建应用并准备好其产物。这个过程包括用 HTML 与 JavaScript 构建静态站点,以及在命令行中检查构建产物。

Market App 是上架到应用市场后可安装到其他 Space 的应用。其形态与 Web Hosting 相同,是静态 Web 应用。只要把预先构建好的界面文件集合上传,访问者进入时就会原样看到这些界面。

它与普通 Web 应用有一处不同,因此在构建时多出一条必须遵守的规则。本页讲解这处差异、相应规则,以及上架前的验证。

安装后资源会复制到安装者的 Space

安装 Market App 时,不仅是应用界面,连同发布时一起选择的资源(Content TypeContentMedia 等)也会复制到安装者的 Space。假设你制作了一个服装店商品目录应用并上架。当有人安装该应用时,应用界面会连同商品 Content Type 与商品 Content 一起被复制进那个人的 Space

被复制的资源会在安装它的 Space 中获得新的标识符。用于读取内容的 Delivery Access Token 也会在安装的 Space 中重新创建。因此安装后的应用读取的并不是制作者的 Space,而是复制到安装者 Space 中的自己的副本。安装完成后,该应用仅凭安装 Space 的资源运行。

为什么要把访问信息固化进构建产物

安装后的 Market App 没有服务器。 它与 Web Hosting 一样是静态托管,没有为每个请求计算界面的服务器运行时,内容是由浏览器直接调用 WEEGLOO 的传递 API(CDA,Content Delivery API)来获取的。因此,构建产物(界面文件)内部必须以文字写明从哪个 Space 读取什么、用什么凭据读取

问题在于,正如前面所讲,安装后资源会以新的标识符被复制。构建文件中写入的值是制作者 Space 的标识符与令牌,而在安装处需要读取的是新复制出来的副本。如果原样保留旧值,应用就会指向错误的地方。

因此 WEEGLOO 在安装时会代为替换这些值。 发布时会预先找出制作者 Space 的标识符、令牌、资源标识符在构建文本中写在何处,安装时则把这些位置替换为安装 Space 副本的新值。借此,安装后的应用会自动指向安装的 Space

这一替换只对随应用一同打包的资源发生。所以界面读取的资源(Content TypeDelivery Access Token 等)在发布时必须毫无遗漏地一并打包。一旦遗漏,那个标识符就不会被替换,在安装处会留下错误的值。需要一并打包哪些内容,将在应用发布的资源选择中讲解。

这种自动替换有一个前提:值必须以一个完整的字符串原样存在于构建文本中。因为发布阶段会逐字查找该字符串并记录其位置。如果把值拆开、在运行时动态生成、或从外部获取,发布阶段就找不到它,那么安装时也不会发生替换,安装后的应用便无法运行。

固化进构建产物(并在安装时被替换)的值有三个。

  • 原始 Spacesys.id(spaceId):从哪个 Space 读取。
  • 原始 SpaceDelivery Access Token:可读取该 Space 已发布内容的只读凭据。
  • 应用所引用资源的 sys.id:例如装载商品的 Content Typesys.id 等,客户端代码所指向的资源标识符。

将值以字面量形式内联

关键在于,上述三个值必须以一个完整的字符串字面量(intact literal substring)出现在构建产物中。打开构建出的文本文件(JS、HTML、JSON 等)时,值应当没有被拆分或变形,原样呈现为一整块。只有这样,发布阶段才能找到该值并记录位置,安装阶段才能把该位置替换为新值。

下面是放在客户端代码中的配置示例。其中的值只用于展示格式,需要替换为实际的凭据。

// weegloo.config.js: 这些值会原样写入构建产物
export const WEEGLOO = {
  spaceId: "spc_xxxxxxxxxxxxxxxx",                 // 原始 Space 的 sys.id
  deliveryAccessToken: "dat_xxxxxxxxxxxxxxxxxxxx",  // 原始 Space 的 Delivery Access Token
  productContentTypeId: "ct_xxxxxxxxxxxx",          // 应用读取的 Content Type 的 sys.id
};

浏览器用这些值直接调用 CDA。

fetch(`https://cda.weegloo.com/v1/spaces/${WEEGLOO.spaceId}/contents`, {
  headers: { Authorization: `Bearer ${WEEGLOO.deliveryAccessToken}` },
});

以下做法不可使用。 它们都会让值无法以完整字面量留在构建产物中,使发布阶段找不到值。那样一来,安装时就不会发生替换,安装后的应用便读不到自己 Space 的副本。

  • 运行时查询环境变量。 安装后的应用没有可注入值的服务器或运行时环境,值也不会以文字留在构建文本中。

    // 不可用: 安装处不存在这个环境变量
    deliveryAccessToken: process.env.DELIVERY_ACCESS_TOKEN
  • 在运行时通过 fetch 获取。 如果让值从某处获取而来,构建文本中就不会留下值,也没有可获取的地方。

  • 用字符串拼接拆分。 值不会以一整块出现,发布阶段无法找到。

    // 不可用: 产物中不会留下 "dat_xxxxxxxxxxxxxxxxxxxx" 这一个完整 substring
    deliveryAccessToken: "dat_" + "xxxxxxxxxxxxxxxxxxxx"
  • 留作占位符或留空。 填入值的工作由 WEEGLOO 在安装时完成。但那种替换是查找固化在构建中的实际值并替换其位置,因此若留作空白或临时标记,就没有可查找的值,也就无法成为替换对象。在生成构建产物的时刻,实际的值必须以文字原样存在。

值务必放在文本文件(JS、HTML、JSON 等)中。不要放进图像、字体等二进制文件。查找并替换值的工作只在文本文件中发生。

打包工具(bundler)也是检查对象。部分打包工具会在优化过程中拆分或变形字符串字面量。不要只看源代码就放心,请打开实际的构建产物确认值是否仍以完整字面量留存(见下一节)。

令牌以最小权限发放

固化进构建的 Delivery Access Token 会原样暴露在浏览器中。安装的任何人都能从应用的构建文件中看到这个值(安装后在那个 Space 中重新创建的令牌同样会被暴露)。因此,这个令牌必须以只能读取应用实际需要读取的 Content Type最小权限 SpaceRole 来发放。不要用 Administrator 角色发放。 一旦管理员权限的令牌暴露在浏览器中,原始 Space 的全部内容都会陷入危险。

创建最小权限 SpaceRole 并用该角色发放 Delivery Access Token 的方法,将在令牌中讲解。

发布前的验证

上架前,请不要凭记忆,而要在实际的构建产物中确认值是否正确写入。在构建出的文件夹中分别对原始 spaceId、令牌、资源 sys.id 执行 grep,看它们是否以完整字面量出现。

grep -r "DATxxxxxxxxxxxxxxxx" dist/

只要要查找的值在构建产物中以一整块(未被拆分或变形)出现即可。请对固化的三个值(spaceId、Delivery Access Token、被引用资源的 sys.id)都进行确认。其中只要有一个无法被 grep 命中,发布阶段也找不到该值,安装时便不会被替换(要么是打包工具变形了值,要么是被运行时查询漏掉了)。这种情况下,请参考前面的“将值以字面量形式内联”,将值修正为以完整字面量留存。

静态构建限制

Market App 的构建产物遵循与 Web Hosting 相同的静态限制。

  • 没有服务器运行时。必须以静态导出(static export)方式构建(无 SSR)。
  • 解压后文件须在 100 个以内。
  • 文件集合的最上层(根目录)须有 index.html
  • WEEGLOO API(CDA 等)的调用由浏览器直接进行。

更详细的静态限制与文件打包规则,将在网站部署中讲解。

构建出的界面会装入 App Bundle

通过验证的构建产物会在发布时装入 App Bundle(按版本打包应用的集合包)。在发布界面一同选择的资源也会装入同一个集合包,安装时复制到安装者的 Space。发布并提升版本的步骤,将在应用发布中讲解。

如果应用接收自有会员

到此为止讲的都是用 CDA 读取任何人都可阅读的公开内容的情形。如果应用接收自有的会员注册与登录,则使用 ServiceLogin官方客户端 SDK。这种情况下,浏览器调用的不是 CDA,而是用会员的令牌调用 ACDA(App Content Delivery API)。配置与对接方法将在服务会员登录中讲解。

安装后 Market App 的认证方式由 App Auth 负责,对安装后应用拥有访问权限的用户由 App Member 负责。

下一步要做的事

  • 应用发布:讲解将制作好的应用(App Bundle)上架到应用市场的内容工作室步骤。
  • 网站部署:讲解静态构建、100 个文件上限、index.html 置于根目录等 Web Hosting 的基础。
  • 令牌:讲解如何用最小权限 SpaceRole 发放要内联进构建的 Delivery Access Token
  • API 参考:讲解应用界面加载内容时调用的 CDA(传递 API),以及接收自有会员的应用所用 ACDA 的请求格式等技术规格。