最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 混乱是进步的阶梯 —— ESM规范的崛起【上】

    正文概述 掘金(魔术师卡颂)   2021-04-23   612

    前言

    前端发展到如今,社区生态已经非常丰富。

    在无数开源大神的努力下,很多前端开发的痛点(比如静态类型检查浏览器兼容性)早已有了事实上的标准解决方案(比如TSbabel)。

    然而,在这繁荣之下,有一个日常开发不易感知的问题:

    你可曾遇到过莫名其妙的bug,在多方搜资源,反复验证,耗费数个小时终于发现:

    原来是某个包导出的是CJS,而项目使用ESM导致。

    比如这个例子:记一次打包压缩报错

    如果你觉得这是个很容易发现的问题,再考虑结合上node_modules的层层依赖呢?

    这个问题,揭开了模块化规范间斗争与博弈的冰山一角。

    作为现代前端工程化的基石,模块化规范有太多值得深究的内容。

    我会花几篇文章来讲解模块化规范。本文是第一篇,会围绕模块化规范的演进展开。

    正文

    如果问十年前的前端最头疼的是什么?一定是浏览器兼容性。

    随着babel等编译工具出现,兼容性逐渐被工程化方案解决(ES6+编译为ES5)。

    不仅是兼容性问题,DSL(如JSXVUE的模版语法)、代码压缩代码静态检查(TS)等日常开发的刚需都能在工程化方案中找到解决办法。

    如果将当今繁荣的前端工程化生态比喻为一座大厦,那大厦的地基一定是模块化规范

    现代JS代码都是基于模块化规范组织起来,让我们从下往上来看看这座大厦:

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    规范的实现依赖于宿主环境,比如浏览器环境实现了EcmaScript Module(后文简称ESM)规范。

    Node v12之前支持CommonJS(后文简称CJS)规范,12之后同时支持CJSESM

    宿主环境之上,是基于模块化规范实现的工具集,比如webpackviteVScode生态。

    再往上,基于工具集提供的API,可以实现各种工程化工具。比如:

    • webpack loader

    • VScode plugin

    • babel plugin

    再往上,就是开发者自己编写的业务代码。

    开发者只需要在工具集中配置好工具,就能为业务代码提供服务。比如:

    • VScode(工具集)中配置eslint(工具),就能在开发时获得相应提示

    • webpack(工具集)中配置babel loader(工具),就能在开发时使用ES6+语法

    可见,理想状态下,在开发者视角是不需要关注底层的模块化规范实现的。

    规范之争

    然而,事物是动态发展的,模块化规范也不是一蹴而就的,让我们回到09年。

    美国程序员Ryan Dahl创造了node.js项目,将JS用于服务端开发。

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    node.js使用CJS标准作为模块化规范。

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    有了服务端模块规范(CJS),很自然的,JS开发者们想为客户端(主要是浏览器)提供一种模块化规范。

    然而CJS是为服务端设计的。

    在服务端,IO操作通常能迅速完成,所以CJS规范定义的:

    这个流程是作为一个整体同步执行的。

    然而在浏览器环境,模块加载(即数据请求)通常很耗时。有人曾作出一个形象的比喻:

    如果一个CPU周期话费1秒完成,那么文件的网络请求需要话费4年。

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    显然浏览器端需要一种支持异步的模块化规范。

    AMD(Asynchronous Module Definition 异步模块定义)规范,就是这样需求背景下的产物。

    然而这些社区提出的规范终究只是为了解决一时的需求,随着历史的发展,新的模块化规范不断涌入、消亡。

    直到ESM规范被提出。

    ESM规范是ES标准的模块化规范,他的早期讨论可以追溯到2019年。

    ESM将模块规范分为三个阶段:

    其中模块加载由宿主环境提供的loader完成(比如在浏览器环境,loader的行为由HTML规范定义)。

    模块实例化模块执行ESM规范定义执行流程。

    区别于CJS规范的同步执行,ESM规范将流程拆解为3个独立阶段。

    模块加载同步、异步与否由宿主环境决定。

    支持不同宿主环境,抹平多端差异、能力比其他规范都强大(后文会介绍)、再加上血统纯正(ES官方提出),

    使得ESM规范一统前端看似指日可待。

    然而,此时社区已经有大量基于CJS规范产出的开源包、组件,他们无法立刻切换到ESM规范。

    所以,JS生态的现状是:会处于、并将长期处于CJS规范的库与ESM规范的库共存的状态。

    但是最终,ESM规范一定会成为主导,毕竟他的优点太多(同样,后文会介绍)。

    规范割裂带来的机会

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    当前模块化规范的混乱,对开源大佬们来说,就是机会。

    为了让开发者将更多精力放在业务,而不是模块规范的适配上。

    很多开源工具集都试图抹平模块化差异,比如:

    • babel中使用babel-plugin-transform-commonjs可以将CJS规范的代码转换为ESM规范

    • 为了一刀切解决当前ESMCJS、浏览器script标签导入这3种规范互相不兼容的情况,提出了兼容三者格式的UMD(Universal Module Definition)规范

    一些工具集利用模块化规范的不同与其他竞品形成差异化竞争,比如:

    • browserify这款打包工具的卖点是:使用CJS规范打包,使一份代码同时在Node环境与浏览器环境(打包后)执行。

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    其中,在浏览器环境中,Node的一些核心库(如events、stream、path...)会被打包成浏览器支持的版本。

    • ViteDEV环境使用ESM规范构建模块间的依赖关系。

    依赖于大部分现代浏览器原生支持ESM规范,省去了打包的过程,使其编译速度大大提升。

    • rollup原生对ESM提供更多支持。

    严格支持ESM规范,并提供更好的静态分析,使rollup一度提供性能更优异的treeShaking能力。

    成为更多打包工具的首选。

    webpack这样的的大而全方案形成差异竞争。

    规范割裂带来的痛

    可以看到,由于底层宿主环境对模块化规范支持的割裂,需要上层工具集来抹平模块规范的差异。

    设想一个同时使用了webpackbabelTS的项目。

    这3个工具集都对多种模块规范有兼容处理。比如:

    单独使用babel时,对于如下代码:

    import a from 'lib';
    console.log(a);
    

    会被babel编译为:

    "use strict";
    
    var _lib = _interopRequireDefault(require("lib"));
    
    function _interopRequireDefault(obj) {
      return obj && obj.__esModule ? obj : { default: obj };
    }
    
    console.log(_lib.default);
    

    ESM默认导出会被编译为包含default属性的对象。

    当多个工具集在同一个项目中,为了各自目的做着同一件事(抹平模块化规范差异),

    一旦工具链中某个插件配置有一丝丝不符合预期,或者引入了一个不符合预期的包,那么艰难的debug就此开始了......

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    曙光

    即使当前有诸多不便,历史的进程是无法阻止的,那些被历史巨轮甩下并碾碎的模块化规范,会逐渐消失在开发者的视野中。

    混乱是进步的阶梯 —— ESM规范的崛起【上】

    而赢家注定会通吃。

    为什么ESM注定会成为最大赢家?他有什么无法比拟的优势?我们会在下篇文章揭晓。


    起源地下载网 » 混乱是进步的阶梯 —— ESM规范的崛起【上】

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元