尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Nueyaml 实战指南:在 Nue 项目中用“零惊喜“的 YAML 替代品编写可靠配置

Nueyaml 实战指南:在 Nue 项目中用“零惊喜“的 YAML 替代品编写可靠配置 Nueyaml 实战指南在 Nue 项目中用零惊喜的 YAML 替代品编写可靠配置【免费下载链接】nueFastest way to build modern websites项目地址: https://gitcode.com/GitHub_Trending/nu/nue导读Nueyaml 是 Nue 项目中内置的 YAML 简化方言它把标准 YAML 规范中 80 页容易引发歧义的智能推断全部砍掉只保留看起来像字符串就是字符串这一条铁律用于编写站点的site.yaml、app.yaml等复杂配置。读完本文你将理解标准 YAML 的类型推断陷阱、Nueyaml 的完整类型系统与语法规则并能在自己的 Nue 站点中直接写出无引号、无转义、无挪威问题的配置文件。标准 YAML 的问题把配置变成雷区原始 YAML 规范埋藏了一个优雅的想法——用缩进表达层级结构——却在其下堆叠了 80 多页的特性这些特性制造的问题比解决的问题还多。它总是猜测你写的是什么而且经常猜错# 标准 YAML 的意外 country: NO # 可能变成 false挪威问题 time: 12:30 # 可能变成 750分钟 version: 1.10 # 可能变成 1.1浮点数 port: 08080 # 可能变成 4176八进制这些便利把配置文件变成了雷区你只能防御性地给一部分值加引号记住一部分陷阱却记不住全部。配置一直正常运转直到某天悄然出错。Nueyaml 的解决方案只有一条规则Nueyaml 的修复方式简单到只有一条规则可预测。只要在人类眼里像字符串它就是字符串# Nueyaml零意外 country: NO # 字符串 NO time: 12:30 # 字符串 12:30 version: 1.10 # 数字 1.10 port: 08080 # 字符串 08080只有显而易见的数字123、45.67才变成数字只有true和false才变成布尔值其余一切保持字符串。这条规则在源码中体现得极为直接——parseValue 函数 依次只做四件事空值返回null、精确匹配true/false返回布尔、isNumber校验通过的数字返回数字、ISO 日期返回Date其余一律原样返回字符串。而 isNumber 函数 的正则^-?\d(\.\d)?$直接封杀了八进制、十六进制、科学计数法与下划线分隔符——凡是带0前缀或非纯十进制形态的值一律不算数字。简单类型系统只有配置真正需要的类型Nueyaml 只支持你真正需要的类型完整规则见 YAML 语法参考字符串—— 默认类型。不需要引号除非你想用。数字—— 看起来像数字的整数和小数。布尔值—— 只有true和false。没有yes、YES、on或True。日期—— 单一 ISO 格式2024-01-15或2024-01-15T10:30:00Z。Null—— 空值变成null。数组与对象—— 标准 YAML 集合。仅此而已。没有二进制数据、没有集合set、没有有序映射、没有自定义类型、没有挪威问题。只有每个配置文件都需要的那些数据类型。各类型的边界行为在测试中都有明确锁定见 nueyaml.test.jsisNumber(42)、isNumber(3.14)、isNumber(-42)为真而isNumber(00800)、isNumber(hello)为假parseValue(hello)与parseValue(hello)会被去掉外层引号返回hello而parseValue(a quoted word)保持原样。数字的严格边界age: 30 # 整数 price: 19.99 # 小数 count: 0 # 零 negative: -42 # 负整数 scientific: 1.2e3 # 字符串 1.2e3 octal: 0o755 # 字符串 0o755 hex: 0xFF # 字符串 0xFF underscore: 1_000 # 字符串 1_000布尔值的严格边界enabled: true visible: false active: yes # 字符串 yes on: ON # 字符串 ON日期的严格边界created: 2024-01-15 updated: 2024-01-15T10:30:00Z us_date: 01/15/2024 # 字符串 euro_date: 15.01.2024 # 字符串 text_date: Jan 15, 2024 # 字符串语法精要从源码看解析器的真实行为属性名几乎可以包含任何字符解析器寻找:冒号加空格作为键值分隔符因此冒号本身、斜杠、media查询、甚至点号都可以出现在键名中# 含特殊字符的键 /api/users/:id: getUserHandler /api/posts: getPostsHandler media (max-width: 768px): mobile-styles users[0].name: John api:key: secret-value with spaces: allowed关键在分隔符规则对应 detectStructure 中的冒号探测逻辑key:value # 无效 - 冒号后无空格 key: value # 有效 key : value # 有效 - 多余空格可以 complex:key: value # 有效 - 键名中的冒号保留该逻辑由测试用例锁定例如detectStructure([/app/:view:id: baz])会得到键/app/:view:id、值baz见 complex keys 测试。注意Nueyaml 不支持带引号的属性名quoted key: value无效。缩进只用空格自动检测基准缩进必须使用空格行首的 Tab 会直接抛错validateIndentation 抛出Tabs not allowed for indentation. Use spaces only.。解析器从第一个有缩进的行自动检测基准缩进大小默认 2 空格并强制所有缩进层级都是它的整数倍否则报Inconsistent indentation# 有效 - 统一 2 空格 app: name: Test config: debug: true # 有效 - 统一 4 空格 app: name: Test config: debug: true # 无效 - 混合缩进 app: name: Test config: mixed # 错误不是 2 的倍数需要留意的是Tab 出现在字符串值内部是被允许的——validateIndentation 的测试 明确验证了key: value\twith\ttab不会抛错Tab 禁令只针对结构缩进。注释只有前面有空格的#才是注释#用于注释但必须由空白字符引导以免与值中的#冲突# 整行注释 name: John Doe # 行内注释 password: secret#123 # password 中的 # 不是注释 api_key: sk-1234#abcd # 对敏感值安全 valid # comment # 空格前的 # 是注释 no#comment # 无空格# 属于值的一部分 also#not#comment # 多个无空格的 # 全部保留这正是 stripComments 的实现整行以#开头返回空串否则只在匹配到\s#时截断key: value#notcomment这类无空格的#原样保留见 hash in string 测试。多行字符串缩进续行即内容当某个值以更大的缩进在下一行继续时就形成多行字符串description: This is a multi-line string that preserves line breaks exactly as written.结果等价于This is a multi-line\nstring that preserves\nline breaks exactly\nas written.。多行字符串完整保留换行、相对首行的缩进、每行行尾空白以及内容中的空行对应 buildObject 中multiline块的处理分支测试见 multiline and comments 测试。数组行内与块状两种写法# 行内数组 tags: [frontend, javascript, react] numbers: [1, 2, 3] mixed: [hello, 42, true] # 块状数组 tags: - frontend - javascript - react # 对象数组 servers: - name: web-01 ip: 192.168.1.1 - name: web-02 ip: 192.168.1.2行内数组由 parseYAMLArray 处理它要求键名后紧跟:和[所以hey [foo]、hey: [foo]、hey: a [foo]都不会被误判为数组见 array looking value 测试。错误处理带行号的清晰报错解析失败时会给出带行号的明确信息user: name: John age: 30 # 错误Line 3: Inconsistent indentation综合集成测试覆盖了完整链路例如 nested lists 测试 验证了数组项内部嵌套行内数组、注释、多级子数组的解析complex structure 测试 验证了对象与对象数组混排的完整解析。一个完整的真实配置把以上语法组合起来完整示例见 yaml-syntax.md# 应用配置 app: name: My Application version: 1.2.0 debug: false launched: 2024-01-15 # 数据库设置 database: host: localhost port: 5432 credentials: username: admin password: # null留给环境变量 connection_string: postgresql://adminlocalhost:5432/myapp ?ssltruetimeout10 # API 路由 - 键中的特殊字符 /api/users/:id: getUserHandler /api/posts: getPostsHandler /api/auth/login: loginHandler # 特性数组 features: [auth, analytics, caching] experimental: - new-dashboard - dark-mode - websockets # 响应式断点 breakpoints: media (max-width: 768px): mobile media (max-width: 1024px): tablet media (min-width: 1025px): desktop # 多行内容 welcome_message: Welcome to our application! This message spans multiple lines and preserves blank lines and indentation exactly as written. # 服务器清单 servers: - name: web-01 ip: 192.168.1.10 active: true roles: [web, api] - name: web-02 ip: 192.168.1.11 active: false roles: [web]在 Nue 项目中的真实应用Nueyaml 不是孤立玩具而是 Nue 工具链的配置地基。Nuekit 的 conf.js 直接import { parseYAML } from nueyaml来读取站点的site.yaml随后解析出的对象参与mergeConf等合并逻辑asset.js 与 render/svg.js 也分别引入了parseYAML与parseYAMLArray处理资源元数据。仓库内的 blog 模板 site.yaml 就是一份现成的 Nueyaml 配置范本meta: title: Emma Bennet / Design Engineering Blog title_template: %s / Emma Bennet author: Emma Bennet site: origin: https://acme.org view_transitions: true rss: enabled: true title: Acme blog description: Latest news on web development collection: blog design: inline_css: true collections: blog: include: [ posts/ ] require: [ title ] sort: date desc注意include: [ posts/ ]这种行内数组与sort: date desc这类含空格字符串的混用在 Nueyaml 下都无需任何引号防御。完整的新建站点配置方式可参考 site.yaml 说明 与 project-structure.md。FAQ为什么用 YAML配置文件应该为人而写而不是为解析器而写。对比 JSON 与 YAML{ database: { host: localhost, port: 5432, credentials: { username: admin, password: secret123 } } }database: host: localhost port: 5432 credentials: username: admin password: secret123YAML 去掉了语法噪音键不用引号、没有花括号、没有逗号只有像 Python 代码和 Markdown 文档一样的缩进结构。为什么不用 TOMLTOML 遇到嵌套数据会变得冗长[database] host localhost [database.credentials] username admin [[servers]] name web-01 [[servers]] name web-02database: host: localhost credentials: username: admin servers: - name: web-01 - name: web-02TOML 的段标题和点分键反而模糊了结构Nueyaml 用缩进让层级一目了然。为什么不用 JSON5JSON5 依然处处需要引号和逗号{ features: [auth, analytics], api_key: sk-1234 }features: [auth, analytics] api_key: sk-1234JSON5 改进了 JSON却保留了它的仪式感语法Nueyaml 连这些噪音一起消除。与标准 YAML 兼容吗兼容是单向的Nueyaml 是合法的 YAML但不是所有 YAML 文件都是合法的 Nueyaml。它支持有用的子集、拒绝危险的部分。你现有的 YAML 工具可以读取 Nueyaml 文件但 Nueyaml 解析器会拒绝锚点、标签、多文档等复杂 YAML 特性。不支持的完整清单见 yaml-syntax.md 的 Limitations 章节锚点与引用anchor、*reference、合并键: *defaults、标签!!str、多文档分隔---、块标量指示符|、、转义序列\n、替代布尔值yes/on、多日期格式、二进制数据、指令%YAML等。现有 YAML 文件怎么办大多数真实世界的 YAML 文件其实已经遵守 Nueyaml 的约束它们不用锚点、不用标签、不用多种日期格式本质上已经是 Nueyaml 兼容的。规范只是把这种默契正式化。安装与使用Nueyaml 作为独立的 ES Module 包发布见 package.jsontype: module入口为nueyaml.js安装bun install nueyaml解析配置文件import { parseYAML } from nueyaml const config parseYAML(yamlString)运行测试使用仓库自带的 Makefilebun test测试文件 nueyaml.test.js 覆盖了注释剥离、缩进校验、类型解析、数组识别、嵌套结构与报错信息的全部行为是理解解析器边界的最佳入口。结论Nueyaml 的价值不在功能多而在功能少且行为确定。它砍掉了 YAML 规范中所有帮你做决定的智能特性换来的是看一眼就能确定结果的可预测性看起来是字符串就是字符串数字、布尔、日期都有唯一且严格的判定标准。当配置不再需要防御性引号、不再依赖你记住各种类型转换陷阱时复杂配置的编写与审查成本都会被显著压缩——这正是它在 Nue 全栈工具链中被选作配置语言的根本原因。【免费下载链接】nueFastest way to build modern websites项目地址: https://gitcode.com/GitHub_Trending/nu/nue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表