[轉] webpack解惑:require的五種用法

webpack中可以寫commonjs格式的require同步語法蝠筑,可以寫AMD格式的require回調語法,還有一個require.ensure昼扛,以及webpack自己定義的require.include,再加上ES6的import語法,這么多豈不是會把人給搞亂奠衔。本篇就來梳理一下這些require各自的特點谆刨,以及都在什么場景下使用。

commonjs同步語法

經(jīng)典的commonjs同步語法如下:

var a = require('./a');
a.show();

此時webpack會將a.js打包進引用它的文件中归斤。這是最普遍的情形痊夭,不必贅述。

commonjs異步加載

在commonjs中有一個Modules/Async/A規(guī)范脏里,里面定義了require.ensure語法她我。webpack實現(xiàn)了它,作用是可以在打包的時候進行代碼分片迫横,并異步加載分片后的代碼番舆。用法如下:

require.ensure([], function(require){
    var list = require('./list');
    list.show();
});

此時list.js會被打包成一個單獨的chunk文件,大概長這樣:

1.fb874860b35831bc96a8.js

可讀性比較差矾踱。我在上一篇結尾也提到了恨狈,給它命名的方式,那就是給require.ensure傳遞第三個參數(shù)呛讲,如:

require.ensure([], function(require){
    var list = require('./list');
    list.show();
}, 'list');

這樣就能得到你想要的文件名稱:

list.fb874860b35831bc96a8.js

你也可以傳入像"question/list"這樣帶層級的名字禾怠,這樣webpack會按照層級給你創(chuàng)建文件夾

需要注意的是圣蝎,如果你在require.ensure的函數(shù)中引用了兩個以上的模塊刃宵,webpack會把它們打包在一起,比如:

require.ensure([], function(require){
    var list = require('./list');
    list.show();
    var edit = require('./edit');
    edit.display();
}, 'list_and_edit');

list.js和edit.js將會被打包成一個文件徘公,并命名為list_and_edit.js牲证。這就需要根據(jù)你的實際情況來衡量了,如果你不希望打包在一起关面,只能寫兩個require.ensure分別引用這兩個文件坦袍。

多說一句,這種思維其實我是很不喜歡的等太,在編碼階段卻要對打包的事情做出決策捂齐,明顯違背了職責分離原則。

commonjs預加載懶執(zhí)行

在上面的用法中缩抡,我們給require.ensure的第一個參數(shù)傳了空數(shù)組奠宜,實際上這里是可以接收模塊名稱的,作用就是實現(xiàn)預加載懶執(zhí)行瞻想。用法如下:

require.ensure(['./list'], function(require){
    var list = require('./list');
    list.show();
});

給require.ensure的第一個參數(shù)傳了['./list']压真,執(zhí)行到這里的時候list.js會被瀏覽器下載下來,但是并不會執(zhí)行l(wèi)ist.js模塊中的代碼蘑险,也就是webpack官網(wǎng)說的滴肿,不會進行evaluate。真正進行evaluate的時候是到了后面這句var list = require('./list');這就是所謂的懶執(zhí)行佃迄。

寫在函數(shù)中的多個模塊會被打包在一起泼差,這一點和上面沒有區(qū)別贵少。另外,寫在數(shù)組中的模塊也會跟他們打包在一起堆缘,不管你有沒有手動執(zhí)行滔灶。

這種寫法也是有點別扭的,像是commonjs和AMD的結合體套啤,而且一個模塊名稱還要寫兩次宽气,真是不夠優(yōu)雅。所以webpack自己定義了一個方法潜沦,能夠實現(xiàn)預加載萄涯。

webpack自帶的require.include

require.include是webpack自己提供的,并沒有什么規(guī)范做后臺唆鸡,所以是個小角色涝影。它可以實現(xiàn)上面是預加載功能,而不用把模塊寫在數(shù)組中争占,用法如下:

require.ensure([], function(require){
    require.include('./list');//此處只加載不執(zhí)行
});

據(jù)webpack官網(wǎng)文檔介紹燃逻,require.include還有一個作用是能把子模塊中的公共部分,提取到父模塊中臂痕,比如child1和child2都引用了list.js這個模塊伯襟,那么如果在parent中include了list.js,那么子模塊中的就會被刪掉握童,相當于提升到了父模塊中姆怪。(這里所謂的父子關系是指引用關系)

這個方法官方也是一筆帶過,看來也是一個雞肋的東西澡绩,用處不大稽揭。因為我發(fā)現(xiàn)require.include的返回值是undefined,也就是說肥卡,如果你想使用模塊溪掀,姿勢是這樣的:

require.ensure([], function(require){
    require.include('./preview'); //加載
    let p = require('./preview'); //執(zhí)行
    p.getUrl(); //使用
}, 'pre');

AMD異步加載

webpack既支持commonjs規(guī)范也支持AMD規(guī)范,這就意味著AMD的經(jīng)典語法是可以正常使用的步鉴,如:

require(['./list'], function(list){
    list.show();
});

當然揪胃,這樣寫的話list.js也是被單獨打包成一個文件的。與上面類似氛琢,如果你在這里寫了多個模塊只嚣,那么這些模塊都會被打包成一個文件,如:

require(['./list', './edit'], function(list, edit){
    list.show();
    edit.display();
});

list.js和edit.js會被打包在一起艺沼。不同的是,AMD的方式無法傳入第三個參數(shù)當文件名蕴掏,所以得不到很好看的文件障般。

ES6 import

這年頭不用ES6都不好意思跟人打招呼调鲸。所以我們的代碼中,又會多一種模塊引入語法挽荡,那就是import藐石。import會被轉化為commonjs格式或者是AMD格式,所以不要把它認為是一種新的模塊引用方式定拟。babel默認會把ES6的模塊轉化為commonjs規(guī)范的于微,你也不用費勁再把它轉成AMD了。

所以如下寫法是等價的:

import list from './list';
//等價于
var list = require('./list');

不過這兩種寫法只需選一種青自,避免在代碼中同時使用兩種株依,否則會造成混淆。

總結

以上把require的用法捋了一遍延窜,明白了各自用法的區(qū)別之后恋腕,我們就可以在項目中進行選擇了。我覺得最佳選擇是往commonjs方向靠攏逆瑞,想嘗試ES6的話就用import代替commonjs同步語法即可荠藤。

因此,代碼中保持以下兩種風格就好:

//可打包在一起的同步代碼获高,使用import語法
import list from './list';
 
//需要獨立打包哈肖、異步加載的代碼,使用require.ensure
require.ensure([], function(require){
    var list = require('./list');
});

很顯然念秧,你在寫代碼的時候還是需要對打包結果進行決策淤井,這是我不喜歡webpack的原因。gulp那樣多好出爹,編碼就是編碼庄吼,編譯就是編譯,分開來严就。不過這就是webpack以模塊為核心的打包方式的特點吧总寻,仁者見仁,只要團隊內做一個約定梢为,也不會打的一塌糊涂渐行。

轉自https://www.cnblogs.com/laneyfu/p/6262321.html

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市铸董,隨后出現(xiàn)的幾起案子祟印,更是在濱河造成了極大的恐慌,老刑警劉巖粟害,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕴忆,死亡現(xiàn)場離奇詭異,居然都是意外死亡悲幅,警方通過查閱死者的電腦和手機套鹅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門站蝠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人卓鹿,你說我怎么就攤上這事复局÷仍幔” “怎么了喜最?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵芥永,是天一觀的道長。 經(jīng)常有香客問我杰妓,道長藻治,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任稚失,我火速辦了婚禮栋艳,結果婚禮上,老公的妹妹穿的比我還像新娘句各。我一直安慰自己吸占,他們只是感情好,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布凿宾。 她就那樣靜靜地躺著矾屯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪初厚。 梳的紋絲不亂的頭發(fā)上件蚕,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音产禾,去河邊找鬼排作。 笑死,一個胖子當著我的面吹牛亚情,可吹牛的內容都是我干的妄痪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼楞件,長吁一口氣:“原來是場噩夢啊……” “哼衫生!你這毒婦竟也來了?” 一聲冷哼從身側響起土浸,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤罪针,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后黄伊,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泪酱,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了西篓。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愈腾。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖岂津,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情悦即,我是刑警寧澤吮成,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站辜梳,受9級特大地震影響粱甫,放射性物質發(fā)生泄漏。R本人自食惡果不足惜作瞄,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一茶宵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宗挥,春花似錦乌庶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至搪桂,卻和暖如春透敌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背踢械。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工酗电, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人内列。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓撵术,卻偏偏與公主長得像,于是被迫代替她去往敵國和親德绿。 傳聞我的和親對象是個殘疾皇子荷荤,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內容