- 编程语言
- 编译器
- 云原生
- 语言运行时
【免费下载链接】wing
A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡
本篇指南面向 Wing 项目的贡献者与文档作者,系统讲解如何为 Wing 开源仓库的官方文档(docs 目录)提交更新、在本地启动 Docusaurus 文档网站进行预览,以及如何为 Examples 示例库 新增一个由 Markdown + frontmatter 驱动的社区示例。读完本文,你将掌握pnpm docs本地预览命令的底层原理、示例文件 frontmatter 全字段的含义与取值、如何在代码块中嵌入在线 Playground,以及示例代码如何被自动抽取为测试用例的完整链路。
一、文档仓库结构概览
Wing 的全部官方文档都存放在仓库根目录下的docs目录中,其内部又细分为若干子目录,分别承载不同类型的内容:
docs/by-example/:按主题组织的短小语言示例(如 Hello world、HTTP Server、Json、Structs 等),每个文件就是一个可独立阅读的示例页面;docs/api/:标准库 API 参考(cloud、std、fs、http、math、util 等模块的 Markdown 与.yml定义文件);docs/docs/:概念性文档(预飞行与飞行阶段 preflight/inflight、平台、模拟器、工具等);docs/examples/:社区模式与教程合集,即本文重点讲解的 Examples 示例库;docs/contributing/:面向贡献者的文档(本文即位于docs/contributing/01-start-here/08-docs.md)。
从仓库根目录的 package.json 可以看到,docs脚本被直接挂载为根级 npm/pnpm 命令("docs": "./scripts/docsite.sh"),也就是说文档网站的一切操作都可以从仓库根目录发起。
二、如何更新文档:直接提交 Pull Request
官方文档的主体是纯 Markdown 文件。要提出文档更新,不需要任何额外的构建流程,直接对相应的 Markdown 文件发起 Pull Request 即可:
- 定位到目标文档对应的
.md文件(例如想修改示例库说明就编辑docs/examples/下的文件); - 在分支上完成修改并提交;
- 向 Wing 仓库提交 Pull Request,由维护者评审合并。
文档页面顶部的 frontmatter(如title、id、keywords、custom_edit_url等字段)同时承担了 Docusaurus 侧边栏、SEO 关键词与"在 GitHub 编辑此页"链接的职责。以 docs/by-example/02-hello-world.md 为例,其 frontmatter 就声明了slug: /hello-world、sidebar_label: Hello world与custom_edit_url,这些字段共同决定了页面在文档站点中的路由与导航位置。
三、在本地预览文档网站:pnpm docs的原理与完整流程
在提交 PR 之前,贡献者通常希望先在本地看到文档的真实渲染效果。仓库提供了开箱即用的一行命令:
pnpm docs该命令的实际行为由 scripts/docsite.sh 实现,其核心逻辑如下:
- 克隆/更新 docsite 框架:将 Docusaurus 站点框架仓库
winglang/docsite克隆到~/.winglang-docsite目录(若目录已存在则执行git restore与git pull保持同步); - 符号链接本地文档:将仓库内的
docs目录通过软链接ln -s挂载到 docsite 中的./docs位置,保证文档站点展示的是你本地工作区的最新内容; - 生成版本配置:向 docsite 写入
["current"]版本的versions.json,使站点以"当前版本"模式运行; - 安装依赖并启动:执行
npm i安装 Docusaurus 依赖,最后npm run start启动开发服务器并自动打开浏览器。
从脚本实现(scripts/docsite.sh)可以看出几个实用细节:克隆时使用了--depth=1浅克隆以加快速度;如果克隆失败,脚本会自动清理~/.winglang-docsite并给出明确的错误提示;每次运行时都会先重置 docsite 目录再重新建立软链接,因此不会残留旧的本地内容。
依赖项方面,docs/目录自身是一个独立的@winglang/docs包,其 package.json 中定义了compile脚本(tsx src/generate_examples_files.ts),用于从文档示例代码块生成测试文件——这一点将在后文详细展开。
四、Examples 示例库是什么
docs/examples/是 Wing 的社区模式与教程集合,旨在通过真实可运行的用例帮助开发者理解 Wing。当前仓库中已有以下示例文件:
basic-auth-api.md:基于基本认证的 API 示例;deploy-a-static-website.md:静态网站部署示例;introduction-to-wing.md与introduction-to-preflight-and-inflight.md:交互式入门教程(type为interactive tutorial);processing-messages-in-a-queue.md:队列消息处理模式;quick-share.md:综合演示应用 QuickShare;redis.md:结合 Redis winglib 的缓存写入模式。
这些示例完全由Markdown 文件 + frontmatter 元数据驱动——不需要编写任何站点代码,新增一个示例本质上就是新增一个带有规范 frontmatter 的.md文件。
五、新增一个示例的三步流程
在docs/examples/目录下新增示例非常简单,只需三步:
- 在 docs/examples 目录 下新建一个 Markdown 文件(可以参考已有的
processing-messages-in-a-queue.md); - 在文件的 frontmatter 中填写示例的元信息;
- 在正文中用 Markdown 配以代码片段说明示例的用法与模式。
5.1 frontmatter 字段详解
以仓库中真实的 docs/examples/redis.md 为例,其 frontmatter 完整呈现了示例文件支持的字段:
--- title: "Using Redis with Wing" subtitle: "Example application that uses Redis to set values in a Redis cache" type: - "pattern" platform: - "awscdk" - "sim" language: - "wing" githubURL: "https://github.com/winglang/examples.git" repoDirectory: "examples/redis" coverImage: "/img/examples/redis.png" coverImageInPage: true resources: - label: "Redis winglib" href: "https://github.com/winglang/winglibs/tree/main/redis" - label: "Explore Wing functions" href: "/docs/api/standard-library/cloud/function" authors: - name: "David Boyne" role: "Developer Advocate, Wing" twitter: "https://twitter.com/boyney123" github: "https://github.com/boyney123" cloudResources: - function ---各字段的含义与取值约定如下:
| 字段 | 含义 | 典型取值 |
|---|---|---|
title | 示例页面上展示的标题 | 任意字符串 |
subtitle | 示例页面上展示的副标题/一句话摘要 | 任意字符串 |
type | 示例类型,用于站点分类与筛选 | "pattern"(模式)或"interactive tutorial"(交互式教程) |
platform | 该示例支持编译运行的 Wing 平台 | "awscdk"、"tf-aws"、"sim"的组合 |
language | 示例使用的语言 | "wing"或"typescript" |
githubURL | 示例完整源码所在的仓库地址 | 如https://github.com/winglang/examples.git |
repoDirectory | 源码在仓库中的目录位置 | 如examples/redis |
coverImage | 示例卡片上渲染的封面图路径 | 站点内图片路径,如/img/examples/redis.png |
coverImageInPage | 是否在示例页面正文中展示封面图 | true/false |
resources | 附加的学习资源链接列表,每一项包含label与href | 指向 winglib、API 文档等 |
authors | 作者信息,可包含name、role、twitter、github | 对象数组 |
cloudResources | 示例用到的云资源列表(可选),用于站点按资源过滤 | 如function、queue、bucket、api |
不同字段的组合还能实现更精细的站点行为:例如 docs/examples/deploy-a-static-website.md 额外使用了coverImageOptions按平台(awscdk/tf-aws)指定不同的封面图;交互式教程类示例(如 docs/examples/introduction-to-wing.md)则通过url字段指向站外的在线课程地址。
5.2 编写示例正文
frontmatter 之后就是示例的正文内容。以 redis 示例为例,正文先用文字描述模式,再给出可直接运行的 Wing 代码:
bring redis; bring cloud; // Create a redis resource let redisInstance = new redis.Redis(); new cloud.Function(inflight () => { // Set value in the redis cache redisInstance.set("mykey", "myvalue"); });这段代码演示了一个典型的 preflight/inflight 组合:redis.Redis()与cloud.Function在 preflight 阶段创建资源,而函数内部的inflight闭包则在运行时通过 Redis 的 inflight API 写入缓存值。正文末尾通常还会附上"本示例用到的资源"清单,方便读者跳转查阅对应 API,例如 cloud function 标准库文档。
封面图方面,redis 示例引用了仓库内实际存在的配图 docs/examples/img/examples/redis.png,它直观展示了 Function 模块调用 Redisset操作的架构关系:
5.3 在示例中嵌入在线 Playground
Wing 提供了无需本地安装即可试玩的在线 Playground,开发者可以直接在示例页面中嵌入它。做法非常简单:在代码块的 fence 语言标识中追加playground关键字。
例如 docs/examples/processing-messages-in-a-queue.md 中的代码块声明为```js example playground:
bring cloud; bring util; bring expect; let bucket = new cloud.Bucket(); let queue = new cloud.Queue(); queue.setConsumer(inflight (message) => { bucket.put("wing.txt", "Hello, {message}"); }, timeout: 30s); test "Hello, world!" { queue.push("world!"); let found = util.waitUntil(() => { log("Checking if wing.txt exists"); return bucket.exists("wing.txt"); }); expect.equal(bucket.get("wing.txt"), "Hello, world!"); }同样地,docs/examples/basic-auth-api.md 中的```js example playground代码块展示了完整的自定义BasicAuth类与 API 路由认证逻辑。playground关键字只影响页面渲染(显示为可运行的 Playground 组件),example关键字则与示例的自动化测试机制相关,详见下一节。
六、示例代码如何被自动抽取为测试
Examples 示例并不只是"展示用",其中的代码会被自动抽取成可执行的测试用例。这一机制由 docs/src/generate_examples_files.ts 实现:
findExamples递归扫描文档目录下的所有.md文件;extractExamples通过正则/```.*? example.*?\n([\s\S]*?)```/g提取所有带example关键字标记的代码块,并解析代码块行内可选的 JSON 元数据(如{ "valid": false });generateTestsFromDocExamples将每个代码块写入tests/doc_examples/{valid|invalid}/目录下、以<文件名>_example_<序号>/main.w命名的测试工程中。
在仓库中可以直接看到生成产物,例如 tests/doc_examples/valid/processing-messages-in-a-queue.md_example_1/main.w,其内容正是上一节队列示例代码块,文件头部的注释标注了它的来源示例与元数据。也就是说:只要示例代码块带example关键字,它就会自动进入 Wing 的回归测试集,这既保证了示例代码长期可运行,也要求贡献者在写示例时必须保证代码真实可编译、可执行。
该抽取逻辑由docs包的compile脚本(见 docs/package.json)触发,与根目录的文档预览、CI 测试流程联动。
七、小结:贡献文档的完整工作流
将以上内容串联起来,一位文档贡献者的标准工作流是:
- 在 docs 下定位或新建目标
.md文件; - 若是 Examples 示例,填写规范的 frontmatter(参考 docs/examples/redis.md),在正文中给出带
playground/example关键字的代码块; - 运行
pnpm docs,由 scripts/docsite.sh 拉起本地 Docusaurus 站点,在浏览器中核验页面渲染、frontmatter 展示与 Playground 效果; - 通过
compile脚本(docs/src/generate_examples_files.ts)验证示例代码能被正确抽取为测试用例; - 提交 Pull Request,由维护者评审合并。
通过这套流程,文档既能在本地被真实预览,示例代码又能持续经受自动化测试的检验,从而保证 Wing 官方文档始终与仓库代码保持同步、可读且可信。
- 编程语言
- 编译器
- 云原生
- 语言运行时
【免费下载链接】wing
A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡
相关推荐
Kubernetes Examples 仓库示例贡献指南:从规范制定到高质量示例落地的完整实践
Kubernetes Examples 仓库示例贡献指南:从规范制定到高质量示例落地的完整实践 本文基于本仓库根目录下的 guidelines.md https
示例工程symfony/process文档贡献指南:完善API文档与示例
symfony/process文档贡献指南:完善API文档与示例 symfony/process是一个用于在PHP中执行命令行进程的库,提供简单易用的API,可
后端Quartz.NET 仓库贡献指南:从构建、测试到文档编写的完整工作流
Quartz.NET 仓库贡献指南:从构建、测试到文档编写的完整工作流 本指南围绕 Quartz.NET 开源仓库的 CONTRIBUTING.md https
任务调度后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考