2018年,我曾经在deno发布后不久写过一篇文章《Deno不是下一代Node.js!》。刚好最近有研究,2021年再看deno。毫无疑问,deno改变了大家对包管理的看法。Deno本身足够小,试错成本低。它确实引领了一种趋势。虽然这项改进并不新鲜,但反响确实不错。大概是因为世界上的人长期被npm(npm开玩笑:你害怕吗)所困扰。使用简单、高效,甚至衍生出很多关于CDNforJavaScript模块的思考。接下来,我们一起来看看吧。我们做了一个iMove的开源项目。iMove是一个逻辑可重用、面向功能和过程可视化的JavaScript工具库。目前支持的特性[x]流程可视化:简单易用,易于绘制,逻辑表达更直观,易于理解[x]逻辑复用:iMove节点支持复用,单节点支持参数配置[x]灵活可扩展:仅A需要编写函数,可以扩展节点,支持插件集成[]多语言编译:无语言编译代码限制(例如:支持JavaScript,Java编译代码输出)其实说白了,是一套用于运营配置开发的玩法。每个节点都是一个函数,可视化、可配置、可组装、可代码导出,非常克制。基于x6图形和json协议,可以说以最小的投入成本达到最大的效果。从定位来看,还是比较准确的。我们在自己的业务中使用,体验和效果也很好。最近为了开源,小伙伴们提出了两个优化点:双击图形,可以编辑函数,操作更方便。完成。使节点或进程在此接口上可测试。确实存在这个问题。如果节点是可测量的,它在功能上会更实用。第二点,我非常赞同。但问题是,如何实现呢?每个节点的代码相当于一个js文件,不用担心全局变量的命名污染,甚至可以导入已有的npm包,但最后必须导出一个函数。需要注意的是,由于iMove天生就支持节点代码的异步调用,所以导出的函数默认是一个promise。比如以是否登录这个分支节点为例,我们看看节点代码怎么写:importfetchfrom'node-fetch';导出默认异步函数(ctx){returnfetch('/api/isLogin')。然后(res=>res.json()).then(res=>{const{success,data:{isLogin}={}}=res;returnsuccess&&isLogin;}).catch(err=>{console.log('fetch/api/isLoginfailed,theerris:',err);returnfalse;});}扩展说这是esm,基于es模块的主流写法。支持外部包导入,否则难以应对复杂场景。类似的jsbin,或者codepen,或者codesandbox,可以使用webpack的离线插件实现,也可以使用webide来初始化安装模块,但这都不是什么好办法。imove兼容浏览器和node,本地无需安装npm包即可直接运行,在node中也能完美运行。于是,我们不得不往http导入的方向去思考。System.js是一个很好的选择。import-http查看deno链接外部代码文档(https://deno.land/manual/link...),其做法是使用--allow-net参数选项允许deno运行时下载导入并将其缓存在磁盘上。这个其实只是缓存在系统目录下,比如mac上的$HOME/Library/Caches/deno。事实上,并没有真正的改善。通过代码地址引用代码真的很爽。不再有node_modules膨胀,无需安装依赖项。在节点世界,有人实现了类似的机制,即https://github.com/egoist/imp...。它在编译时通过webpack/rollup处理。查看具体用法,先配置webpack.config.js:constImportHttpWebpackPlugin=require('import-http/webpack')module.exports={plugins:[newImportHttpWebpackPlugin()]}然后就可以直接在代码:importReactfrom'https://unpkg.com/react'importVuefrom'https://unpkg.com/vue'console.log(React,Vue)原理:通过webpack的compiler.resolverFactory解析import-http-.hooks.resolver解析器,即用http和https导入。然后通过fileModuleCache和httpCache缓存下载的内容。其实Node.js做这个也很简单。只要在https://github.com/nodejs/nod...,下载和缓存就可以解决。然而,历史的包袱太重了,要实现https源不导入任何文件系统还有很长的路要走。不过这也是大家参与贡献Node.js源码的一个好点。模块:ESM加载器下一步https://github.com/nodejs/nod...官方工作组https://github.com/nodejs/mod...支持第三方ESM加载器即将到来,让我们拭目以待看到了,用法类似下面这样JavaScript模块的新时代CDN”。这个说的很直白,就是重新定义基于CDN的JavaScript模块新的托管方式。它的原理图。以npm和github为源,同步到Amazons3,再代理到各个CDN为用户提供服务。cjstoesm很长时间以来就有一个cjstoesm工具。比如https://github.com/standard-t...,自己实现大量的polyfills和transitionstates,试试还行,迟早还是要回归内核。极其简单、无babel、无捆绑的ECMAScript模块加载器。//将选项设置为参数、环境变量或rc文件。require=require("esm")(module/*,options*/)module.exports=require("./main.js")这是一种本地方法。如果变成了httpimport,这件事情就不需要在本地做。把这些留给类似CDN的服务比较合适。事实上,pika.dev/skypack.dev/jspm.io已经这样做了。使用http://jspm.io(或其他类似服务)将commonjs转换为兼容的esm格式。从“https://dev.jspm.io/npm:cheerio/index.js”导入cheerio;扩展一下,2个问题。中国没有类似的服务。既然有cnpm,会不会有类似的服务?我认为有人会这样做。传统CDN厂商下一步也会往这个方向发展,要么收购,要么自建。这其实是一门好生意。一方面可以满足开发者的需求,另一方面也可以为传统CDN厂商提供增量服务。也是新基建不可或缺的一部分。总结一下,deno是一个非常好的创新。上面提到的import-http、esm.run或模块转换服务,可以说是deno探索间接或直接作用的结果。但如果要取代Node,目前的特性和性能提升还不足以取代Node。Node社区在node4之后采用es特性后与时俱进,cjs和esm处理也非常及时。那么现在时机成熟了,距离node拥抱httpimport的今天还会远吗?
