Node.js require 同步加载机制应用到浏览器端
发布于 2年前 作者 ldjking 1362 次浏览

异步非阻塞这就不说了,当然很多语言都支持异步编程,Node.js肯定是比较简单易用的。 但是我觉得require的模块化机制才是Node.js最核心最最重要的功能。 有了require,所以才产生了那么多的优秀的组件, express,require了connect等 connect,require了mime、cookie 点滴汇聚,形成了众多优秀的项目。

那么require这个功能是如何实现的呢?V8的源码肯定一时半会没精力没能力读。 以前看过AMD的模块加载规范,但是这个是异步的,对require和define有些了解, 这里面主要依赖的是DOC.currentScript,相当于获取到当前解析js文件的上下文。 AMD的模块加载可以参考司徒正美的MASS框架。 但是AMD的缺点也是显而易见的,模块需要额外写在define函数里,异步的异步会让人总担心出错的可能, 如果能像Node.js一样同步require多直观多方便啊。

Node.js的模块默认需要提供package.json和readme.md文件,相当于模块的自描述文件, 开发者可以很清晰的获取到功能模块的清单,以及模块之间的相互依赖关系。

能不能在浏览器端的JavaScript开发中也利用起类似Node.js的同步的模块加载机制呢? There is a will there is way。 我的实现思路由四步组成 1.通过XMLHttpRequest获取js文件内容 2.利用Function将js内容构成出一个函数,var fn=new Function("module",str),支持一个module参数 3.新建一个obj对象,fn(obj);执行这个函数 4.return obj.exports

伪代码看起来是这样的: var str=ajax.getScriptSync(“a.js”); var fn=new Function("module",str); var module={}; fn(module); return module.exports;

理论上同步加载已经能实现了,但是如何解决相对路径的引用问题呢, 一个模块引用内部私有的文件,一般应该是requrie(“./lib/a.js”); 这里需要把“.”这个当前目录引用替换成该模块的实际路径,并在模块名变化的时候重新构建。

最终形成的目录应该是这样的 modules/ 存放所有模块 lib/ 存放对“.”重新构建后的代码

这样在前端开发过程中,再也不需要关心资源引用的问题了,所有你想要的东西, 直接一段 var tree=require(“tree-a”); var animation=rq(“animation”); tree.render(dom,data,option); animation.run();

打算抽时间把这个功能实现,前端的代码就更便于积累了。

2 回复

前端的框架太多了, 如果前端框架都遵循require的规范进行开发,可以减少很多大家的学习成本。 希望html5的时代快到来,特别不喜欢各种浏览器的乱象和兼容性代码。

https://github.com/jiyinyiyong/banyan 楼主和我想到一块去了, 看我上边的试验代码… 主要是异步加在的问题, 导致这个方案不实用. Hack 的方案可能也有…

社区主要的方案是 Browserify, Node 模块, 打包编译, 发送到客户端执行, 外加 SourceMaps 调试 如果只是为了用的话, 建议 Browserify 直接上

回到顶部