【译】现代Web应用应该是Bundless的

> 译者说明:D2今年分享里有Bundless topic,ppt我已经看过了,准备的非常用心。大家也可以提前感受一下具体内容。这篇文章是dhh写的,极其难翻译,rails 都16年+了,dhh的格局是极好的,值得一看

28d229fddd134518855d3f8cc21d7980.png

我不是很在意把原生JavaScript升级到ES6。尽管从2000年至今,我经历了不同的方法来避免编写太多js代码。首先是RJS(Ruby-to-JavaScript),然后是CoffeeScript。这2种转译方式都为编写浏览器中可执行的JavaScript源码带来了更多快乐。可以说它确实是有效的。

但这显然是恐惧的。当我们等待浏览器来更好理解JavaScript时,它就是一个替代品。虽然有一段时间,它看起来是不会发生的,并且我们永远会嵌入到某些恐惧中!

谢天谢地不是这样的。JavaScript改进了,并且在2015年,一个巨大的进步是ES6最终落地了。继往开来 - Babel转移器让我们可以编写面向未来的JavaScript代码。

这是一个启示。可以让程序员使用更好的JavaScript,而且之前浏览支持也是可用的。它让人感觉有一点欺骗性。就好像我们什么都没有收获一样。尽管,它不是相当正确的。

通过Babel在可怕且复杂的转译管道和工具领域引领潮流。编写更潮的JavaScript代码不再自由。代价就是前所未有的扩大了web的复杂度。很明显这不是终态。

我很感谢像Webpack这样的工具让转译成为可能,尽管很厌恶它带来的复杂度,这还是一笔划算的买卖。所以回到2016年,我创建了 Webpacker, 在2017年,我们发布了Rails 5.2, 这个版本嵌入了这种方式来管理Rails里的JavaScript。

五年后的今天,我们看到的情况已经完全改变了。我不再相信这种方式适合更多的新应用。它不是终态,依然有某些类型应用里它是有意义的(hello react!),但它不再会是Rails应用的好的默认项。

首要改变是ES6现在已经被各大浏览器支持已成为事实。Chrome, Edge, Safari, 和 Firefox都已经完全支持ES6了。最后一个支持是IE11,但是今年也已经支持了。

这意味着我们不再需要一个转移过程将ES6转成在浏览器中可执行的代码。它可以跑的很好,无需任何改变。这是非常成功的。

第二个关键的改变是HTTP2已经是标准。使用HTTP2,你不再为发送许多小文件而烦恼,相反你可以使用一个大文件。单一链接可以多路服用你你需要的所有响应。不再管理多个链接,为多个SSL握手有很大开销。这意味着打包所有文件到一个文件会丢失很多它带来的性能收益 (是的,  tree-shaking就是之中之一)

事实上,现在看单一大bundle模式在很多方式里是很糟糕的,不仅仅是开发者效率(比如打包时长很长!)。当你打包所有的JavaScript到一个单一文件里,任何模块的改变都会导致重新打包。强制浏览器去重新下载一个完整的新文件,所有过程都要重新解析,这实在是糟糕透了。

当你保持每个模块独立,它们会单独过期。如果你20个模块,且只有个变更,这样其他19个模块依然是走缓存的。这对追求性能而使用动态缓存是非常好的。

但更为重要的是我们的全部参数,如果你为了性能不在需要打包,你就可以完完全全的摆脱打包器了!简单的托管每个模块,将它们自身的文件直接跑在浏览器里。

你能想象到我们要做的是什么吗?不需要转译来编写JavaScript,让开发者更快乐,不在打包所有模块,直接使用:不需要任何的JavaScript工具链将你的代码转换成其他。杜绝复杂度。

最后要讲的是推动这2个关键改变的是站在import maps范式上。它们允许ES6模块的逻辑引用(也被称为 ESM),不需要显式的文件引用。显式文件引用的问题在于长周期缓存标准方式使用摘要后的文件名匹配是很糟糕的。

当你看到文件名像main-a6d26cef87d241eba5fa.js,后面这串字符是对整个文件进行摘要获得的。它是某个文件所特有唯一的,所以如果我们改变文件,这个摘要也会变了。这意味着文件不变,我们告诉浏览器一直去通过摘要来缓存文件。如果改变了,它会获得一个新的文件名。这对通过缓存动态过期控制来提升性能是至关重要的。

想象一下,如果你有50个文件都是通过import打开的,使用这样写法"import { Controller } from './javascript/stimulus-a6d26cef87d241eba5fa.js'"那要多么恶心。每次你遇到刺激的依赖问题,你不得不去更新这些文件里的每一个文件,并且这些文件如果你改了,它还需要独立过期。

这个问题的答案是 import maps,它是a feature already shipping in Chrome and Edge 。Firefox已明确表达他们会跟进。Safari还没有吐露口风。但是无所谓的,已有一个完美的可用的兼容补丁,它可以是实现import map,支持所有浏览器支持ESM( 一个补丁里支持所有ES6功能)。

使用import maps,你可以定一个imports映射。所以不需要使用"./javascript/stimulus-a6d26cef87d241eba5fa.js",用"stimulus"即可,import map会表达"stimulus": "/javascript/stimulus-a6d26cef87d241eba5fa.js"。如果你改变了Stimulus,你只需要改变映射关系即可,无需改变引用。以上就是!

手动管理import map依然是有点令人厌烦的,所以对Rails而言,我已经创建了新的 importmap-rails gem,  这个gem可以自动帮你构建映射。包含了shim补丁,所以它是可以在所有浏览器上都正常的。它依赖我们的老的稳定的Sprockets这个asset pipeline 引擎来完成摘要工作。这是一个已经完成的包。

通过这些无转译器或无打包器的进步,匹配到生成的import map, 并且现在你有了一个不再需要本地安装node来创建modern, awesome web apps.

Rails里 Hotwire gems,同时为 Stimulus 和 Turbo而生,已经修改为依赖这些设置。这些gems使用程序访问在对应的场景中设置import map,在你的 application.js里,你可以以这样的方式直接import这些模块。

表达通过裁切复杂度上的肿瘤给开发体验带来的不同是很困难的,感觉就像改进某人状况或前景的机会。但依然有一些未解问题和妥协。

正如提到的,首先是某个流行框架,比如React依赖了JSX的编译,就不会在这个方案上生效(至少目前是这样)。任何需要引用显式转译或编译步骤显然是需要一个转译器或编译器的。之后你又会回到老路上来。

其次是当Hotwire时,结合Rails里的 JavaScript 在某些场景,比如Action Text, Active Storage, 和 Action Cable,可以通过Ruby gems 和 asset pipeline搞定的,拥有一个伟大的JavaScript生态依然是我们需要寻求答案的。

这个生态需要能够发布ESM包,而不是UMD (曾被Nodejs使用的老的包管理系统)包。通过想skypack.dev 这样的服务可以帮助弥补不足,将UMD包转成ESM包。

如果不想通过npm 的package.json文件来完成这个事儿,Rails就需要找到如何依赖和更新这些包的解法。这里讲一些我的想法,但它们还不是那么完善。在过渡期间,你可以简单的下载这些esm包,并将它们保存在本地的vendor/目录下。

所以即使如何承诺,真正跃迁到无处不在的ES6,随着HTTP2普及,和import maps合并横空出世,依然会有典型的应用是需要Webpack (和 Webpacker)的。至少就目前而言,它们是非常好的。我们通过这样的方案向前进步。不是每个人都会采用这样的方案,尽管这些方案将会让他们变得更快乐。

除非新的证据涉及到拒绝本文分析中的的基础原则。Rails 7.0目的是给你一个基于 import maps的默认设置,并让Webpacker变为一个备选方案。

我们在追求一个正确的让前端回归简单的方式。ES6/HTTP2/Import maps看起来会实现的。万岁!


下面是广告时间,最近在弄视频号直播。

662fae96e81d8ae99f74df58aee7e212.png

如果想和狼叔1v1连麦,可以加入知识星球,提前提问,可以更有针对性的回复。

b403cb7d4c83281fe394f05d00549617.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值