import與export在node.js中的使用詳解
簡(jiǎn)述
import與export是es6中模塊化的導(dǎo)入與導(dǎo)出,node.js現(xiàn)階段不支持,需要通過babel進(jìn)行編譯,使其變成node.js的模塊化代碼。(關(guān)于node.js模塊,可參考其他node.js模塊化的文章)
export 曝露
使用export可以曝露出方法、對(duì)象、字符串等等,如下代碼
//寫法1
export var foo=function(){
console.log(1);
}
//寫法2
var bar ={a:"1",b:2};
export {bar};
//寫法3
var baz='hello world';
export {baz as qux};
那么,上面的代碼經(jīng)過babel的編譯后,變成可以執(zhí)行的node.js代碼,如下
"use strict";
//標(biāo)記這個(gè)模塊是es的模塊
Object.defineProperty(exports, "__esModule", {
value: true
});
//寫法1
var foo = exports.foo = function foo() {
console.log(1);
};
//寫法2
var bar = { a: "1", b: 2 };
exports.bar = bar;
//寫法3
var baz = 'hello world';
exports.qux = baz;
看到上面的代碼我們知道了,es6的export會(huì)被轉(zhuǎn)成node.js中的exports的曝露方式。
import 導(dǎo)入
再來看下import的寫法,我們引入上面寫export的文件xx.js
第一種寫法
import {foo,qux} from './xx';
console.log(qux);
foo,qux是在xx.js中我們曝露出來的屬性,在xx.js中曝露出來的屬性有foo、bar、qux3個(gè),由此可知這種寫法需要知道引入文件中曝露出來的屬性的名稱,并且可以按需要寫,不需要枚舉全部屬性。
下面我們來看下babel編譯后的代碼:
'use strict';
var _ = require('./xx');
console.log(_.qux);
就是一個(gè)簡(jiǎn)單的require方法,引入xx.js,所以用這種方式我們是可以引入es6的模塊也可以引入node.js模塊的。
第二種寫法
import * as xx from './xx'; console.log(xx.bar);
這里還是引入xx.js,這種寫法會(huì)把xx.js中曝露出來的屬性都賦值給xx這個(gè)變量(其實(shí)就是給module.exports起個(gè)別名),被babel編譯后如下下:
'use strict';
var _ = require('./xx');
var xx = _interopRequireWildcard(_);
function _interopRequireWildcard(obj) {
//判斷是node模塊還是es模塊
if (obj && obj.__esModule) {
return obj;
}
else {
var newObj = {};
if (obj != null) {
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key))
newObj[key] = obj[key];
}
}
//兼容舊的babel編譯
newObj.default = obj;
console.log(newObj);
return newObj;
}
}
console.log(xx.bar);
看到上面的代碼,有一個(gè)判斷是node模塊還是es模塊,這種寫法也是兼容es模塊和node的模塊的。
第三種寫法
import oo from './xx' console.log(oo.bar);
在這種寫法中oo是隨意的變量,乍一看可能會(huì)覺的和第二種寫法一樣,其實(shí)不然,來看一下編譯后的代碼:
'use strict';
var _ = require('./xx');
var _2 = _interopRequireDefault(_);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj :
{ default: obj };
}
console.log(_2.default.bar);
在最后一行,oo.bar被編譯成了_2.default.bar,多了一個(gè)default,這里的bar當(dāng)然就找不到了,所以這種用法不是用來引入export的屬性的,而是下面要說的export default。
export default 曝露且一次性曝露
export與export default我會(huì)在別的文章總結(jié),這里我們只說export default的用法,下面來看代碼。
var foo=123; export default foo;
被babel編譯后
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var foo = 123;
exports.default = foo;
看到最后一行foo會(huì)被賦給exports.default,這樣正好對(duì)應(yīng)上了import oo from './xx'這種寫法里面會(huì)調(diào)用default里面的屬性,所以這兩種用法對(duì)應(yīng)使用。既然屬性的值是會(huì)賦給exports.default,那么就可以有下面的用法
export default 123;
export default {foo:123};
export default function f(){}
export default function (){}
上面的代碼是分開寫的,因?yàn)橐粋€(gè)js里面只能使用一次export default,理由和使用module.exports一樣,除了不能寫多個(gè),下面也是錯(cuò)誤的寫法:
export default var foo=123; //錯(cuò)誤
export default還可以用來曝露class這里不多說了,都是曝露。
其他的一些用法
繼承
這里說是模塊繼承,其實(shí)就是一個(gè)父模塊引入子模塊,然后又將子模塊曝露出來的屬性曝露出去:
export * from './xx';
被編譯后
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ = require('./xx');
Object.keys(_).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _[key];
}
});
});
注意下面這句
if (key === "default" || key === "__esModule") return;
default屬性不向外曝露...這說明,我們的引入的xx.js這個(gè)文件里面用exports default是無效的,替代寫法是
export {default} from './xx';
繼承的寫法常用于組織多個(gè)模塊,經(jīng)常與下面要說的引包一起用
引文件夾(引包)
很多人不理解下面這行代碼
import * as o from './oo'; //oo是個(gè)文件
為什么import可以引入文件夾,注意不是什么文件夾都可以,里面至少有一個(gè)文件就是index.js或者有package.json和另外名字的js,因?yàn)槲募A里面有index.js那么這就不是一個(gè)文件夾而是node.js的包了(更多參見node.js包的文章),import會(huì)被babel編譯成require,require可以去引用指定路徑的包,因此,import可以去導(dǎo)入一個(gè)文件夾,我們可以依賴index.js將文件夾中的其他文件代碼導(dǎo)出,例如:

//index.js export * from './1'; export * from './2';
我們可以通過import oo這個(gè)文件夾得到1.js、2.js里面曝露出的屬性。
總結(jié)
從看babel編譯后的代碼,可以看出export與exports,module.exports與export default的用法的相似,至于用什么怎么用還是看個(gè)人喜好吧。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
node.js入門教程之querystring模塊的使用方法
querystring模塊主要用來解析查詢字符串,下面這篇文章主要介紹了關(guān)于node.js中querystring模塊使用方法的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-02-02
Node.js中文件操作模塊File System的詳細(xì)介紹
FileSystem模塊是類似UNIX(POSIX)標(biāo)準(zhǔn)的文件操作API,用于操作文件系統(tǒng)——讀寫目錄、讀寫文件——Node.js底層使用C程序來實(shí)現(xiàn),這些功能是客戶端JS所不具備的。下面這篇文章就給大家詳細(xì)介紹了Node.js中的文件操作模塊File System,有需要的朋友們可以參考借鑒。2017-01-01
node.js學(xué)習(xí)總結(jié)之調(diào)式代碼的方法
調(diào)式代碼很多時(shí)候類似于查案一樣,只是結(jié)果的重要程度不同,警察查案為的是人民安穩(wěn),而我們調(diào)式則是為了系統(tǒng)的安穩(wěn)。既然這樣我們就不要冤枉任何一段代碼和程序,以免他們受到不合理的懲罰。2014-06-06
在Node.js中實(shí)現(xiàn)關(guān)注列表和粉絲列表的方法示例
在社交網(wǎng)絡(luò)或者任何需要用戶交互的應(yīng)用中,實(shí)現(xiàn)關(guān)注和被關(guān)注的功能是非常常見的需求,本文將通過一個(gè)簡(jiǎn)單的例子,展示如何在Node.js環(huán)境下實(shí)現(xiàn)用戶的關(guān)注列表和粉絲列表,需要的朋友可以參考下2024-04-04
Express進(jìn)階之log4js實(shí)用入門指南
本篇文章主要介紹了Express進(jìn)階之log4js實(shí)用入門指南,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02
使用Raygun對(duì)Node.js應(yīng)用進(jìn)行錯(cuò)誤處理的方法
這篇文章主要介紹了使用Raygun對(duì)Node.js應(yīng)用進(jìn)行錯(cuò)誤處理的方法,Node.js是一款用于服務(wù)器端的JavaScript框架,需要的朋友可以參考下2015-06-06
Node.js開發(fā)者必須了解的4個(gè)JS要點(diǎn)
這篇文章主要介紹了Node.js開發(fā)者必須了解的4個(gè)JS要點(diǎn),Node.js是一個(gè)面向服務(wù)器的框架,立足于Chrome強(qiáng)大的V8 JS引擎。盡管它由C++編寫而成,但是它及其應(yīng)用是運(yùn)行在JS上的,需要的朋友可以參考下2016-02-02

