使用AMD,CommonJS和ES Harmony编写模块化JavaScript代码(ES Harmony)
2016-12-06 14:19
681 查看
原文:https://addyosmani.com/writing-modular-js/
因此,已经提出了一些针对这一需求的改进方案。其中包括可以适用于客户端和服务端的灵活的模块系统,模块加载器以及一些其他的特性。在这一章里,我将会针对这些即将发布的新特性,展示对应的示例代码,期望能够让你对其有最基本的了解。
注意:虽然Harmony还是在提案阶段(译者注:请以当前最新的ES规范为准),但是多亏了Chrome的Traceur 编译器,你已经可以去尝试这些新的功能特性了。通过入门教程,可以在几分钟内上手。如果你对这个项目十分感兴趣的话,那么可以尝试阅读JSConf描述(译者注:原文中存在链接,但打开后404)。
import声明,将模块的exports作为局部变量进行绑定,并且可能会通过重命名以避免变量的冲突。
export声明,将本地绑定的模块声明为外部可见的,因此其他的模块可以访问该模块的
在Harmony中,类将成为语言的一部分,包括了构造器,和私有性。在随后的示例中,我加入了行内注释,以帮助你更好的理解类是如何构建的。同时你会发现这里并没有使用
相关阅读
A First Look At The Upcoming JavaScript Modules
David Herman On JavaScript/ES.Next (Video)
ES Harmony Module Proposals
ES Harmony Module Semantics/Structure Rationale
ES Harmony Class Proposals
简而言之,我建议尝试下当前被推荐的这些规范,它们为构建可复用的模块化功能提供了更强的效率和灵活性。
这就是全部内容,如果你有任何疑问关于这些主题,欢迎在twitter上与我联系,我将尽我的最大努力回答!
ES Harmony 模块化的未来
TC39,是负责定义ECMAScript语法和语义标准的机构,由一群精英的开发人员组成,不断进行标准规范的版本迭代。在过去几年里,一些开发人员(像Alex Russell)已经将探索的重心放在让JavaScript适合大型项目开发的解决方案上,并且也深深的体会到对模块化JS编程的强烈需求。因此,已经提出了一些针对这一需求的改进方案。其中包括可以适用于客户端和服务端的灵活的模块系统,模块加载器以及一些其他的特性。在这一章里,我将会针对这些即将发布的新特性,展示对应的示例代码,期望能够让你对其有最基本的了解。
注意:虽然Harmony还是在提案阶段(译者注:请以当前最新的ES规范为准),但是多亏了Chrome的Traceur 编译器,你已经可以去尝试这些新的功能特性了。通过入门教程,可以在几分钟内上手。如果你对这个项目十分感兴趣的话,那么可以尝试阅读JSConf描述(译者注:原文中存在链接,但打开后404)。
具有imports和exports的模块(Modules)
如果你已经读过了AMD和CJS模块标准的话,那么应该熟悉了imports(module dependencies 模块依赖)和exports(或者是可被其他模块访问的公共API/变量)的的概念。在下一版的ES规范(ES.next)中,上述依赖概念被简洁地定义为import关键字来实现。
export和我们期待的并没有什么不同,我想大多数的开发者通过下面的示例,就能很快的理解。
import声明,将模块的exports作为局部变量进行绑定,并且可能会通过重命名以避免变量的冲突。
export声明,将本地绑定的模块声明为外部可见的,因此其他的模块可以访问该模块的
exports,但不能修改。有趣的是,模块可以暴露(export)它的子模块,而不能暴露在其他位置定义的模块。同时,可以将暴露的方法或变量重命名,而无需使用其本地的名称。
module staff{ // specify (public) exports that can be consumed by // other modules export var baker = { bake: function( item ){ console.log('Woo! I just baked ' + item); } } } module skills{ export var specialty = "baking"; export var experience = "5 years"; } module cakeFactory{ // specify dependencies import baker from staff; // import everything with wildcards import * from skills; export var oven = { makeCupcake: function( toppings ){ baker.bake('cupcake', toppings); }, makeMuffin: function( mSize ){ baker.bake('muffin', size); } } }
从远程资源加载模块
ES Harmony的模块化协议同样适用于基于远程的模块(例如,第三方的API封装),使其能够简洁的从外部位置加载模块。下面就是远程拉取我们之前定义的模块并且使用的例子module cakeFactory from 'http://addyosmani.com/factory/cakes.js'; cakeFactory.oven.makeCupcake('sprinkles'); cakeFactory.oven.makeMuffin('large');
模块加载器API
模块加载器描述了严格控制情况下,加载模块的推荐动态API。支持的加载器包括加载模块的函数load(url, moduleInstance, error),创建模块的函数
createModule(object, globalModuleReferences)以及其他的方法。下面是在模块中动态加载我们之前定义的模块的示例。与上面通过远程资源加载模块不同,模块加载器API更适合动态加载的情况。
Loader.load('http://addyosmani.com/factory/cakes.js', function(cakeFactory){ cakeFactory.oven.makeCupcake('chocolate'); });
服务端类似CommonJS的模块
对于面向服务的开发人员,ES.next的模块系统并非仅仅拘泥于适用于浏览器的模块。下面的例子,展示了在服务端使用的类似CommonJS的模块。// io/File.js export function open(path) { ... }; export function close(hnd) { ... };
// compiler/LexicalHandler.js module file from 'io/File'; import { open, close } from file; export function scan(in) { try { var h = open(in) ... } finally { close(h) } }
module lexer from 'compiler/LexicalHandler'; module stdlib from '@std'; //... scan(cmdline[0]) ...
具有构造器,Getter方法和Setter方法的类
类的概念一直是纯粹主义者争论的焦点,迄今为止,我们已经使用了很多方法来模拟类的功能,包括利用原生JavaScript的原型系统,或者使用框架,或者利用抽象等等,这些都可以提取为相同的原型行为。在Harmony中,类将成为语言的一部分,包括了构造器,和私有性。在随后的示例中,我加入了行内注释,以帮助你更好的理解类是如何构建的。同时你会发现这里并没有使用
function关键字。这并非是拼写错误:TC39希望开发人员能够更为简洁的编写代码,因此为了减少随意滥用
function的情况,而做出了极大的努力。
class Cake{ // We can define the body of a class' constructor // function by using the keyword 'constructor' followed // by an argument list of public and private declarations. constructor( name, toppings, price, cakeSize ){ public name = name; public cakeSize = cakeSize; public toppings = toppings; private price = price; } // As a part of ES.next's efforts to decrease the unnecessary // use of 'function' for everything, you'll notice that it's // dropped for cases such as the following. Here an identifier // followed by an argument list and a body defines a new method addTopping( topping ){ public(this).toppings.push(topping); } // Getters can be defined by declaring get before // an identifier/method name and a curly body. get allToppings(){ return public(this).toppings; } get qualifiesForDiscount(){ return private(this).price > 5; } // Similar to getters, setters can be defined by using // the 'set' keyword before an identifier set cakeSize( cSize ){ if( cSize < 0 ){ throw new Error('Cake must be a valid size - either small, medium or large'); } public(this).cakeSize = cSize; } }
ES Harmony总结
像你看到的那样,即将到来的ES.next会伴随这许多令人兴奋的特性。虽然在现在可以使用Traceur来尝试新的特性,但是立刻将Harmony使用到当前的项目中,并非是一个优越的选择(就目前来看)。这其中仍然有些问题存在,例如官方规范的变动,以及在跨浏览器兼容性可能存在的问题(例如IE会在运行ES Harmony一段时间后锁死进程)。所以最好等到规范最终的确定,并且囊括了AMD(浏览器模块)和CJS(服务端模块)。相关阅读
A First Look At The Upcoming JavaScript Modules
David Herman On JavaScript/ES.Next (Video)
ES Harmony Module Proposals
ES Harmony Module Semantics/Structure Rationale
ES Harmony Class Proposals
总结和后续推荐阅读
在文中我们大概了解了几种可选择的用于编写模块化JavaScript代码的现代化模块规范。这些模块相较于传统的模块模式具有很大优势:包括避免了开发人员针对每个创建的模块去定义全局变量,更好的支持动态和静态的依赖管理,通过脚本加载器提高可配型,在服务端使模块具有更优的可配行,等等。简而言之,我建议尝试下当前被推荐的这些规范,它们为构建可复用的模块化功能提供了更强的效率和灵活性。
这就是全部内容,如果你有任何疑问关于这些主题,欢迎在twitter上与我联系,我将尽我的最大努力回答!
相关文章推荐
- 使用 AMD、CommonJS 及 ES Harmony 编写模块化的 JavaScript
- 使用AMD,CommonJS和ES Harmony编写模块化JavaScript代码(AMD VS CJS)
- 使用 AMD、CommonJS 及 ES Harmony 编写模块化的 JavaScript
- [置顶] Javascript模块化编程——使用AMD,CommonJS,ES Harmony
- 使用requirejs编写模块化代码
- JavaScript编写检测用户所使用的浏览器的代码示例
- 分享:使用 TypeScript 编写的 JavaScript 游戏代码
- 使用浏览器命令行编写JavaScript代码
- 使用 Promises 编写更优雅的 JavaScript 代码
- 该如何理解AMD ,CMD,CommonJS规范--javascript模块化加载学习总结
- JavaScript模块化编程 - CommonJS, AMD 和 RequireJS之间的关系
- 使用CoffeeScrip优美方式编写javascript代码
- Javascript模块化开发,使用模块化脚本加载工具RequireJS,提高你代码的速度和质量。
- webStore 使用技巧 <<node 开发 代码提示 >> 任何解决编辑node代码 像编写JavaScript代码一样智能提示!
- 该如何理解AMD ,CMD,CommonJS规范--javascript模块化加载学习总结
- JavaScript编写检测用户所使用的浏览器的代码示例
- 【JavaScript】JavaScript模块化编程 - CommonJS, AMD 和 RequireJS之间的关系
- Javascript模块化编程(一)AMD规范(规范使用模块)
- JavaScript模块化编程 - CommonJS, AMD 和 RequireJS之间的关系
- 使用AngularJS编写较为优美的JavaScript代码指南