深入浅出Node.js2.7 前后端共用模块_深入浅出Node.js2.7 前后端共用模块试读-查字典图书网
查字典图书网
当前位置: 查字典 > 图书网 > 编程 > 深入浅出Node.js > 2.7 前后端共用模块

深入浅出Node.js——2.7 前后端共用模块

谈论了许多后端模块的具体实现后,现在我们围绕CommonJS规范再次回到前端模块上。JavaScript在Node出现之后,比别的编程语言多了一项优势,那就是一些模块可以在前后端实现共用,这是因为很多API在各个宿主环境下都提供。但是在实际情况中,前后端的环境是略有差别的。 2.7.1 模块的侧重点 前后端JavaScript分别搁置在HTTP的两端,它们扮演的角色并不同。浏览器端的JavaScript需要经历从同一个服务器端分发到多个客户端执行,而服务器端JavaScript则是相同的代码需要多次执行。前者的瓶颈在于带宽,后者的瓶颈则在于CPU和内存等资源。前者需要通过网络加载代码,后者从磁盘中加载,两者的加载速度不在一个数量级上。 纵观Node的模块引入过程,几乎全都是同步的。尽管与Node强调异步的行为有些相反,但它是合理的。但是如果前端模块也采用同步的方式来引入,那将会在用户体验上造成很大的问题。UI在初始化过程中需要花费很多时间来等待脚本加载完成。 鉴于网络的原因,CommonJS为后端JavaScript制定的规范并不完全适合前端的应用场景。经过一段争执之后,AMD规范最终在前端应用场景中胜出。它的全称是Asynchronous Module Definition,即是“异步模块定义”,详见https://github.com/amdjs/amdjs-api/wiki/AMD。除此之外,还有玉伯定义的CMD规范。 2.7.2 AMD规范 AMD规范是CommonJS模块规范的一个延伸,它的模块定义如下: define(id?, dependencies?, factory); 它的模块id和依赖是可选的,与Node模块相似的地方在于factory的内容就是实际代码的内容。下面的代码定义了一个简单的模块: define(function() { var exports = {}; exports.sayHello = function() { alert('Hello from module: ' + module.id); }; return exports; }); 不同之处在于AMD模块需要用define来明确定义一个模块,而在Node实现中是隐式包装的,它们的目的是进行作用域隔离,仅在需要的时候被引入,避免掉过去那种通过全局变量或者全局命名空间的方式,以免变量污染和不小心被修改。另一个区别则是内容需要通过返回的方式实现导出。 2.7.3 CMD规范 CMD规范由国内的玉伯提出,与AMD规范的主要区别在于定义模块和依赖引入的部分。AMD需要在声明模块的时候指定所有的依赖,通过形参传递依赖到模块内容中: define(['dep1', 'dep2'], function (dep1, dep2) { return function () {}; }); 与AMD模块规范相比,CMD模块更接近于Node对CommonJS规范的定义: define(factory); 在依赖部分,CMD支持动态引入,示例如下: define(function(require, exports, module) { // The module code goes here }); require、exports和module通过形参传递给模块,在需要依赖模块时,随时调用require()引入即可。 2.7.4 兼容多种模块规范 为了让同一个模块可以运行在前后端,在写作过程中需要考虑兼容前端也实现了模块规范的环境。为了保持前后端的一致性,类库开发者需要将类库代码包装在一个闭包内。以下代码演示如何将hello()方法定义到不同的运行环境中,它能够兼容Node、AMD、CMD以及常见的浏览器环境中: ;(function (name, definition) { // 检测上下文环境是否为AMD或CMD var hasDefine = typeof define === 'function', // 检查上下文环境是否为Node hasExports = typeof module !== 'undefined' && module.exports; if (hasDefine) { // AMD环境或CMD环境 define(definition); } else if (hasExports) { // 定义为普通Node模块 module.exports = definition(); } else { // 将模块的执行结果挂在window变量中,在浏览器中this指向window对象 this[name] = definition(); } })('hello', function () { var hello = function () {}; return hello; });

展开全文

推荐文章

猜你喜欢

附近的人在看

推荐阅读

拓展阅读

《深入浅出Node.js》其他试读目录

• 1.1 Node的诞生历程
• 1.2 Node的命名与起源
• 1.3 Node给JavaScript带来的意义
• 1.4 Node的特点
• 1.5 Node的应用场景
• 1.6 Node的使用者
• 1.7 参考资源
• 2.1 CommonJS规范
• 2.2 Node的模块实现
• 2.3 核心模块
• 2.4 C/C++扩展模块
• 2.5 模块调用栈
• 2.6 包与NPM
• 2.7 前后端共用模块 [当前]
• 2.8 总结
• 2.9 参考资源