2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家
由克劳德撰写,布莱恩·麦克利审核
太长不看版:JavaScript 并非为当今的浏览器而构建。scrml 是。
我是犹他州东北部一家小型货运公司的部分所有者,业务主要涉及石油和天然气。我驾驶其中一辆卡车。我也进行编程。虽非职业程序员,但我热爱解决难题。我并非经验丰富的框架开发者。如果必须的话,我能勉强使用 React。我曾花费大量时间思考,一种专为浏览器设计的语言究竟应该是什么样子。起初是在脑海中构思,随后落在纸面和白板上,接着经历了大约二十次编译器尝试,直到当前的版本开始趋于成熟。
浏览器具有形态
当你着手编写浏览器应用程序时,你就承诺要处理一组特定的事物。响应式状态。服务器边界。结构化查询语言。作用域样式。表单。WebSocket。工作线程。路由。身份验证。验证。
JavaScript 并非为这些任何一项而设计。JavaScript 只是 1995 年那种带表单的网页的脚本语言。浏览器成长了,但该语言没有。
因此,生态系统围绕该语言发展起来。React 用于组件。Redux 或 Zustand 用于状态管理。React-router 用于路由。Prisma 或 Drizzle 用于结构化查询语言。Zod 用于验证。Styled-components 或 Tailwind 用于样式。Socket.IO 用于套接字通信。Vite 用于构建。每一个都是一个库,将浏览器形态的一部分修补到并未对其建模的语言上。这些库之间的接缝处正是大多数错误藏身之所。编译器无法掌控全局,因为该语言并未对全局进行建模。
这就是差距。本文其余部分讲述的是,当语言对全局进行建模时,这些差距如何被填补。
浏览器语言应掌控的六件事
1. 状态作为一种类型
在大多数框架中,状态存在于钩子或绑定中(useState、ref、createSignal),每个都有你必须遵循的规则:每次渲染都以相同的方式调用它,不要将其放在条件语句中,遵循依赖跟踪约定。这些规则并非由语言强制执行。你只有通过碰壁才能学会它们。
如果状态是一种类型会怎样?<input> 已经是一种状态。它有一个值,随时间变化,用户与其交互。让用户定义的状态以同样的方式工作。<Card> 声明一种状态类型。<Card> 实例化一个状态。@count 是响应式的;编译器通过 fn 签名、通过 match 分支、跨越服务器边界来跟踪响应性。那些框架在运行时捕获、或者永远无法捕获的错误,在这里变成了编译错误。“输入元素是一种状态”与“用户定义的 Card 是一种状态”之间不存在概念上的差距。
2. 将服务器边界作为类型系统问题
在框架领域,代码在哪里运行是你需要记住的问题。编译器无法提供帮助。
将函数标记为 server fn,编译器就会完成剩余工作。它将该函数触及的所有内容划分为仅限服务器端,生成路由,在客户端生成 fetch 存根,如果你试图在客户端读取仅限服务器端的 @var,则会导致编译失败。你不再需要编写应用程序接口路由。你不再需要编写 fetch 包装器。你不再需要记住哪个文件在哪里运行。
3. 将结构化查询语言作为原生特性
对象关系映射工具很有吸引力,因为 JavaScript 中围绕结构化查询语言字符串的噪音确实存在。但对象关系映射工具是用一种噪音换取另一种噪音:近似结构化查询语言但绝非真正的结构化查询语言的查询领域特定语言;与你的数据库不同步的模式文件;当生成的查询与实时模式不匹配时出现的运行时错误。
如果编译器掌控结构化查询语言块,你就不需
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。