如何用AI技术降噪? QCon 广州“音视频架构实践”专场给你答案! 了解详情
写点什么

ES 模块生产应用经验谈

  • 2020 年 11 月 29 日
  • 本文字数:2348 字

    阅读完需:约 8 分钟

ES模块生产应用经验谈

本文最初发布于 Bryan Braun 的个人博客,遵循创作共用许可,由 InfoQ 中文站翻译并分享。


在过去的一年里,我一直在生产环境中运行一个基于 ES 模块的单页 Web 应用程序。


这是一个 JavaScript 应用程序,但它没有使用 Babel、Webpack、Rollup 或任何其他转译或绑定工具。我在开发中编写的文件与在生产环境中提供给最终用户的文件相同。


该应用程序是一个业余项目…一个在线音乐盒歌曲制作工具。它不是一个大型 App,但也不小——目前有大约 60 个 JavaScript 模块,其中包含了组件、工具和第三方库。其代码库看起来很像 ReactJS 项目,但它没有使用 React。它使用普通的 JavaScript,用原生 JavaScript 特性(如模板字符串)替代像 JSX 这样的抽象。这个框架与本文无关,但如果你感兴趣,可以阅读我之前的文章了解更多内容。


当我在 2019 年 8 月发布这款应用时,业界一致认为在生产中使用非绑定 ES6 模块是一个坏主意。可汗学院尝试解绑其主页的 JS,得出的结论是,这样会减慢他们的初始页面加载速度。那是五年前的事了,我还不知道有谁认真考虑过跳过绑定器在生产环境中使用 ES6 模块*。


这太糟糕了,因为现在浏览器对ES模块的支持已经很好了,似乎我们可以通过编写浏览器能够识别的JavaScript来避免很多无意义的东西(至少对于行得通的项目如此)。


我一直在寻找这样的例子,但很难找到,所以我决定尝试一下,看看这到底有多糟糕。以下是我的发现。

符合预期的方面


开发体验。我期望有良好的开发体验,这方面符合预期。不需要安装,没有启动延迟。不需要监视文件、生成源映射或等待重新编译。只需保存文件并刷新即可。


部署。部署非常简单。我所需要做的就是按原样将代码复制到服务器。我托管在 Web 上的 Netlify 可以很轻松地在 git push 时完成这个任务(不过,公平地说,Netlify 甚至可以使最复杂的设置都很容易部署)。


开发/生产对等。每次我发现一个生产缺陷时,我都能够在本地重现它。这不是主要目标,但很方便。

低于预期的方面


依赖项不支持 ES 模块。我经常发现,我想使用的库不支持 ES 模块。它们通常支持 CommonJS,这意味着我不能使用它们。起初,我通过加载使用浏览器全局变量的库版本(通过脚本标签或副作用导入)来解决这个问题。这种方法有效,但感觉并不理想。


最后,我开始使用Snowpack,它可以导入不支持 ES 模块的依赖项,并生成支持 ES 模块的一次性构建。这种方法非常有效,我已经开始在其他项目中使用它了


环境变量。通常,我会在构建时赋值,但不构建时就不能这样做了。幸运的是,Cory House 有一篇很棒的文章描述了所有的选项。我最后使用了环境嗅探,这感觉有点奇怪,但对我的应用来说终归不是什么大问题。


CSS 的组织。我遵照 BEM 约定使用了传统的 CSS,这很好。不过,我仍然想要分解我的文件,所以我使用了一个main.css文件和一堆@import。这样感觉好多了,但后来我遇到了一个阻塞请求,它导致了页面渲染延迟,所以我将@imports移动到一个内联样式标签中。我不确定我是否喜欢这样,所以我可能会继续改进。


超出预期的方面


缓存失效。我担心我在失效缓存的 CSS 或 JavaScript 时会遇到问题(因为我不能依赖一个绑定器赋予资源的缓存清除文件名)。事实证明,ETags是一个很好的解决方案(特别是我的 Web 主机有一个可靠的实现,既快速又简单)。我听说缓存清除(cache-busting)文件名可以比 Etags 快一点,但在我看来,Netlify 的实现已经相当精炼了。


性能。我所听说的是,ES 模块的性能很糟糕,即使使用 HTTP/2。所以我做好了准备,这很好。我甚至没有做任何优化,除了确保初始 HTML 文件有一些好的默认标记。我觉得它的性能还不错,因为我的应用还没有大到可以碰到瓶颈的程度(这项研究表明,如果你的应用程序没有达到几百个模块,就没问题,这一点似乎已经得到了证实)。这让我意识到,关于什么样的应用才算“太大”,我的直觉错了。在需要一次性加载 300 到 500 个文件之前,你还有很长的路可以走。至少我觉得我的应用不太可能达到这些限制。


我有点担心我的 JavaScript 没有最小化。那不是可以节省大量的字节吗?事实证明,如果你的文件是 gzip 压缩的(或 brotli 压缩的,就像我的情况),那么区别很小。通过重命名变量和删除注释,最小化仍然可以使我的文件更小,但差异比预期的要小。


浏览器支持。由于我没有使用 Babel,我预计会出现很多跨浏览器问题,但这种情况很少**。事实证明,一旦你放弃 IE11 支持,浏览器对现代 JS 特性的支持是非常好的。箭头函数、const/let、模板字符串、ES6 类和fetch等都有超过 95%的全局支持(包括 IE11)。唯一一个我真正想用而又没有使用的 JS 特性是可选链接操作符,而这个特性在未来一两年可能会得到 95%的支持。Evergreen 浏览器是一个功能强大的东西。

总体评价


这让我感到惊喜。如果这是一个传统的绑定式单页应用程序,那么到现在,我需要处理一两个主要工具的升级。取而代之,我可以把重点放在功能上。原生Web技术万岁


如果我的模块数量太多以至于性能开始明显下降,我很有信心使用 Snowpack 来解决它。根据其文档


Snowpack将绑定作为可选的生产优化,这意味着你可以自由跳过绑定的额外复杂性,直到你需要它。你使用绑定器,应该是因为你想这样做,而不是因为你需要这样做。


我喜欢这个延缓复杂性的主意。让人感觉非常灵活。


也许 ES 模块并不适用于每个项目,但它们在我的项目中工作得很好。如果有根本的缺陷,我也还没有发现。


老实说,我现在很难想象用其他方式来构建一个业余项目。


我最近发现了一些其他的 ES 模块实例,包括runpkg.com源代码)和Phillip Walton的博客源代码)。如果你知道其他的例子,请通过电子邮件(bbraun7@gmail.com)告诉我。


更准确地说,我曾遇到过一些跨浏览器的问题,但这不是 Babel 能够帮助我解决的问题。当浏览器实现存在Bug或者你的方法存在根本性缺陷时,Babel 的 polyfill 就没有任何帮助了。


原文链接:


ES modules in production: my experience so far


2020 年 11 月 29 日 17:411016

评论

发布
暂无评论
发现更多内容

四种引用类型在Springboot中的使用

4ye

Java spring 后端 springboot 8月日更

Swift 实现聚光灯动效

fuyoufang

swift 8月日更

fil价格走势分析?fil为什么会大涨?

区块链 分布式存储 IPFS fil价格走势 fil大涨

模块五作业

河马先生

架构实战营

设计微博系统中”微博评论“的高性能高可用计算架构

木云先森

架构训练营

模块五-微博评论“的高性能高可用计算架构

柱林

JavaScript 数组元素的一些操作

HoneyMoose

手撸二叉树之第二小的节点

HelloWorld杰少

数据结构与算法 8月日更

模块五作业 - 微博评论的高性能高可用计算架构

君子意如何

「架构师训练营第 1 期」

20张图带你了解JVM运行时数据区(上)

阿Q说代码

JVM 8月日更 pc寄存器 虚拟机栈 本地方法栈

SpringApplication启动run了啥

Rubble

8月日更

神策数据微信小程序 SDK 架构解析

神策技术社区

大前端 后端 数据 代码 数据采集

LeetCode题解:27. 移除元素,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

架构实战营 模块五 作业

三叔叔_拖延症晚期

HBase 原理、Shell、API读写操作

Mike

百度助力人工智能教育创新:教育部产学合作协同育人项目申报进行中!

百度大脑

人工智能

开发一个分布式IM(即时通信)系统!

小傅哥

Netty DDD 小傅哥 即时通信

【LeetCode】反转字符串中的元音字母Java题解

Albert

算法 LeetCode 8月日更

模块五作业

VE

架构实战营

vue入门:定制自定义指令和过滤器

小鲍侃java

8月日更

从源码角度解析线程池中顶层接口和抽象类

华为云开发者联盟

Java 线程 软件开发 高并发 线程池

模块5作业

脉动

iOS开发:Xcode报错“Could not insert new outlet connection:Could not find any...”问题的解决方法

三掌柜

8月日更 8月

netty系列之:内置的Frame detection

程序那些事

Java Netty 程序那些事

架构实战营 - 模块 5 - 微博评论的高性能高可用计算架构

雪中亮

架构实战营 #架构实战营

模块5 作业

SAKIN

架构训练营模块五作业

喻高咏        

你真的了解二叉树吗?(树形结构基础篇)

有道技术团队

技术 二叉树 网易

老和云起小游

箭上有毒

8月日更

【Flutter 专题】63 图解 Flutter 集成极光 JPush 小结

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 8月日更

JNI 提示

Changing Lin

8月日更

「云智公开课」百度沧海·存储

「云智公开课」百度沧海·存储

ES模块生产应用经验谈_前端_Bryan Braun_InfoQ精选文章