从这个API能看到整个前端的缩影

网友投稿 198 2023-05-26

大家好,我卡颂。

如果要从JS中找一个API作为整个前端的缩影,ESM规范中的import再合适不过了。

本文我们从这个API出发,来聊聊web的发展。

web的本质是开放

在所有JS​运行时中,web​是最开放的(紧随其后的可能是deno​)。这一点可以从import语法的「模块说明符」窥探一丝端倪。

复制// 模块说明符为 ./a.js import xxx from ./a.js1.2.

在ES规范中只明确「模块说明符是一个字符串字面量」,并没有限制「如何解析模块说明符」,所以「解析模块说明符」的任务就交给了宿主环境。

在web​的HTML规范中,「模块说明符」可以是如下形式:

绝对路径的url,比如:
复制import confetti from https://cdn.skypack.dev/canvas-confetti;1.
以/、./、../开头的相对路径,比如:
复制import xxx from ./a.js1.
定义模块名到url的映射,再以模块名的形式引入,比如:
复制<script type="importmap"> { "imports": { "moment": "/node_modules/moment/src/moment.js" } } </script>1.2.3.4.5.6.7.

再引入模块:

复制import moment from "moment";1.

PS:这种方式被称为import-maps[1],当前浏览器兼容性还不高:

可以发现,这三种方式对「模块说明符」的来源都很开放。反观​​Node.js​​运行时,如果以包名的形式引入模块,比如:

复制import moment from "moment";1.

背后是一套指向node_modules,并最终指向npm库的机制。npm是家私人公司,被github收购,而github被微软收购。

所以,如果某一天国内无法直接安装npm包,也不必惊讶,毕竟他的背后是一家私人公司。

与之相对,web的开放让他不会面临这种囧境。

兼容性的迭代

web​的发展史,就是一部「新三年、旧三年、修修补补又三年」的兼容史。很多API​的兼容性问题可以通过polyfill解决。

所以,很自然的,库作者在面对模块规范的兼容性问题时,也想替用户做到最好。但是,这份努力也让代码行为变得更扑朔迷离。

比如:在ESM​模块中是可以引入CJS​模块的。对于如下CJS模块:

复制// a.js cjs模块 exports.hello = () { console.log(hello) }1.2.3.4.

在同级的ESM模块中引入,并通过解构或者对象方法来使用hello:

复制import utils from ./a.js; const {hello} = utils; // 或者 const hello = utils.hello;1.2.3.4.5.

为什么不能直接以「具名引入」的形式使用hello呢:

复制// 不能这样 import {hello} from ./a.js1.2.

这是因为ESM规范的导入声明都是静态的,而CJS规范的导出是动态的,所以当ESM模块引入CJS模块时,在编译时是没法知道有哪些导出的。

这很符合规范,但看起来有点不符合直觉。

比如,React只提供了CJS规范的包,所以在ESM模块中正确的引入方式是:

复制import React from react; const { useState } = React;1.2.

而大家日常开发显然下面这种方式用的更多:

复制import { useState } from react;1.

之所以这么引入不会报错,是因为库作者(比如vite、babel)在编译时默默做了转换。

为了方便开发者而违背规范,这其实是个很不好的事(类似的事还有npm、yarn的影子依赖)。

但开发者喜闻乐见的API就是好API,整个web的发展就是修修补补螺旋向上的。

bundle将长期存在

在vite横空出世,带来极致的开发时速度后,社区就掀起一股「bundle vs bundleless」的讨论。

既然bundleless能为开发环境带来提速,同样的优势能不能也带到生产环境?或者更极端点,未来前端会逐渐抛弃打包工具么?

从ESM​规范的角度出发,答案是否定的。有两个刚需现阶段bundleless还无法解决:

tree shakingESM模块过多,导致发起大量请求

所以,在未来很长一段时间内,打包工具仍会存在。

总结

在我的技术群中,经常看到新人前端发出感叹:「不知道该学啥」。

究其原因,当前的前端开发,主要是使用「集成了最佳实践的各种大型框架」(比如Nuxt​、Next.js​、UmiJS...)。而这些封装完备的框架为了降低上手门槛,隐藏了大量技术细节。

如果你也有这种迷茫,我建议你从ESM规范开始学起。

他就像一张地图,能够串联起前端的方方面面。

参考资料

[1]import-maps:https://github.com/WICG/import-maps

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java Swing JCheckBox复选框的实现方法
下一篇:APISpace送中秋团圆API好礼
相关文章

 发表评论

暂时没有评论,来抢沙发吧~