就算遇到ES6和Node中module的坑,也要承认世界将是JavaScript的

广告位招租
扫码页面底部二维码联系

PHP是世界上最好的语言,而JavaSc本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。ript将统治全世界

【作者:唐霜】本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。【未经授权禁止转载】
【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net

这个梗,已经完全不能被扒出是什么时候,由转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net哪位神经大条的网友创造出来的。之所以这个【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net梗被无时无刻的搬出来调侃,是因为编程世界【版权所有】唐霜 www.tangshuang.net【本文受版权保护】的坑多到走完这条路,就脚残的节奏。

本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。

今天就来扒一扒在node和ES6中的mo【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。dule,主要是为了区分node和ES6未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】中的不同意义,避免概念上的混淆,同时也分本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】享一下,自己在这个坑里获得的心得。

【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】【未经授权禁止转载】

在ES6之前【原创内容,转载请注明出处】

【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。

模块的概念是在ES6发布之前就出现的,我【原创不易,请尊重版权】未经授权,禁止复制转载。感觉主要是为了适应大型应用开发的需要而引转载请注明出处:www.tangshuang.net原创内容,盗版必究。入了JavaScript世界。模块化编程原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net已经从噱头上升为必备,所以ES6也顺应时转载请注明出处:www.tangshuang.net【版权所有,侵权必究】代,把这个写进了标准。

未经授权,禁止复制转载。【原创不易,请尊重版权】【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。

CommonJS和AMD都是JavaSc【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.netript模块化规范,在ES6之前,Nod【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。e主要遵循CommonJS,而AMD则主【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。要运用在浏览器端,比如requirejs【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。

转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】

而且node发布的时候,就天生具备mod原创内容,盗版必究。【本文受版权保护】ule,所以从某种意义上讲,是node促原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】进了js世界里面的模块化编程。

【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。【转载请注明来源】【版权所有,侵权必究】
// module-file.js for node
module.exports = {
  a : function() {},
  b : 'xxx'
};

把上面这个js文件放在node环境中,我本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】们这样去用它:

本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。
var myModule = require('./module-file');
var b = myModule.b;myModule.a();

当然了,node中module的知识有很著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。多,这里就不再挖坑了。

未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】

从模块化思想出发,requirejs和国转载请注明出处:www.tangshuang.net【本文受版权保护】内前端大牛发布的seajs(遵循CMD)【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net也允许前端猿们通过require去加载另【本文受版权保护】著作权归作者所有,禁止商业用途转载。一个模块。不过在模块定义的时候,需要借助【访问 www.tangshuang.net 获取更多精彩内容】【未经授权禁止转载】一个define函数:

【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】
// module-file.js for requirejs
define(function(require, exports, module){
   module.exports = {};
});

requirejs和seajs都支持上面【本文首发于唐霜的博客】【原创内容,转载请注明出处】这种形式,在define的回调函数中提供【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】了模拟的require, exports【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net, module,折让习惯了node环境本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net中使用方法的猿类可以顺便在浏览器端写基本【关注微信公众号:wwwtangshuangnet】【转载请注明来源】相同的代码。

【转载请注明来源】转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】【作者:唐霜】

node,requirejs,seajs【关注微信公众号:wwwtangshuangnet】【转载请注明来源】也同时支持下面这种导出模块的方式:

著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】
define(function(){
  return {}; // return的值就是导出的模块
});

这就出现了UMD,即一个兼容多种环境的方未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】案。

【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。

Node,requirejs中的expo【本文首发于唐霜的博客】【本文受版权保护】rts

【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。【作者:唐霜】

node中导出模块接口就是用export著作权归作者所有,禁止商业用途转载。【作者:唐霜】s,你可以这样做:

【本文受版权保护】原创内容,盗版必究。【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】
module.exports.a = function() {};
module.exports.b = 'xxx';

也可以写在一个对象中:著作权归作者所有,禁止商业用途转载。

著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。
module.exports = {
  a : function() {},
  b : 'xxx'
}

在requirejs中,还提供了一个ex【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。ports变量作为module.expo【关注微信公众号:wwwtangshuangnet】【作者:唐霜】rts的别名:

本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】原创内容,盗版必究。
define(function(require, exports, module){
   exports.a = function(){};
   exports.b = 'xxx';
});

注意“别名”的含义:exports是mo本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。dule.exports的地址的引用。它【作者:唐霜】原创内容,盗版必究。的本质是:

【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。
var exrpots = module.exports;

因此,你必须注意两个点,就是导出接口的时本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。候:1.不能直接用exports={}来【原创不易,请尊重版权】未经授权,禁止复制转载。导出整个接口;2.如果使用了module原创内容,盗版必究。【原创内容,转载请注明出处】.exports={},那么export未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。s.a等都会被覆盖无效。

未经授权,禁止复制转载。【版权所有,侵权必究】未经授权,禁止复制转载。【原创不易,请尊重版权】

这是非常容易理解的,如果你不是很理解,可【本文首发于唐霜的博客】【版权所有,侵权必究】以阅读我写的《JavaScript引用类型数据【转载请注明来源】》一文。【访问 www.tangshuang.net 获取更多精彩内容】

原创内容,盗版必究。【本文受版权保护】著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】

ES6中的import和export【版权所有】唐霜 www.tangshuang.net

【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】【本文首发于唐霜的博客】本文作者:唐霜,转载请注明出处。

在ES6之前,要使用一个模块,必须使用r原创内容,盗版必究。原创内容,盗版必究。equire函数将一个模块引入,但ES6未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。并没有采用这种模块化方案,在ES6中使用【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】import指令引入一个模块或模块中的部【版权所有,侵权必究】【原创内容,转载请注明出处】分接口,并没有将require写入标准,本文版权归作者所有,未经授权不得转载。本文版权归作者所有,未经授权不得转载。这也就是说require对于ES6代码而【版权所有,侵权必究】【版权所有,侵权必究】言,只是一个普通函数。

转载请注明出处:www.tangshuang.net【作者:唐霜】原创内容,盗版必究。【版权所有,侵权必究】

同理,在ES6标准中,导出模块的接口也只原创内容,盗版必究。【原创内容,转载请注明出处】能使用export指令,而非export【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。s对象,这也同样意味着module.ex【未经授权禁止转载】【本文受版权保护】ports只是node,requirej【关注微信公众号:wwwtangshuangnet】【转载请注明来源】s等模块化库的自定义变量,而非ES标准接【版权所有,侵权必究】【本文受版权保护】口。

本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net

当然,ES6的模块化也很复杂,不只模块接本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。口的导入导出这点东西,只不过本文无耻的只本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。讨论这个相对而言比较常见的问题。

【转载请注明来源】未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】

常见export方式原创内容,盗版必究。

未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。【本文受版权保护】【原创内容,转载请注明出处】【本文受版权保护】

在ES6规定中,这样导出一个模块的接口:

【本文首发于唐霜的博客】未经授权,禁止复制转载。未经授权,禁止复制转载。【作者:唐霜】原创内容,盗版必究。
export function fun() {};
export { name1, name2, …, nameN };
export { variable1 as name1, variable2 as name2, …, nameN };
export let name1, name2, …, nameN; // also var
export let name1 = …, name2 = …, …, nameN; // also var, const
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };
export * from …;export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;

ES6里面,直接把要导出的变量、函数、对【作者:唐霜】【版权所有】唐霜 www.tangshuang.net象、类等前面加一个export关键字。比转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。如:

【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】
// module-file.js
export function a(){};
export var obj = {};

有一个点:export必须导出具有对应关【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net系的变量,下面的接口输出是错误的:

本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】
// 错误演示
export 1; // 这种导出的内容不是变量是绝对错误的,包括导出表达式,也是绝对错误的
var a = 1;
export a;
function b() {}
export b;

上面的这些方法都是错误的,不能这样导出接著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】口。导出接口仅限两种:

【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。

1.声明时导出本文版权归作者所有,未经授权不得转载。
【原创内容,转载请注明出处】【未经授权禁止转载】 2.以对象的形式导出(和解构联系起来)

【原创不易,请尊重版权】【本文受版权保护】【转载请注明来源】著作权归作者所有,禁止商业用途转载。

如果要导出某个变量,可以用花括号括起来,本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】像这样:

未经授权,禁止复制转载。【原创内容,转载请注明出处】【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。
var a = 1;
export {a}; // 等效于:{a:a}
function b() {}
export {b};

我有点疑惑的是,为何export允许多次【本文首发于唐霜的博客】原创内容,盗版必究。export {}这种形式?看上去很奇怪【原创不易,请尊重版权】【转载请注明来源】。另外,ES6更厉害之处在于,可以在ex本文作者:唐霜,转载请注明出处。【未经授权禁止转载】port变量之后,继续修改变量:

【版权所有,侵权必究】原创内容,盗版必究。【转载请注明来源】【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】
export var obj {};obj.a = 1;

在import之后,obj的值仍然可以在【转载请注明来源】未经授权,禁止复制转载。模块内继续改变,这是CommonJS以往【本文首发于唐霜的博客】【未经授权禁止转载】不可能做到的。

著作权归作者所有,禁止商业用途转载。【转载请注明来源】转载请注明出处:www.tangshuang.net【未经授权禁止转载】

import基本用法本文版权归作者所有,未经授权不得转载。

著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】【原创内容,转载请注明出处】

在另外一个js文件里面这样使用这些接口:

【本文首发于唐霜的博客】【本文首发于唐霜的博客】未经授权,禁止复制转载。【未经授权禁止转载】【原创内容,转载请注明出处】
import {a,obj} from './module-file';a();alert(obj.b);

和node之前的require不一样,r【本文受版权保护】未经授权,禁止复制转载。equire只能把模块放到一个变量中,而【关注微信公众号:wwwtangshuangnet】【本文受版权保护】在ES6中,拥有对象解构赋值本文作者:唐霜,转载请注明出处。的能力,所以直接就把引入的模块的接口赋值未经授权,禁止复制转载。【本文首发于唐霜的博客】给变量了。内在机理也有不同,requir本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】e需要去执行整个模块,将整个模块放到内存本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。中(也就是我们说的运行时),如果只是使用【本文首发于唐霜的博客】【本文首发于唐霜的博客】到其中一个方法,性能上就差很多,而imp【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】ort…from则是只加载需【访问 www.tangshuang.net 获取更多精彩内容】本文版权归作者所有,未经授权不得转载。要的接口方法,其他方法在程序启动之后根本【未经授权禁止转载】未经授权,禁止复制转载。触及不到,所以这种又被称为“编译时”,性【本文首发于唐霜的博客】【原创内容,转载请注明出处】能上好很多。

原创内容,盗版必究。【原创内容,转载请注明出处】【关注微信公众号:wwwtangshuangnet】

as关键字【未经授权禁止转载】

【原创内容,转载请注明出处】【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】【原创不易,请尊重版权】【访问 www.tangshuang.net 获取更多精彩内容】

编程的同学对as都容易理解,简单的说就是转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。取一个别名。上面export中可以用,i【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】mport中其实也可以用:

本文作者:唐霜,转载请注明出处。原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net
// a.jsvar a = function() {};export {a as fun};
// b.jsimport {fun as a} from './a';a();

上面这段代码,export的时候,对外提著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net供的接口是fun,它是a.js内部a这个原创内容,盗版必究。【本文受版权保护】函数的别名,但是在模块外面,认不到a,只【关注微信公众号:wwwtangshuangnet】【作者:唐霜】能认到fun。

转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。【本文首发于唐霜的博客】

import中的as就很简单,就是你在使本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。用模块里面的方法的时候,给这个方法取一个【本文首发于唐霜的博客】【转载请注明来源】别名,好在当前的文件里面使用。之所以是这本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。样,是因为有的时候不同的两个模块可能通过原创内容,盗版必究。【版权所有,侵权必究】相同的接口,比如有一个c.js也通过了f本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netun这个接口:

【本文首发于唐霜的博客】【作者:唐霜】本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】
// c.jsexport function fun() {};

如果在b.js中同时使用a和c这两个模块本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】,就必须想办法解决接口重名的问题,as就【版权所有】唐霜 www.tangshuang.net【本文受版权保护】解决了。

著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net【作者:唐霜】原创内容,盗版必究。

default关键字【版权所有,侵权必究】

著作权归作者所有,禁止商业用途转载。【作者:唐霜】【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。【原创不易,请尊重版权】

其他人写教程什么的,都把default放【版权所有,侵权必究】【转载请注明来源】到export那个部分,我觉得不利于理解原创内容,盗版必究。【作者:唐霜】。在export的时候,可能会用到def【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。ault,说白了,它其实是别名的语法糖:

【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.net【作者:唐霜】
// d.jsexport default function() {}
// 等效于:function a() {};export {a as default};

在import的时候,可以这样用:【转载请注明来源】

【版权所有,侵权必究】【本文受版权保护】【关注微信公众号:wwwtangshuangnet】【未经授权禁止转载】
import a from './d';
// 等效于,或者说就是下面这种写法的简写,是同一个意思import {default as a} from './d';

这个语法糖的好处就是import的时候,【本文受版权保护】【原创不易,请尊重版权】可以省去花括号{}。简单的说,如果imp著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。ort的时候,你发现某个变量没有花括号括【作者:唐霜】本文版权归作者所有,未经授权不得转载。起来,那么你在脑海中应该把它还原成有花括著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。号的as语法。

【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】转载请注明出处:www.tangshuang.net

所以,下面这种写法你也应该理解了吧:转载请注明出处:www.tangshuang.net

【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】
import _,{each,map} from '_';

*符号著作权归作者所有,禁止商业用途转载。

【原创内容,转载请注明出处】原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net

*就是代表所有,只用在import中,我未经授权,禁止复制转载。【本文受版权保护】们看下两个例子:

【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。本文作者:唐霜,转载请注明出处。【本文受版权保护】【本文首发于唐霜的博客】
import * as underscore from '_';

在意义上和原创内容,盗版必究。import _ from '_';是不同的,虽然实际上后面的使用方法是一样【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net的。它表示的是把’_R【未经授权禁止转载】本文作者:唐霜,转载请注明出处。17;模块中的所有接口挂载到unders【本文首发于唐霜的博客】转载请注明出处:www.tangshuang.netcore这个对象上,所以可以用under【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。score.each调用某个接口。

本文作者:唐霜,转载请注明出处。原创内容,盗版必究。【转载请注明来源】本文作者:唐霜,转载请注明出处。
export * from '_';
// 等效于:import * as all from '_';export all;

该用require还是import?【本文首发于唐霜的博客】

未经授权,禁止复制转载。【原创内容,转载请注明出处】【作者:唐霜】【未经授权禁止转载】

接下来的问题,就是我们在实操中,还有必要【转载请注明来源】本文版权归作者所有,未经授权不得转载。用require吗?我感觉ES6标准已经著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.net将之前的所有模块化规范都给碾压了,这在以原创内容,盗版必究。【转载请注明来源】前的标准发布中极少见,ES6用更加简单的【作者:唐霜】【原创不易,请尊重版权】方式,实现了更加有效的module,感觉著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】require可以回家养老了。

本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。

标准与非标准未经授权,禁止复制转载。

未经授权,禁止复制转载。【未经授权禁止转载】原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】【作者:唐霜】

既然是标准,那么就是所有引擎应该去实现的【本文受版权保护】原创内容,盗版必究。,node和浏览器未来都会直接支持这种模著作权归作者所有,禁止商业用途转载。【作者:唐霜】块加载方式,require完成历史使命回转载请注明出处:www.tangshuang.net原创内容,盗版必究。家自己玩儿。而且作为node或浏览器,同本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。时可以利用import提供自己的API,【原创内容,转载请注明出处】【本文受版权保护】比如手机端提供基于网络的定位API,这都【本文受版权保护】原创内容,盗版必究。不用SDK了,直接内置在客户端内部,im本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netport一下就可以了。

【本文受版权保护】著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】原创内容,盗版必究。

不过现在import导入模块还并不是全部【未经授权禁止转载】【未经授权禁止转载】环境都支持,使用babel可以让node【原创内容,转载请注明出处】【本文受版权保护】支持ES6,但在浏览器端,则毫无办法,可【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】能还得暂时依赖require。但是非常不本文作者:唐霜,转载请注明出处。【本文受版权保护】好的消息是,require不是ES6标准转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。,这也就是说如果将来浏览器支持impor本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.nett后,你想用它,就必须升级代码,而不能直本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】接被兼容。

【本文受版权保护】【版权所有】唐霜 www.tangshuang.net【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。【访问 www.tangshuang.net 获取更多精彩内容】

import只能在文件开头使用,在imp本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。ort之前,你不能有其他的代码,这和其他本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net语言是一样的。但是require则不同,【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。它相当于node的一个定义在全局的函数,未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】你可以在任意地方使用它,甚至使用变量表达【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。式作为它的参数,这样有一个好处,就是可以未经授权,禁止复制转载。【本文首发于唐霜的博客】在循环中加载模块。

【版权所有】唐霜 www.tangshuang.net【转载请注明来源】转载请注明出处:www.tangshuang.net【未经授权禁止转载】

有没有兼容import和require的本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。模块?

【未经授权禁止转载】本文作者:唐霜,转载请注明出处。【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】

但是很坑的是,node的模块导出和ES6原创内容,盗版必究。未经授权,禁止复制转载。标准也不符,因为node的模块体系遵循的【关注微信公众号:wwwtangshuangnet】本文作者:唐霜,转载请注明出处。是CommonJS规范,这就导致你写的模【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。块文件,不可能同时支持require和i【转载请注明来源】【本文受版权保护】mport。

【未经授权禁止转载】【本文受版权保护】本文作者:唐霜,转载请注明出处。

要强调的就是,不要把require和im未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。port两种模块加载方案混用,比如:

【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】【未经授权禁止转载】
// module-file.jsmodule.exports = {};
// a.jsimport a from './moule-file';

这种混搭感觉不是很好(但可以用,下面有解未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.net释)。所以,其实我没有任何建议,我只是觉【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】得,躺在坑里,挺自在的……毕竟node中【原创不易,请尊重版权】转载请注明出处:www.tangshuang.netrequire的使用更加灵活一点,它没有未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】必须放在哪里的限制,所以可以在任意位置使【原创内容,转载请注明出处】【转载请注明来源】用,而且它的结果也非常形象,甚至可以把r【本文首发于唐霜的博客】【原创内容,转载请注明出处】equire当做一个引用类型别名,可以这【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net样使用:

【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【版权所有,侵权必究】
require('./a')(); // a模块是一个函数,立即执行a模块函数
var data = require('./a').data; // a模块导出的是一个对象
var a = require('./a')[0]; // a模块导出的是一个数组

这样的写法感觉像给模块取了一个别名,使用【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。的时候非常灵活。但是需要注意的是,如果你【访问 www.tangshuang.net 获取更多精彩内容】转载请注明出处:www.tangshuang.net打算使用require来导入这个模块,那本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。么请使用module.exports导出【本文受版权保护】【转载请注明来源】这个模块。

【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。

(临时)兼容方案【原创内容,转载请注明出处】

未经授权,禁止复制转载。原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。

有没有一种兼容方案呢?【未经授权禁止转载】

【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】
function a() {}
class b {}
module.exports = {a,b}; // {a,b}是ES6的写法

在实践中发现,module.export【本文受版权保护】【作者:唐霜】s可以兼容require和import,【原创内容,转载请注明出处】【未经授权禁止转载】而且这个案例需要你的node环境配置好支【作者:唐霜】著作权归作者所有,禁止商业用途转载。持ES6语法。module.export原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.nets导出的模块,如果使用import,那么【关注微信公众号:wwwtangshuangnet】未经授权,禁止复制转载。完全就是一个对象赋值、解构的过程:

本文作者:唐霜,转载请注明出处。【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。
import mod,{a,b} from './a';

之所以这是成立的,是因为我们使用babe【原创不易,请尊重版权】转载请注明出处:www.tangshuang.netl对ES6代码进行转码后执行,而实际上,【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。目前为止,没有任何一个环境是支持ES6 【关注微信公众号:wwwtangshuangnet】【转载请注明来源】module方案的,即使babel,也仅【本文受版权保护】【原创内容,转载请注明出处】仅是将ES6的import,export【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】转码为require, module.e转载请注明出处:www.tangshuang.net【本文受版权保护】xports后交给node去执行。

【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net

导出的模块接口被赋值给mod,所以mod【版权所有,侵权必究】【本文受版权保护】是一个对象,含有a,b两个方法。这里的m【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.netod并没有通过default导出,所以和【版权所有,侵权必究】【原创不易,请尊重版权】ES6有非常大的意义上的区别,这种非标准著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。的写法,墙裂建议永远不要用。而且,由于r【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】equire和module.export【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】s是非标准的东西,仅在Node环境中有效【未经授权禁止转载】原创内容,盗版必究。,所以当未来浏览器支持模块导入时,并不会著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net主动提供require,而是采用impo本文版权归作者所有,未经授权不得转载。著作权归作者所有,禁止商业用途转载。rt,如果要使用require,还是不得【转载请注明来源】转载请注明出处:www.tangshuang.net不使用requirejs等库,借助def【版权所有,侵权必究】【原创内容,转载请注明出处】ine来用。

著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。

所以,最终,如果你打算用CommonJS本文版权归作者所有,未经授权不得转载。【本文首发于唐霜的博客】,就不要掺和进ES6.

原创内容,盗版必究。【本文受版权保护】著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。

2016-11-07 36337 , , ,

为价值买单,打赏一杯咖啡

本文价值363.37RMB
已有11条评论
  1. ych 2020-07-06 11:18

    node有用es module的打算吗,作为小白来说,不知道他两的性能,但是论好用程度后者明显碾压啊,但是我怎么看node文档,node挺自豪commonjs的。。。甚至还有点瞧不起esmodule

    • 否子戈 2020-07-08 09:36

      node已经支持import mjs文件,浏览器也支持了。
      node作为js的运行环境,只会向ES标准靠近。当然,它保留自己的commonjs和独特api,是无可厚非的。
      有兴趣可以体验一下deno这个环境。

  2. 小飞侠 2020-05-23 16:50

    抱歉,在下是来挑刺的,阁下文中有一处严重的错误,
    》以对象的形式导出(和解构联系起来)
    》export {a}; // 等效于:{a:a}
    此处export的‘{ }’是语法结构,而非对象或解构
    eg: export { a as ax, a as default }
    若以阁下所言,》等效于:{a:a}。然经在下实测,无论export {a:a},export {b:a},export {a:b},皆为非法。
    export导出接口,而非对象,【https://es6.ruanyifeng.com/#docs/module】,
    换言之,它对外暴露模块内部的变量(方法,类..)的引用

    还望阁下认真求证,谨言慎行。

    • 否子戈 2020-05-23 17:53

      我看了很久,也没有找到你所指出的export {a:a}问题,export 导出语法只有 export { a as b } 这种形式。
      这篇文章后面部分讨论的是ESModule和commonjs混用的时候的一些实际情况,你评论中估计是在说这一块。具体可以再阅读一下文章,另外,后续我也更新了关于webpack tree shaking使用时的一些新规则,可以查看这篇文章 https://www.tangshuang.net/7686.html

      • 小飞侠 2020-05-23 18:02

        在3.export 命令
        以下是原话
        需要特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系。

        // 报错
        export 1;

        // 报错
        var m = 1;
        export m;
        上面两种写法都会报错,因为没有提供对外的接口。第一种写法直接输出 1,第二种写法通过变量m,还是直接输出 1。1只是一个值,不是接口。正确的写法是下面这样。

    • 否子戈 2020-05-23 17:55

      看到你所说的“等效于:{a:a}”这句话,已经做了修改,确实会让人误解,谢谢指出

  3. 阿川先生 2018-01-16 11:54

    寫得很好!謝謝您的分享!

    • 否子戈 2018-01-19 08:32

      多交流

  4. 你扛我输出 2017-10-17 20:57

    写的很好

  5. aaaaaaaaa 2017-09-07 18:32

    var b = myModule;\na();   这里a undefined

    • 否子戈 2017-09-07 19:51

      谢谢指出