require和import


ES6標準發(fā)布后县钥,module成為標準伺绽,標準的使用是以export指令導出接口甲馋,以import引入模塊埂奈,但是在我們一貫的node模塊中,我們采用的是CommonJS規(guī)范定躏,使用require引入模塊账磺,使用module.exports導出接口。

CommonJS

CommonJS定義的模塊分為:{模塊引用(require)} {模塊定義(exports)} {模塊標識(module)}
require()用來引入外部模塊痊远;exports對象用于導出當前模塊的方法或變量垮抗,唯一的導出口;module對象就代表模塊本身碧聪。
require統(tǒng)治了ES6之前的所有模塊化編程冒版,即使現(xiàn)在,在ES6 module被完全實現(xiàn)之前逞姿,還是這樣辞嗡。

// a.js

// -------- node -----------
module.exports = {
  a : function() {},
  b : 'xxx'
};
// b.js

// ------------ node ---------
var m = require('./a');
m.a();

require()是同步方法
ES6發(fā)布的module并沒有直接采用CommonJS,甚至連require都沒有采用滞造,也就是說require仍然只是node的一個私有的全局方法续室,module.exports也只是node私有的一個全局變量屬性

注意:module.exports方法不會多次生效,只執(zhí)行最后一行語句的導出方法谒养,這個與下面要介紹的export是有區(qū)別的挺狰,后面會介紹這個

ES6 模塊

ES6 模塊不是對象,而是通過export命令顯式指定輸出的代碼买窟,再通過import命令輸入丰泊。
模塊功能主要由兩個命令構(gòu)成:export和import。export命令用于規(guī)定模塊的對外接口始绍,import命令用于輸入其他模塊提供的功能夕吻。

// ES6模塊
import { stat, exists, readFile } from 'fs';

上面代碼的實質(zhì)是從fs模塊加載 3 個方法,其他方法不加載焊夸。這種加載稱為“編譯時加載”或者靜態(tài)加載,即 ES6 可以在編譯時就完成模塊加載满葛,效率要比 CommonJS 模塊的加載方式高。但是這樣會造成import時無法動態(tài)加載

//react native根據(jù)平臺動態(tài)加載js罢屈,無法使用import方式加載
var NativeAPI = require('./Native_API/NativeAPI.' + Platform.OS);

export導出模塊

// module "my-module.js"
function cube(x) {
  return x * x * x;
}
const foo = Math.PI + Math.SQRT2;
export { cube, foo };

注意嘀韧,export命令規(guī)定的是對外的接口,必須與模塊內(nèi)部的變量建立一一對應關(guān)系缠捌。但是module.exports是可以的

// 錯誤演示
// 報錯
export 1; // 絕對不可以

// 報錯
var a = 100;
export a;

//module.exports
var a = 1;
module.exports = a

export在導出接口的時候锄贷,必須與模塊內(nèi)部的變量具有一一對應的關(guān)系。直接導出1沒有任何意義曼月,也不可能在import的時候有一個變量與之對應谊却。 export a 雖然看上去成立,但是 a 的值是一個數(shù)字哑芹,根本無法完成解構(gòu)炎辨,因此必須寫成 export {a} 的形式。即使a被賦值為一個function聪姿,也是不允許的碴萧。

// 寫法一
export var m = 1;

// 寫法二
var m = 1;
export {m};

// 寫法三
var n = 1;
export {n as m};

注意:export可以在代碼中導出多個

var m = 1;
export {m};//導出m

var b = 2;
export //導出b

import導入模塊

import的語法跟require不同末购,而且import必須放在文件的最開始破喻,且前面不允許有其他邏輯代碼。

// import "user.js"
import { cube, foo } from 'my-module';
console.log(cube(3)); // 27
console.log(foo);    // 4.555806215962888

import后面跟上花括號的形式是最基本的用法盟榴,花括號里面的變量與export后面的變量一一對應曹质。這里,你必須了解 對象的解構(gòu)賦值 的知識擎场,也可參考阮一峰的結(jié)構(gòu)賦值

as關(guān)鍵字

簡單的說就是取一個別名羽德。export中可以用,import中其實可以用:

// a.js
var a = function() {};
export {a as fun};

// b.js
import {fun as a} from './a';
a();

export的時候顶籽,對外提供的接口是fun玩般,它是a.js內(nèi)部a這個函數(shù)的別名,但是在模塊外面礼饱,認不到a坏为,只能認到fun。
import中的as就很簡單镊绪,就是你在使用模塊里面的方法的時候匀伏,給這個方法取一個別名,好在當前的文件里面使用蝴韭。兩個不同文件可能都export同一個fun的對象

export default 命令

export default命令够颠,為模塊指定默認輸出。

// 第一組
export default function crc32() { // 輸出
  // ...
}
import crc32 from 'crc32'; // 輸入

// 第二組
export function crc32() { // 輸出
  // ...
};
import {crc32} from 'crc32'; // 輸入

default其實是as的語法糖榄鉴,這個語法糖的好處就是import的時候履磨,可以省去花括號{}蛉抓。

*符號

*代表所有

 import * as _ from 'xxx.js';//表示把xxx模塊中的所有接口掛載到 _ 這個對象上

通過*號直接繼承某一個模塊的接口

export * from '_';

// 等效于:
import * as all from '_';
export all;

盡量少用,它使用的所有的export的接口剃诅,但是你當前模塊其實并不一定需要用到所有的接口巷送,還是用{}按照需要去引用

Require Or Import

require理論上可以運用在代碼的任何地方,甚至不需要賦值給某個變量之后再使用矛辕;但是import則不同笑跛,它是編譯時的(require是運行時的),它必須放在文件開頭聊品,而且使用格式也是確定的飞蹂,不容置疑。它不會將整個模塊運行后賦值給某個變量翻屈,而是只選擇import的接口進行編譯陈哑,這樣在性能上比require好很多。

按照規(guī)范module.exports =>require妖胀,export=>import芥颈,但是現(xiàn)在開發(fā)為了兼容低版本的JS引擎會對import進行降級處理惠勒,會把import轉(zhuǎn)換成require赚抡;這樣就造成了各種方法可以混合使用,如

//import.js:導出模塊a和d
export class a {//分開導出
    constructor(arg=2) {
        this.t = 1;
        this.t2 = arg;
    }
    b(){
        console.log('b');
        console.log(this.t2);
    }
    c(){
        console.log('c')
        console.log(this.t);
    }
}
var d = function(){
};
export rrp9bvh;

//require.js:導出模塊a,d,e
class a {//分開導出
    constructor(arg=2) {
        this.t = 1;
        this.t2 = arg;
    }
    b(){
        console.log('b');
        console.log(this.t2);
    }
    c(){
        console.log('c')
        console.log(this.t);
    }
}
var d = function(){
    console.log(d)
};
var e = 1
module.exports = {a,d,e};

//index.js
var require_a = require('./require')
var import_a = require('./import')
import {a as test} from './import'
import a from './require'
import * as all_require from './require'
import * as all_import from './import'

console.log(require_a);//{a: ?, d: ?, e: 1}
console.log(import_a);//{a: ?, d: ?, __esModule: true}
console.log(test);//? a()
console.log(a);//{a: ?, d: ?, e: 1}
console.log(all_require);//{a: ?, d: ?, e: 1, default: {…}}
console.log(all_import);//{a: ?, d: ?, __esModule: true}

//a1,a2數(shù)據(jù)不影響
//constructor可傳參數(shù)纠屋,但參數(shù)名不能與變量名相同
var a1 = new test();
var a2 = new test(4);

console.log(a1.t,a1.t2);//1,2
a1.b();//b,2
a1.t=3;
a1.c();//c,3

console.log(a2.t,a2.t2);//1,4
a2.b();//b,4
a2.t=5;
a2.c();//c,5

可以看到在混用時require和import在編碼是是都可以使用的涂臣,需要注意的是require是把所有模塊加載進去,與import * 基本相同售担,但是import *會增加default屬性赁遗。import需要指定模塊名,如果不存在會返回undefined族铆。

require 取到整個對象

import a 取到default的對象岩四,如果無default對象,在編譯時會報錯

import {a} 取到 a對象

import * as XX 取到所有對象哥攘,并放到XX里面

//a.js
export default class xxxx {}

var xxx = require('./a.js');//{default:? xxx()}
import xxx from './a.js';//? xxx()

當export有default時,在使用require時剖煌,需要從default中才能取到要使用的對象,而import可以直接拿到對應的屬性

//a.js
module.exports = class a {}

var a = require('./a.js');//? xxx()
import a from './a.js';//? xxx()

如果module.exports導出的是單一的對象時逝淹,使用require和import取到的對象是同樣的耕姊,都是可以直接使用,和default的效果基本一致栅葡。

注意:webpack3在module.exports編譯時茉兰,在模塊前自增加了default屬性

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市欣簇,隨后出現(xiàn)的幾起案子规脸,更是在濱河造成了極大的恐慌坯约,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件莫鸭,死亡現(xiàn)場離奇詭異鬼店,居然都是意外死亡,警方通過查閱死者的電腦和手機黔龟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門妇智,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人氏身,你說我怎么就攤上這事巍棱。” “怎么了蛋欣?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵航徙,是天一觀的道長。 經(jīng)常有香客問我陷虎,道長到踏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任尚猿,我火速辦了婚禮窝稿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凿掂。我一直安慰自己伴榔,他們只是感情好,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布庄萎。 她就那樣靜靜地躺著踪少,像睡著了一般。 火紅的嫁衣襯著肌膚如雪糠涛。 梳的紋絲不亂的頭發(fā)上援奢,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音忍捡,去河邊找鬼集漾。 笑死,一個胖子當著我的面吹牛锉罐,可吹牛的內(nèi)容都是我干的帆竹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼脓规,長吁一口氣:“原來是場噩夢啊……” “哼栽连!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤秒紧,失蹤者是張志新(化名)和其女友劉穎绢陌,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體熔恢,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡脐湾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了叙淌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秤掌。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鹰霍,靈堂內(nèi)的尸體忽然破棺而出闻鉴,到底是詐尸還是另有隱情,我是刑警寧澤茂洒,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布孟岛,位于F島的核電站,受9級特大地震影響督勺,放射性物質(zhì)發(fā)生泄漏渠羞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一智哀、第九天 我趴在偏房一處隱蔽的房頂上張望次询。 院中可真熱鬧,春花似錦盏触、人聲如沸渗蟹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至授艰,卻和暖如春辨嗽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背淮腾。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工糟需, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谷朝。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓洲押,卻偏偏與公主長得像,于是被迫代替她去往敵國和親圆凰。 傳聞我的和親對象是個殘疾皇子杈帐,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容