软件更美好未来的要素

还没有读者喜欢这个。
Open source code for a better food system, code with grass image

摄影:Jen Wike Huger

在本次访谈中,我深入探讨了 Kyle Simpson 的生活和动力,他是一位开放网络布道者,也是关于 javascript 的书籍 You Don't Know JS 的作者。在 GitHub 上找到他,并在 Getify.me 上查看他的许多项目和帖子。

你来自哪里?

俄克拉荷马城出生和长大。在俄克拉荷马州开始上学,但现在居住在德克萨斯州奥斯汀——从大学中期开始。我和 我的妻子 和两个孩子住在那里。我搬到奥斯汀是因为 90 年代俄克拉荷马州没有太多的科技社区,而奥斯汀是最近的大型科技中心。现在,我回到俄克拉荷马州探亲,看到他们那里有一个 很棒的社区,我真嫉妒!很高兴看到!

你在哪里上学?

我最初在 俄克拉荷马大学 就读,然后转学到 德克萨斯州立大学 并从那里毕业,获得了计算机科学工程专业的理学学士学位。

你每天的工作是什么样的?

我的一天有两种不同的类型:讲课/教学日和 FOSS 开发日。在教学日,我与社区联系,并通过教授 JS 谋生——主要是在企业研讨会环境或与会议相关的公开研讨会中。那些日子我整天站着,教学、讲课,并带领人们完成练习。

当不在路上做这些事时,我就会参与 FOSS 社区——编写代码,或撰写博客或书籍。我花很多时间做这些事,经常在 GitHub 上提交和拉取请求。我目前在 GitHub 上有一个 300 多天的连胜纪录——不是为了炫耀——而是为了激励其他人为 FOSS 贡献做更多、更规律的事情。如果我的连胜纪录可以鼓励一个人多做一份贡献,那就是它的全部意义所在。

描述它的最佳方式是:我 50% 的时间用于教学以支付账单,50% 的时间捐赠给 FOSS 社区,以围绕 Web 平台及其技术建立意识,其理论是“潮水涨,众船高”。学习和欣赏 Web 技术的人越多,雇用我教他们的人就越多。我是一个对事物充满热情的人,学习的最佳方式是教别人。我思考“我如何让别人理解这一点?”。一旦我学会了某些东西,我就会编写代码来解释它,找到一本书或帖子来描述它,如果我发现有些东西我不理解,就分支出去,学习更多,然后再开始这个循环。它只会变得越来越深入。

我之前说过,“我认为对于开发人员,尤其是那些刚进入行业的人来说,找到 一件 你喜欢学习的东西并掌握它非常重要。” 它可能不是你编写所有其余代码的东西,但 坚持掌握某件事的过程是很有价值的。不要只是从一件事跳到另一件事。虽然这样做你可能会获得不错的薪水,但在深刻理解某件事的艺术中,会缺少一些东西。一旦你完成了,并且你知道了那里有什么需要知道的,那么扩展到尝试其他事物就很棒了!在扩展的同时寻找你想要掌握的下一件事,冲洗并重复。作为“万事通,样样稀松”不断跳槽在 5-10 年前更相关。现在缺少的是 真正 知道自己在做什么的人。

我们的行业目前奖励“灵活性”和迎合他人的想法。“昨天,我们用 Angular 编写了一切,今天,我们将用 React 重写一切...” 在经历了足够多的这种变化后,你“成为”了一名高级开发人员,但你错过了以真正应有的深刻理解来欣赏一项技术的机会。

掌握?如何掌握?

好吧,具体的答案是可变的。Angular 将与 Node 大不相同。总的来说,重要的技能是好奇心和学习的渴望。不要只读一行代码就说,“我想这就是它的工作方式……” 继续阅读,并不断沿着兔子洞深入,直到你可以说你理解了那行代码的每个部分。我告诉我的研讨会参与者,我不期望你们编写自己的框架,但你们 可以。不要将框架视为黑匣子——你需要深入了解它们。如果你选择了一些东西,不仅要了解它是如何工作的,还要了解 为什么。知道 何时 改变来自于理解为什么——而不是因为有一本很棒的书,或者仓库有多少“星”。这些都是糟糕的信号。除了对开源社区的理解之外,你自己的理解是最强的信号。

你不必重新发明轮子,但你应该在决定将轮子螺栓固定在你正在制造的汽车上之前,了解轮子是如何滚动的。

你是如何开始接触 FOSS 的?

我当时在一家公司工作,不是作为开发人员,而是作为“用户体验 (UX) 架构师”。我在项目管理团队中工作,为用户界面 (UI) 制作原型,并将它们交给开发团队。不可避免地,我编写的所有内容都被直接投入生产,或者略作修改。我在 2008 年参与一个项目,该项目需要进行跨域 Ajax 请求,而当时这真的是一件很痛苦的事情。我需要一个解决方案来验证我的应用程序概念,我说,“我懂一些 Flash,我知道它可以做到这一点。” 因此,我围绕一个不可见的 flash 文件构建了一个 JS API 包装器,其 API 与 XMLHttpRequest (Ajax) 对象相同,我将该项目称为 flXHR(基于 flash 的 XHR)。

一旦我让它工作起来,我就想,“也许其他人会觉得它有用?” 所以,我以开源形式发布了我的代码。那时,开源是 GitHub 之前的时代,所以源代码都在我的网站上,我通过博客文章等方式将人们指向它。我也将代码放在 Google Code 上,但那时也没有那么多的社区。2009 年初,我想进入会议领域。2009 年是第一个大型 JavaScript 专用会议 JSConf,所以我决定去演讲关于 SWFObject(当时 Web 上下载次数最多的项目之一),我在 flXHR 中大量使用了它。我是 SWFObject 的核心开发人员,并在会议上做了一个“B 轨道”演讲。只有大约三个人参加了我的第一次演讲,但我爱上了我可以发表演讲以引起人们对开源代码的关注并激励其他人帮助使其变得更好的想法!

我对开源的完整看法是在那一年晚些时候,2009 年 11 月形成的。我发布了我可能最出名的项目:LABjs(一个性能优化的动态脚本加载器)。我在德国柏林的 JSConfEU做了一个关于 脚本加载的演讲。在登台前两个小时,我听到很多人在谈论一个名为 GitHub 的新网站,所以当我在观众席上坐着时,我就去注册了。我把我的所有 LABjs 代码都推送到了那里,那是我的第一个正式的:“我加入了 FOSS 社区”的时刻。

你希望本科生在毕业前接触到什么?

毫无疑问是“Simple Made Easy”,这是 Rich Hickey 的一次会议演讲,他在 Cognitect 公司从事 Datomic 数据库以及 Clojure 语言的开发。他是一位非常杰出的人。这次演讲对我来说非常重要,我不只是把它放在书签中,而是放在我的 工具栏 上,几乎每天都会参考它。它的前提是,人们混淆了两个术语:“简单”和“容易”。他实际上比较了“复杂”与“困难”。复杂一词的词根来自“complected”,就像绳索的股线编织在一起一样。高度编织的代码很复杂,更难维护和重构。软件开发人员在构建时,他们专注于构建“容易”的软件——即易于安装和使用,并且为你做很多事情。这种追求通常会导致复杂的软件。

如果开发人员追求模块化、简单(非复杂)、非编织的软件,他们通常也可以得到容易的软件。如果你追求容易,你通常最终会得到复杂,但如果你追求简单,你也可以实现容易。

Node.js 是我的例子。我试图在虚拟机上安装它,并且满足了操作系统 (OS) 要求,但由于操作系统没有正确版本的 Python 而无法安装它。Node,一个 JavaScript 框架,使用 Python 作为其安装程序?为什么我需要 Python 才能安装 Node??? 答案是因为用 Python 编写跨平台安装程序 更容易……但是当你添加额外的编织时,你也可能使其实现和维护更加复杂。

地球上几乎每个框架都声称是模块化的,但大多数都不是。对我来说,模块化意味着可以删除一个部分,而框架仍然可以被使用。“单独的文件”并不能使框架模块化,如果所有这些部分都是框架工作所必需的!我的目标,我的愿望是,开发人员追求简单的模块化设计,并将其作为最重要的准则。由此而来的是适当的设计,可以使人们易于使用。我们需要停止过多地担心创建漂亮、“容易”的界面,而是更多地担心制作 简单 的软件。

你的工具链是什么?

Sublime 是我的文本编辑器。原则上,我喜欢基于浏览器的编辑,但我运行浏览器的夜间版本,以便尽早发现错误,以便我还有机会修复它们。我无法忍受浏览器崩溃和编写代码时的不确定性。

Sublime 有很多 插件,你可以根据自己的需要使用。虽然我没有使用很多,但其他人喜欢“智能感知”插件,以及他们构建的伟大生态系统中的许多其他插件。

我的其他主要工具是 Firefox 和 Chrome 中的浏览器开发者工具。

我的另一个关键任务工具是 Git 命令行工具。GitHub 是我的图形 git 客户端,因为它有效地增强了我对 git CLI 的使用。

Git。你 如何 使用它?

我没有很多花哨的流程,这取决于我是写书还是编写代码。对于书籍,当我做出更改时,我想编写一个连贯的章节,并为每个章节进行一次提交。在一个章节的写作中,我可能会添加到目录中,或者澄清另一个章节,或者添加另一个章节。每当我有一系列逻辑更改时,我都会 git add 每个单独的文件(以 markdown BTW 编写的文件),并 git commit -m。在提交消息中,我列出提交所描绘的书籍、章节以及关于它的简要描述。书系列的提交历史真正讲述了一个故事,讲述了几个月来我是如何弄清楚如何逐节、逐次重组地编写它们的!

我通常使用 git commit -m ".." && git push,以便我在提交后立即推送。

我不经常进行批量提交,通常只有当我在没有 wifi 的飞机上待了一段时间时才会这样做,在这种情况下,一旦我重新上线,我会一次推送 5-8 次提交。通常,我会在完成我正在处理的章节后立即尝试推送。

对于代码,我有两种不同的策略。如果它是一个“大”功能,我会创建一个功能分支,并将多个提交放入功能分支。目标不是完成功能并进行大规模合并,而是 定期合并。我喜欢以稳定的批次进行开发,定期合并,并且不对 master 造成损害。如果我在开发功能时在 master 上进行了错误修复,我会 rebase 功能分支以获取该修复。我不一定做短生命周期的分支,但我做短生命周期的差异。:)

许多开发人员进行 squash merges,并希望表现得好像“梦想出了这个完美的功能并一次完美地编写出来”。我不想要那样。我想保留历史记录。在极少数情况下,拉取请求中包含许多逻辑上连接的单独提交,我会进行 squash-merge。

在需要进行简单错误修复的情况下,我通常只需添加并直接提交到 master。无论如何,每次我进行最终提交时,我都会提交文档和测试。我坚信,在它有文档和测试之前,它不算 完成。我实际上不做测试驱动开发 (TDD),而是面向测试或测试知情开发。我有一组测试,有时它们是提前编写的,但典型的计划是“我不知道它应该如何表现”当我修复新功能的某些东西时——它需要我通过实现来了解。我与代码一起开发测试——代码 测试——而不是在测试之后或反过来编写代码。

当在别人的项目上工作或作为更大的团队工作时,我更加正式。我尽量避免需要 Git 的复杂 cherry-picking 或交互式 rebasing 功能的情况。在我的职业生涯中,我只做过几次这些事情。我使用 GitHub 进行大多数这些事情,并且它可以很好地处理这些情况。包含 2-3 个提交的拉取请求,无论他们的流程是什么,都是值得保留在历史记录中的东西,所以我通常只是按原样合并它。

你目前在做什么?

除了我的书之外,我还有三个主要的项目兴趣领域,我会在任何给定的星期轮流进行。

最让我感兴趣的是异步(“async”)编程模式(promises 和 generators,诸如此类的东西)。我有一个名为 asynquence 的库,这是一个 promises 风格的异步库。它还可以处理 generators、reactive sequences,甚至 CSP。(参见:Hoare 的 开创性著作“通信顺序进程”),这些更高级别的模式分层在基本的“序列”抽象之上。大多数其他库只有一种异步编程风格,但我构建了一个可以处理所有主要模式的库。我认为 async 是 JS 开发人员需要尽快掌握的最重要的事情之一。我有一些关于这个主题的会议演讲和项目。

我们越来越认识到,复杂的程序需要更完善和更强大的异步功能。仅靠回调真的不够用了。

[Remy Decausemaker:是的,我认为这与 PythonTulipTwisted 中的功能合并到核心库从 Python 3.3 开始 相吻合。]

第二个与 JS 的“编译到”语言类似。实验对于语言很重要。将其推向极致,我有一套工具来定义自定义 JS 语法并将其转译为标准 JS——基本上,标准 JS + 自定义语法。我正在开发可以对你的代码进行“微小”转换的工具。更大的图景是“可逆转换”或能够双向转换的非丢失转换。如果你可以双向定义它们,你可以为自己的编辑器设置一个“视图”,并为团队存储库设置一个“视图”。你检入和检出代码,你可以以 你的 大脑工作的方式处理代码,而团队可以以他们的大脑工作的方式处理代码。

例如,当你使用 CoffeScript 时,它是一种有损转换,并且是“全有或全无”的决定。每个人都需要以这种方式处理它,或者根本不处理。我的工具可以做的简单版本是简单的样式问题,例如空格与制表符。这些工具可以为你更改代码样式,而不是仅仅报错。

ESRE 是我正在构建的用于双向代码样式转换的工具之一。

let-er 是另一个工具,它将非标准版本的 JS 块作用域转译为标准 JS 块作用域。我有一系列正在进行中的这些各种工具的原型,最终我可以回去编写驱动它们的总体“元”工具,并进行双向转换。

第三个是 JS/CSS 之间的交叉。它是一个模板世界中的项目。模板有两种极端:零逻辑模板或全编程语言模板。零逻辑模板包括像 Mustache 这样的项目。我们不希望视图中有业务逻辑,所以我们根本不使用逻辑。但在实践中,这会创建非常脆弱的控制器代码,这些代码与 UI 的结构紧密相连,而这种脆弱的连接正是我们希望通过保持关注点分离来避免的。

另一个极端是,你的模板中有一个完整的编程语言。我的比喻是“如果我给你一堆绳子,我可以教你建造一座绳桥,这很有帮助,或者一个套索,这不太有用。” 如果你处于“15 分钟必须完成功能的紧要关头”,你只会丢入 if 语句和函数调用,然后放一个 TODO 注释来修复它,但然后你很少这样做。这就是我们无意中将业务逻辑泄漏到视图中的方式。

两种极端都不够好。我们需要中间的某种东西,它有足够的逻辑来进行结构化 UI 构建,但排除了所有你可以 滥用 来进行业务逻辑的机制。

4-5 年来,我一直在试验一个快乐的媒介模板引擎,称为 grips。它具有足够的结构逻辑,但受到约束,因此你无法执行诸如函数调用、数学运算等操作。它足够成熟,我可以在我的项目中使用它,并推出了使用它的生产网站。它绝对是一个正在进行中的工作,但它“足够稳定”可以使用。人们肯定仍然会对语法的细枝末节争论不休,并且可能不喜欢我所做的选择。但我认为我至少提出了正确的问题,例如:模板引擎需要或不需要什么?我从一无所有开始,并且仅在结构性任务需要时才添加功能。你有基本的循环和条件,但方式有限。我将这种平衡总结为,“如果你发现自己无法做某事,那应该是一个信号,表明你不需要在模板引擎中使用它。”

两年前,我开始关注 LESSSASS 以及像 COMPASS 这样的其他工具的兴起。让我感到惊讶的是,在解决我认为在 CSS 世界中重要的问题方面,它们的局限性有多大。这些工具要求每次你进行更改时都重新编译 CSS。“编译 HTML 模板,使用外部数据重新渲染”是一个已解决的问题。但出于某种奇怪的原因,CSS 却没有发生这种情况。

所以,我在核心 grips 模板引擎之上发明了 grips-css,一种类似于 LESS 的 CSS 模板语法。grips-css 最重要的是:数据是外部的(即 CSS 变量),这意味着像 SASS 这样的项目正在 CSS 内部 发明声明性语法来处理的所有数据操作,相反,你可以并且应该在 CSS 之外执行这些数据操作,生成新数据,然后只重新渲染模板。

如果我想将“blue”更改为“red”,我不需要重新编译所有 CSS,我可以采用我预编译的 CSS,并仅使用不同的变量数据重新渲染它。

编译后的 CSS 模板是基本的 JS,这意味着你可以选择在浏览器中动态地重新渲染 CSS,例如,使用 CSS 响应不断变化的条件。简单地重新渲染 CSS 代码片段并将其注入到页面中,比使用脆弱的 JS 代码来更改 CSS 样式属性要干净得多。当然,你也可以像当前使用预处理器一样在服务器上运行 grips-css。关键是 grips-css 为你提供了这两种选择,而不是仅限于服务器端和低效的完全重新编译。我试图表明,SASS 和其他工具的目标精神是 好的,但他们 实现 的方式是有限的,并且对 CSS 的未来来说不是特别健康。

我认为 CSS 模板是一种更干净、更健壮的方式来推动 CSS 工具能力向前发展。

你提到了 CSS 中要解决的重要问题?你认为它们是什么?

LESS 中解决了三个主要问题。可变数据,可以更改和重用,结构性的东西,例如 mixins,以实现 DRY 编码。以及 extends,它是多态性的一种轻量级版本,用于覆盖模板的片段。我们需要解决这些问题,他们也做到了,但正如我所说,我们在多年前就解决了文本模板中的这个问题,我们应该将 HTML/文本模板中的相同原则应用于 CSS 世界。CSS 没有理由为这些问题发明自己的解决方案。

那么,接下来是什么?

戴上“预言家帽子”,你认为在未来 3-5 年内我们会看到什么?

应用程序将变得“UI 可选”。新的 Apple Watch 有一个非常有限的显示屏,有些应用程序根本不会显示任何内容。像 Google GlassOculus 这样的设备,你将拥有根本没有任何视觉表示的应用程序。这就是我所说的即将到来的“APIs-as-Apps”时代。你的“应用程序”可能只不过是一段可以发送和接收数据的代码——一个分布式 API。我们有一些公司构建的应用程序 非常 重视品牌。 Twitter 希望你以 他们 希望的方式体验他们的应用程序。 Facebook 希望你以 他们 希望的方式体验 Facebook 应用程序。但现实是,人们将在根本没有你的 UI 的情况下体验应用程序。随着我们的设备以及与设备的交互从纯粹的视觉交互多样化为听觉或触觉交互,公司必须放弃对演示的控制。

我的手表可能会在没有 UI 的情况下向我朗读内容,而这只不过是一个数据操作。Facebook 应该为我的手表提供文本以供阅读。UI 不一定会消失,但它变成了应用程序的可选附加组件。从长远来看,我想强调更多地解耦。我们看到人们正在构建单页、复杂、前端驱动的应用程序。大多数应用程序都在前端。 Gmail 用起来很酷,当然,但我不认为它们在新兴的可选 UI 趋势中非常灵活。将 Gmail 应用程序Gmail UI 分离将很困难。

开发人员正在假设可以无限制地访问快速带宽,并提供每个 retina 图像……我们没有按照我们知道应该的方式分层设计事物。对于所有连接速度较慢的人来说,只是,“嗯,他们最终会获得更好的访问权限。” 我们需要为浏览器中的用户提供工具,以选择对他们重要的内容。我应该能够说,“不,我不需要一个庞大的单页 Gmail 应用程序,我需要一个简单的页面内移动版本。” 这不仅仅是期望一个“移动站点”。我们需要分层站点。

我们需要认真审视我们在多大程度上假设 UI 和数据带宽使用是 无限资源。这可能类似于“响应式 2.0”——响应式不仅适用于屏幕布局,也适用于网络条件。应用程序应该弄清楚我正在漫游,并且不要尽可能多地向我推送所有内容。UI 需要解耦、简化、分层,并且更加关注便携式应用程序。

多年前我听过 PPK (Peter Paul-Koch) 的一次会议演讲。他建议,“为什么我不能发送短信与你分享一个应用程序?为什么你必须从应用商店购买它?” 他提出货币化将从应用程序转向数据。他认为应用程序应该是自包含的便携式代码片段,可以自由共享,而无需考虑设备。JS 非常适合这一点,因为它无处不在。例如,如果 Facebook 想向我收取数据费用,因为我的设备上没有 UI 可以向我投放广告,我应该能够决定是否愿意为我的更新数据付费。

我希望这种事情代表 Web 的未来以及应用程序的使用和消费。

User profile image.
在 Fedora 项目中,Remy 担任社区行动和影响负责人,为发行版的用户和贡献者基础带来更多热度和光芒。

评论已关闭。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.