写点什么

带您走近 Hyperscript:重新思考 JavaScript

作者:这我可不懂
  • 2023-10-26
    福建
  • 本文字数:3376 字

    阅读完需:约 11 分钟

带您走近Hyperscript:重新思考JavaScript

我们当中一些人也许还记得 HyperCard,这是编程语言进化体系中一个有趣的分支。如果您上了一定的年龄,甚至还可能用 HyperCard 学过编程。Hyperscript 是一种比较新的技术,它具有 HyperCard 的一些优点,特别是它的简洁性和类似英语的语法,并将 HyperCard 运用于浏览器环境。它是一种 JavaScript 替代技术,可以独立使用,也可以结合 HTML 使用,以简化 JavaScript 前端的常见脚本需求。

一个示例胜过千言万语


在我们展开讨论之前,不妨看一个 Hyperscript 示例,它传达了本质:


<div _="init fetch https://stuff as json then put result into me">Using fetch() API...</div>
复制代码


这段代码的作用非常明显。下划线属性是表示 Hyperscript 的特殊属性。在 JavaScript 中,同样的这项功能可能看起来像这样:


<div id="myDiv" onload="async function() {  const response = await fetch('https://stuff', {  headers: { Accept: 'application/json', } });  const data = await response.json();  myDiv.innerHTML = JSON.stringify(data); }"></div>
复制代码


在英语中,它表示:“当 div 元素被加载时,发送一个异步请求到'https://stuff',并将结果放入到 div 中。”但愿您已经明白 Hyperscript 在行为上感觉几乎像是 HTML 的扩展。

Hyperscript 简介


Hyperscript 是一种简化的、更像英语的 JavaScript。您还可以将其视为一种特定领域语言(DSL)。从本质上来讲,Hyperscript 将 JavaScript 简化为一种语法,明确用于满足构建前端 UI 时重复出现的常见需求。它带来了一堆约定,使这种代码编写更简洁。


Hyperscript 是 HTMX 的近亲,出自同一个开发者 Carson Gross 的奇思妙想。这两个项目都反映了 Gross 力求简洁,以及他坚持不懈地将其运用于庞大且活跃的问题空间这一整体思路。在 HTMX 中,我们看到了功能更强大的 HTML,可以消除过去十年中发展起来的复杂性,因为开发人员已经接受了响应式框架+ JSON +类似 REST 的 API 这种前端范式。在 Hyperscript 中,我们看到了 JavaScript 语言复杂性永无止境扩展之外的另一种选择。这是一种诱人的方案。

处理前端复杂性


在生产一线编写代码的前端开发人员肯定有一种不知所措的感觉。谁不想用一种易于记住的表达式语言来取代样板 JavaScript?您只需要凭记忆敲出一些代码,无需引用任何其他,即可执行日常的基本编码。

不妨举一个例子。在下面的 Hyperscript 代码片段中,规范的 button-click-counter 示例变成:


<button _="on click increment :x if :x <= 3 put :x into the next <output/> else put '3 is the max...' into the next <output/> end">Click Me</button><output>--</output>
复制代码


这是使用 React 的同一个示例:


import React from "react";
const Counter = () => { const [x, setX] = React.useState(0);
const handleClick = () => { setX((prevX) => { if (prevX <= 3) { return prevX + 1; } else { return 3; } }); };
return ( <div> <button onClick={handleClick}>Click Me</button> <output>{x}</output> </div> );};
export default Counter;
复制代码


当然,更短小并不意味着更简单。与 React 相比,Hyperscript 的自描述性更明显。现在有人可能会说,React 更复杂,因为功能更强大。它是一种使复杂程序成为现实的语言。但在这里,我们只需看看与 Hyperscript 相比最常见的 JavaScript 前端开发方法(即 React)。我们关注的是可以简化、也应该简化的日常活动。


Hyperscript 的目的在于取代 JavaScript。或许用精细化这个词更合适。Hyperscript 的开发者 Caron Gross 特别指出,这是一个“投机性”的项目。不过,它也是经过深思熟虑、功能强悍又雄心勃勃的项目。你可以想象使用 Hyperscript 的企业级应用程序。


Hyperscript 最大的障碍可能是开发人员普遍熟悉和依赖 JavaScript。当然,它有时会令人困惑和棘手。如果 Hyperscript 真的流行起来,对大多数项目而言,它可能会与 JavaScript 结合使用。

Hyperscript 中的异步事件


不妨看看 Hyperscript 如何处理事件:


<button _="on click send foo to the next <output/>">Send Foo</button><button _="on click trigger bar on the next <output/>">Send Bar</button><output _="on foo put 'I got a foo event!' into me on bar put 'I got a bar event!' into me">No Events Yet...</output>
复制代码


反应式编程是编程史上的一条重要主线,Hyperscript 完全欣然接受了它。在这个示例中,我们可以看到 Hyperscript 如何处理异步事件。事件系统非常强大,包括一系列响应式功能,比如过滤、事件消息对象和队列等。


您还可以看到短语“下一个<输出/>”能够引用 DOM 中的另一个元素,具体是指下一个<输出/>元素,并将事件发送给它。这是一种非常简洁而明显的方式,否则处理起来相当冗长而笨拙,或者至少需要一些响应式连接。这是 Hyperscript 如何有意消除关注点分离的一个例子。

循环、条件和日志记录


在一些前端环境(比如 JSX for React)中,循环可能会很棘手。下面是 Hyperscript 中的循环示例:


for x in [1, 2, 3] index i log i, "is", xend
复制代码


这个例子还让我们看到 Hyperscript 如何处理日志记录。它非常简单,使用逗号分隔的值。


我们已经看到了 Hyperscript 如何处理带有 else 的 if 命令。请注意,它以 End 关键字结束(除非您在脚本的末尾,就像在元素属性上发生的那样):


if :x <= 3 put :x into the next <output/>else put '3 is the max...' into the next <output/>End
复制代码


Hyperscript 还支持 unless 修饰符,它可以引用 CSS 属性:


<button _="on click toggle .bordered on #second-button">Toggle Next Border</button><button id="second-button" _="on click toggle .red unless I match .bordered">Toggle My Background</button>
复制代码


该代码块使第二个按钮改变颜色,除非它有.bordered 类。这是用 CSS 和 HTML 非常简洁地处理了一些原本笨拙的 JavaScript 代码。

行为局部性


灌输给新程序员的原则之一是所谓的关注点分离(SoC)。大多数时候,这个原则是正确的。通过实现 SoC,我们得到了解耦的组件,而这使得系统更具有弹性。然而,还有一股反潮流需要考虑,那就是 Gross 所谓的行为局部性。他在 Hyperscript 中融入了这个想法,您也会在 Tailwind 等其他项目中发现它的身影。


这里的想法是,分离关注点实际上会使系统更难以遵循。前端的关注点分离通常意味着将标记(视图)放在一处,将 JavaScript(行为)放在另一处,将 CSS(表示)放在另外一处。这么做在设计上的好处值得怀疑。SoC 通常在更注重架构的情况下发挥作用。


不过,在基于 HTML、CSS 和 JavaScript 的项目中,必须在上下文之间跳转并始终牢记任务的线程通常很麻烦。这实际上是 JSX 吸引人的地方之一,也是样式组件(Styled Components)框架背后的动因。

违反关注点分离


Hyperscript 拿来您会提取到 JavaScript 中的大量繁琐工作,将其包装在 Hyperscript 语法中,因此您可以将相当复杂的功能直接内联到标记中。这样一来,就很容易将内容放在一起,并使它们更具自文档性。


缺点是,如果需要改变内置语法之外的行为,可能会有问题。换句话说,如果您需要直接可以操作,会发现强耦合组件依赖 Hyperscript 引擎本身,您必须对其进行修改。


我没有在一个大型的真实项目中使用过 Hyperscript,所以没法直接表态。然而,该语言支持可扩展性。

还可以并行运行 JavaScript 和 Hyperscript,这样就给了您逐步改进的余地。对我来说,这也提出了一个问题:在 React、Svelte 或 Vue 项目中并行运行这些语言会是什么情况。

结论


当我开始使用 Hyperscript 时,极其怀疑。然而,我逐渐被 Hypserscript 的感觉所吸引。我认为它会很快取代 JavaScript 吗?不会,我不这么认为。但是我可以设想 HTMX 和 Hyperscript 极大地简化 JavaScript 前端的场景。


这种竭力追求一种更简单的编程范式的做法,我称之为应用常识(applied common sense)。通过质疑假设并将我们学到的一切推倒重来,也许我们就能构建更好的工具。


我们知道的一件事是,复杂性扼杀了软件的创造力和生产力。作为工程师,我们永远面临在抽象中构建的风险,这是复杂性的最后一根稻草——它会扼杀我们的项目。


有时候我们接触某项技术只是因为我们就喜欢它,这种工具随之有了自己的生命。React 等工具变成了产品。这在某些情况下是可以的,但在其他情况下,像 Hypserscript 这样更简单的替代方法可能更好。


至少,Hyperscript 有新的想法可以贡献。像 HTMX 一样,这种语言有助于改善在互联网上进行开发的整体体验。

发布于: 刚刚阅读数: 4
用户头像

低代码技术追随者,为全民开发而努力 2023-02-15 加入

大家好,我是老王,专注于分享低代码图文知识,感兴趣的伙伴就请关注我吧!

评论

发布
暂无评论
带您走近Hyperscript:重新思考JavaScript_JavaScript_这我可不懂_InfoQ写作社区