瀛︿範涓嶈兘鍋滐紝閮界粰鎴戝嵎璧锋潵...
涓€銆佸墠涓栦粖鐢?/h2>
鍦?ES6 涔嬪墠锛孞avaScript 涓€鐩存病鏈夊畼鏂圭殑妯″潡锛圡odule锛変綋绯伙紝瀵逛簬寮€鍙戝ぇ鍨嬨€佸鏉傜殑椤圭洰褰㈡垚浜嗗法澶х殑闅滅銆傚垢濂界ぞ鍖轰笂鏈変竴浜涙ā鍧楀姞杞芥柟妗堬紝鏈€涓昏鐨勬湁 CommonJS锛圕ommonJS Modules锛夊拰 AMD锛圓synchronous Module Definition锛変袱绉嶆ā鍧楄鑼冿紝鍓嶈€呯敤浜庢湇鍔″櫒锛屽悗鑰呯敤浜庢祻瑙堝櫒銆?/p>
闅忕潃 ES6 鐨勬寮忓彂甯冿紝鍏ㄦ柊鐨勬ā鍧楀皢閫愭鍙栦唬 CommonJS 鍜?AMD 瑙勮寖锛屾垚涓烘祻瑙堝櫒鍜屾湇鍔″櫒閫氱敤鐨勬ā鍧楄В鍐虫柟妗堛€?/p>
ES6 妯″潡鐨勮璁℃€濇兂灏介噺鐨勯潤鎬佸寲锛屾槸鐨勭紪璇戞椂灏辫兘纭畾妯″潡鐨勪緷璧栧叧绯伙紝浠ュ強杈撳叆鍜岃緭鍑虹殑鍙橀噺銆?/p>
鍦?rollup銆?webpack 绛夋瀯寤哄伐鍏蜂腑甯歌鐨?Tree Shaking 鑳藉姏锛屽氨鏄緷璧栦簬 ES6 妯″潡鐨勯潤鎬佺壒鎬у疄鐜扮殑銆?/p>
鑰?CommonJS 鍜?AMD 妯″潡閮藉彧鑳藉湪杩愯鏃剁‘瀹氳繖浜涗笢瑗裤€傛瘮濡傦紝CommonJS 妯″潡灏辨槸瀵硅薄锛岃緭鍏ユ椂蹇呴』鏌ユ壘瀵硅薄灞炴€с€?/p>
// CommonJS 妯″潡
const { stat, exists, readFile } = require('fs')
// 鐩稿綋浜?
const _fs = require('fs')
const stat = _fs.stat
const exists = _fs.exists
const readFile = _fs.readFile
浠ヤ笂绀轰緥锛屽疄闄呬笂鏄暣浣撳姞杞戒簡 fs
妯″潡锛堝嵆鍔犺浇 fs
鐨勬墍鏈夋柟娉曪級锛岀敓鎴愪簡涓€涓璞?_fs
锛岀劧鍚庡啀浠庤繖涓璞′笂璇诲彇浜?3 涓柟娉曘€傝繖绉嶆柟寮忕О涓衡€?strong>杩愯鏃跺姞杞?/strong>鈥濓紝鍘熷洜鏄彧鏈夎繍琛屾椂鎵嶈兘寰楀埌杩欎釜瀵硅薄锛屽鑷村畬鍏ㄦ病鏈夊姙娉曞湪缂栬瘧鏃跺仛鈥滈潤鎬佷紭鍖栤€濄€?/p>
ES6 妯″潡涓嶆槸瀵硅薄锛岃€屾槸閫氳繃 export
鍛戒护鏄惧紡鎸囧畾杈撳嚭鐨勪唬鐮侊紝鍐嶉€氳繃 import
鍛戒护杈撳叆銆?/p>
import { stat, exists, readFile } from 'fs'
浠ヤ笂绀轰緥锛屽疄闄呬笂鏄粠 fs
妯″潡涓姞杞戒簡 3 涓柟娉曪紝鍏朵粬鏂规硶涓嶅姞杞姐€傝繖绉嶆柟寮忕О涓衡€?strong>缂栬瘧鏃跺姞杞?/strong>鈥濇垨鈥?strong>闈欐€佸姞杞?/strong>鈥濓紝鍗?ES6 妯″潡鍙互鍦ㄧ紪璇戞椂灏卞畬鎴愭ā鍧楀姞杞斤紝鏁堢巼瑕侀珮浜?CommonJS 妯″潡鐨勫姞杞芥柟寮忋€傝繖涔熷鑷翠簡娌℃硶寮曠敤 ES6 妯″潡鏈韩锛屽洜涓哄畠涓嶆槸瀵硅薄銆?/p>
鐢变簬 ES6 妯″潡鏄紪璇戞椂鍔犺浇锛屼娇寰楅潤鎬佸垎鏋愭垚涓哄彲鑳姐€傛湁浜嗗畠锛屽氨鑳借繘涓€姝ユ嫇瀹?JavaScript 鐨勮娉曪紝姣斿寮曞叆瀹忥紙macro锛夊拰绫诲瀷妫€楠岋紙type system锛夎繖浜涘彧鑳介潬闈欐€佸垎鏋愬疄鐜扮殑鍔熻兘銆?/p>
闄や簡闈欐€佸姞杞藉甫鏉ョ殑鍚勭濂藉锛孍S6 妯″潡杩樻湁浠ヤ笅濂藉锛?/p>
- 涓嶅啀闇€瑕?UMD 妯″潡鏍煎紡浜嗭紝灏嗘潵鏈嶅姟鍣ㄥ拰娴忚鍣ㄩ兘浼氭敮鎸?ES6 妯″潡鏍煎紡銆?/li>
- 灏嗘潵娴忚鍣ㄧ殑鏂?API 灏辫兘鐢ㄦā鍧楁牸寮忔彁渚涳紝涓嶅啀蹇呴』鍋氭垚鍏ㄥ眬鍙橀噺鎴栬€?navigator 瀵硅薄鐨勫睘鎬с€?/li>
- 涓嶅啀闇€瑕佸璞′綔涓哄懡鍚嶇┖闂达紙姣斿 Math 瀵硅薄锛夛紝鏈潵杩欎簺鍔熻兘鍙互閫氳繃妯″潡鎻愪緵銆?/li>
浜屻€佷负浠€涔堥渶瑕佹ā鍧楀寲锛?/h2>
涓句釜 馃尠
<!DOCTYPE html>
<html lang="en">
<body>
<script src="module-a.js"></script>
<script src="module-b.js"></script>
</body>
</html>
// module-a.js
var person = { name: 'Frankie', age: 20 }
// module-b.js
console.log(person.name) // 灏嗕細鎵撳嵃浠€涔堝憿锛?
鎴戜滑鍙互杞昏€屾槗涓惧氨鐭ラ亾 module-b.js
閲屽皢浼氭墦鍗板嚭 Frankie
锛屽師鍥犲緢绠€鍗曪紝瀹冧滑閮芥槸澶勪簬鍏ㄥ眬浣滅敤鍩熶笅锛屽洜姝?module-b.js
涓殑 person.name
灏辫兘璇诲彇鍒板湪 module-a.js
涓畾涔夌殑 person 鍙橀噺銆?/p>
濡傛灉灏?module-a.js
鍜?module-b.js
鍦?HTML 涓殑椤哄簭鎹㈣繃鏉ワ紝灏变細鎶涘嚭閿欒銆傚師鍥犳槸<script>
鏄寜鍧楀姞杞界殑锛屽寘鎷笅杞姐€侊紙棰勶級缂栬瘧鍜屾墽琛屻€傚敮鏈夊綋鍓嶅潡鎵ц瀹屾瘯锛屾垨鑰呮姏鍑洪敊璇紝鎵嶄細鎺ョ潃鍔犺浇涓嬩竴涓?<script>
銆?/p>
娉ㄦ剰锛岃繖閲屾彁鍒扮殑鎸夐『搴忓姞杞斤紝鏄寚娌℃湁
defer
鍜?async
灞炴€х殑鍝堛€傚畠淇╁澶栭儴鑴氭湰鐨勫姞杞芥柟寮忔槸鏈夊奖鍝嶇殑銆備絾闈炴湰鏂囪瘽棰橈紝鍥犳涓嶅睍寮€璁茶堪銆?/p>
閭i棶棰樺氨鏉ヤ簡锛岃繖寰堝鏄撻€犳垚鍏ㄥ眬姹℃煋锛屽浜庡ぇ鍨嬨€佸鏉傜殑椤圭洰鏉ヨ浼氶潪甯告鎵嬨€?/p>
鍋囪娌℃湁璇稿 CommonJS 绛夋ā鍧楀寲瑙e喅鏂规鍙敤锛岃鎬庢牱瑙e喅杩欑闂鍛紵
1. 瀵硅薄瀛楅潰閲忥紙Object Literal锛?/strong>
// 澹版槑
var namespace = {
prop: 123,
method: function () {},
// ...
}
// 璋冪敤
namespace.prop
namespace.method()
缂虹偣锛?/p>
浣滀负涓€涓崟涓€鐨勩€佹湁鏃跺緢闀跨殑鍙ユ硶缁撴瀯锛屽畠瀵瑰叾鍐呭鏂藉姞浜嗛檺鍒躲€傚唴瀹瑰繀椤诲湪 {}
涔嬮棿锛屽苟涓斿睘鎬ф垨鏂规硶涔嬮棿蹇呴』娣诲姞閫楀彿銆傚綋妯″潡鍐呭澶嶆潅璧锋潵涔嬪悗锛岀淮鎶ゆ垚鏈珮锛岀Щ鍔ㄥ唴瀹瑰彉寰楁洿鍔犲洶闅俱€?/p>
鍦ㄥ涓枃浠朵腑浣跨敤鐩稿悓鐨勫懡鍚嶇┖闂达細鍙互灏嗘ā鍧楀畾涔夊垎鏁e埌澶氫釜鏂囦欢涓紝骞舵寜濡備笅鏂瑰紡鍒涘缓鍛藉悕绌洪棿鍙橀噺锛屽垯鍙拷瑙嗗姞杞芥枃浠剁殑椤哄簭銆?/p>
var namespace = namespace || {}
浣跨敤澶氫釜妯″潡锛屽彲浠ラ€氳繃鍒涘缓鍗曚釜鍏ㄥ眬鍛藉悕绌洪棿骞跺悜鍏舵坊鍔犲瓙妯″潡鏉ラ伩鍏嶅叏灞€鍚嶇О鐨勬墿鏁c€備笉寤鸿杩涗竴姝ュ祵濂楋紝濡傛灉鍚嶇О鍐茬獊鏄竴涓棶棰橈紝鎮ㄥ彲浠ヤ娇鐢ㄦ洿闀跨殑鍚嶇О銆傝繖绉嶆柟寮忕О涓猴細宓屽鍛藉悕绌洪棿銆?/p>
// 鍏ㄥ眬鍛藉悕绌洪棿
var globalns = globalns || {}
// 娣诲姞 A 瀛愭ā鍧?
globalns.moduleA = {
// module content
}
// 娣诲姞 B 瀛愭ā鍧?
globalns.moduleB = {
// module content
}
灏界浣跨敤鍛藉悕绌洪棿鍙互鍦ㄤ竴瀹氱▼搴︿笂瑙e喅浜嗗懡鍚嶅啿绐佺殑闂锛屼絾鏄瓨鍦ㄤ竴涓棶棰橈細鍦?moduleB
涓彲浠ヤ慨鏀?moduleA
鐨勫唴瀹癸紝鑰屼笖 moduleA
鍙兘杩樿挋鍦ㄩ紦閲岋紝涓嶇煡鎯呫€?/p>
浠ヤ笂鍛藉悕绌洪棿鍐呯殑鎵€鏈夋垚鍛樺拰鏂规硶锛屾棤璁烘槸鍚︾鏈夛紝瀵瑰閮芥槸鍙闂殑銆傝繖鏄竴涓槑鏄剧殑缂虹偣锛屾ā鍧楀寲涓嶅簲璇ュ姝よ璁°€?/p>
Yahoo 鍏徃鐨?YUI 2 灏辨槸閲囩敤浜嗚繖绉嶆柟妗堛€?/p>
2. 绔嬪嵆鎵ц鍑芥暟琛ㄨ揪寮忥紙Immediately-Invoked Function Expression锛岀畝绉?IIFE锛?/strong>
鍦ㄦā鍧楁ā寮忎腑锛屾垜浠娇鐢?IIFE 灏嗙幆澧冮檮鍔犲埌妯″潡鏁版嵁銆傚彲浠ヤ粠妯″潡璁块棶璇ョ幆澧冨唴鐨勭粦瀹氾紝浣嗕笉鑳戒粠澶栭儴璁块棶銆傚彟涓€涓紭鐐规槸 IIFE 涓烘垜浠彁渚涗簡鎵ц鍒濆鍖栫殑鍦版柟銆?/p>
var namespace = (function () {
// private data
var _prop = 123
var _method = function () {}
return {
// read-only
get prop() {
return _prop
},
get method() {
return _method
}
}
})()
杩欐牱鐨勮瘽锛屾垜浠氨涓嶇敤鎷呭績锛屽湪澶栭儴鐩存帴淇敼 namespace
鍐呴儴鐨勬垚鍛樻垨鑰呮柟娉曚簡銆?/p>
// 璇诲彇
namespace.prop // 123
namespace.method()
// 鍐欏叆
namespace.prop = 456 // 鏃犳晥
namespace.method = function foo() {} // 鏃犳晥
鍥犳锛岀粨鍚堝墠闈㈢殑鍐呭锛屽氨鍙互杩欐牱鍘诲鐞嗭細
// 鍏ㄥ眬鍛藉悕绌洪棿
var globalns = globalns || {}
// 娣诲姞 A 瀛愭ā鍧?
globalns.moduleA = (function () {
// ...
return {
// ...
}
})()
// 娣诲姞 B 瀛愭ā鍧?
globalns.moduleB = (function () {
// ...
return {
// ...
}
})()
鍒扮幇鍦紝鏈変簡鍛藉悕绌洪棿瑙e喅浜嗗懡鍚嶅啿绐侀棶棰橈紝鍚屾椂浣跨敤 IIFE 鏉ョ淮鎶ゅ悇妯″潡鐨勭鏈夋垚鍛樺拰鏂规硶锛屽鍑哄澶栫殑寮€鏀炬帴鍙e嵆鍙€傝繖浼间箮鏈変簡妯″潡鍖栬鏈夌殑鏍峰瓙銆?/p>
浣嗘槸锛岃繕鏈変竴涓棶棰樸€傚墠闈㈡彁鍒拌繃 <script>
鏄寜涔﹀啓椤哄簭鍔犺浇鐨勶紙鍗充娇涓嬭浇椤哄簭鍙兘骞惰鐨勶級锛屼富瑕佸寘鎷細
- 鑴氭湰涓嬭浇
- 鑴氭湰瑙f瀽锛堢紪璇戝拰鎵ц锛?/li>
鍋囪鎴戜滑鐨勮剼鏈涓嬶細
<!DOCTYPE html>
<html lang="en">
<body>
<script src="module-a.js"></script>
<script src="module-b.js"></script>
</body>
</html>
閭d箞鎴戜滑鐨?modueA
鍦紙棣栨锛夎В鏋愮殑鏃跺€欙紝灏辨病鍔炴硶璋冪敤 moduleB
鐨勫唴瀹癸紝鍥犱负瀹冨帇鏍硅繕娌¤В鏋愭墽琛屻€備竴鏃﹂」鐩鏉傚害銆佹ā鍧楁暟閲忎笂鏉ヤ箣鍚庯紝妯″潡涔嬮棿鐨勪緷璧栧叧绯诲氨寰堥毦缁存姢浜嗐€?/p>
涓夈€佺ぞ鍖烘ā鍧楀寲鏂规
鍦?ES2015 涔嬪墠锛岀ぞ鍖轰笂宸茬粡鏈変簡寰堝妯″潡鍖栨柟妗堬紝娴佽鐨勪富瑕佹湁浠ヤ笅鍑犱釜锛氾細
- CommonJS
- AMD锛圓synchronous Module Definition锛?/li>
- CMD锛圕ommon Module Definition锛?/li>
- UMD锛圲niversal Module Definition锛?/li>
鍏朵腑 CommonJS 瑙勮寖鍦?Node.js 鐜涓嬪彇寰椾簡寰堜笉閿欑殑瀹炶返锛屽畠鍙兘搴旂敤浜庢湇鍔″櫒绔紝鑰屼笉鏀寔娴忚鍣ㄧ幆澧冦€侰ommonJS 瑙勮寖鐨勬ā鍧楁槸鍚屾鍔犺浇鐨勶紝鐢变簬鏈嶅姟鍣ㄧ殑妯″潡鏂囦欢瀛樺湪浜庢湰鍦扮‖鐩橈紝鍙湁纾佺洏 I/O 鐨勶紝鍥犳鍚屾鍔犺浇鏈哄埗娌′粈涔堥棶棰樸€?/p>
浣嗗湪娴忚鍣ㄧ幆澧冿紝涓€鏄細浜х敓寮€閿€鏇村ぇ鐨勭綉缁?I/O锛屼簩鏄ぉ鐒跺紓姝ワ紝灏变細浜х敓鏃跺簭涓婄殑閿欒銆傚悗鏉ョぞ鍖轰笂鎺ㄥ嚭浜嗗紓姝ュ姞杞姐€佸彲鍦ㄦ祻瑙堝櫒鐜杩愯鐨?RequireJS 妯″潡鍔犺浇鍣紝涓嶄箙涔嬪悗锛岃捣鑽夊苟鍙戝竷浜?AMD 妯″潡鍖栨爣鍑嗚鑼冦€?/p>
鐢变簬 AMD 浼氭彁鍓嶅姞杞斤紝寰堝寮€鍙戣€呮媴蹇冩湁鎬ц兘闂銆傚亣璁句竴涓ā鍧椾緷璧栦簡鍙﹀ 5 涓ā鍧楋紝涓嶇杩欎簺妯″潡鏄惁椹笂琚敤鍒帮紝閮戒細鎵ц涓€閬嶏紝杩欎簺鎬ц兘娑堣€楁槸涓嶅蹇借鐨勩€備负浜嗛伩鍏嶈繖涓棶棰橈紝鏈夐儴鍒嗕汉璇曞浘淇濈暀 CommonJS 涔﹀啓鏂瑰紡鍜屽欢杩熷姞杞姐€佸氨杩戝0鏄庯紙灏辫繎渚濊禆锛夌瓑鐗规€э紝骞跺紩鍏ュ紓姝ュ姞杞芥満鍒讹紝浠ラ€傞厤娴忚鍣ㄧ壒鎬с€傛瘮濡傦紝宸茬粡鍑夊噳鐨?BravoJS銆丗lyScript 绛夋柟妗堛€?/p>
鍦?2011 骞达紝鍥藉唴鐨勫墠绔ぇ浣帀浼彁鍑轰簡 SeaJS锛屽畠鍊熼壌浜?CommonJS銆丄MD锛屽苟鎻愬嚭浜?CMD 妯″潡鍖栨爣鍑嗚鑼冦€備絾骞舵病鏈夊ぇ鑼冨洿鐨勬帹骞垮拰浣跨敤銆?/p>
鍦?2014 骞达紝缇庣睄鍗庤 Homa Wong 鎻愬嚭浜?UMD 鏂规锛氬皢 CommonJS 鍜?AMD 鐩哥粨鍚堛€傛湰璐ㄤ笂杩欎笉绠楁槸涓€绉嶆ā鍧楀寲鏂规銆?/p>
鍒颁簡 2015 骞?6 鏈堬紝闅忕潃 ECMAScript 2015 鐨勬寮忓彂甯冿紝JavaScript 缁堜簬鍘熺敓鏀寔妯″潡鍖栵紝琚О涓?ES Module銆傚悓鏃舵敮鎸佹湇鍔″櫒绔拰娴忚鍣ㄧ銆?/p>
灏界鍒颁簡 2022 骞达紝鐜扮姸浠嶇劧鏄绉嶆ā鍧楀寲鏂规鍏卞瓨锛屼絾鏈潵鑲畾鏄?ES Module 涓€缁熸睙婀?..
鍏充簬 JavaScript 妯″潡鍖栧巻鍙茬嚎锛屽彲浠ョ湅涓嬭繖绡囨枃绔犮€?/p>
鍥涖€丆ommonJS
Node.js 鐨勬ā鍧楃郴缁熸槸鍩轰簬 CommonJS 瑙勮寖鐨勫疄鐜扮殑銆傞櫎姝や箣澶栵紝鍍?CouchDB 绛変篃鏄?CommonJS 鐨勪竴绉嶅疄鐜般€傝€屼笖瀹冧滑鏈変竴浜涙槸娌℃湁瀹屽叏鎸夌収 CommonJS 瑙勮寖鍘诲疄鐜扮殑锛岀敋鑷抽澶栨坊鍔犱簡鐗规湁鐨勫姛鑳姐€?/p>
鐢变簬鎴戜滑鎺ヨЕ鍒扮殑 CommonJS 閫氬父鎸?Node.js 涓殑妯″潡鍖栬В鍐虫柟娉曪紝鍥犳锛屾帴涓嬫潵鎻愬埌鐨?CommonJS 鍧囨寚 Node.js 鐨勬ā鍧楃郴缁熴€?/p>
鍏堢瀰涓€涓嬶紝涓€涓?CommonJS 妯″潡閲岄潰閮藉寘鎷竴浜涗粈涔堜俊鎭細
濡傛灉鏈変竴浜涚湅涓嶆噦鎴栦笉浜嗚В鍏剁敤澶勭殑锛屽厛涓嶆€ワ紝涓嬮潰濞撳〒閬撴潵銆?/p>
CommonJS 鐨勬ā鍧楃壒鐐癸細
- 姣忎竴涓?JavaScript 鏂囦欢灏辨槸涓€涓嫭绔嬫ā鍧楋紝鍏朵綔鐢ㄥ煙浠呭湪妯″潡鍐咃紝涓嶄細姹℃煋鍏ㄥ眬浣滅敤鍩熴€?/li>
- 涓€涓ā鍧楀寘鎷?
require
銆?code>module銆?code>exports 涓変釜鏍稿績鍙橀噺銆?/li>- 鍏朵腑
module.exports
銆?code>exports 璐熻矗妯″潡鐨勫唴瀹瑰鍑恒€傚悗鑰呭彧鏄墠鑰呯殑鈥滃埆鍚嶁€濓紝鑻ヤ娇鐢ㄤ笉褰擄紝杩樺彲鑳戒細瀵艰嚧鏃犳硶瀵煎嚭棰勬湡鍐呭銆傚叾涓?require
璐熻矗鍏朵粬妯″潡鍐呭鐨勫鍏ワ紝鑰屼笖鍏跺鍏ョ殑鏄叾浠栨ā鍧楃殑module.exports
瀵硅薄銆?/li>- 妯″潡鍙互鍔犺浇澶氭锛屼絾鍙細鍦ㄧ涓€娆″姞杞芥椂杩愯涓€娆★紝鐒跺悗杩愯缁撴灉灏变細琚紦瀛樿捣鏉ャ€備笅娆″啀鍔犺浇鏄洿鎺ヨ鍙栫紦瀛樼粨鏋溿€傛ā鍧楃紦瀛樻槸鍙互琚竻闄ょ殑銆?/li>
- 妯″潡鐨勫姞杞芥槸鍚屾鐨勶紝鑰屼笖鏄寜缂栧啓椤哄簭杩涜鍔犺浇銆?/li>
4.1 Module 瀵硅薄
鍓嶉潰鎵撳嵃鐨?module
灏辨槸 Module
鐨勫疄渚嬪璞°€傛瘡涓ā鍧楀唴閮紝閮芥湁涓€涓?module
瀵硅薄锛岃〃绀哄綋鍓嶆ā鍧椼€傚畠鏈変互涓嬪睘鎬э細
// Module 鏋勯€犲嚱鏁?
function Module(id = '', parent) {
this.id = id
this.path = path.dirname(id)
this.exports = {}
moduleParentCache.set(this, parent)
updateChildren(parent, this, false)
this.filename = null
this.loaded = false
this.children = []
}
婧愮爜 馃憠 node/lib/internal/modules/cjs/loader.js锛圢ode.js v17.x锛?/p>
module.id
锛氳繑鍥炲瓧绗︿覆锛岃〃绀烘ā鍧楃殑鏍囪瘑绗︼紝閫氬父杩欐槸瀹屽叏瑙f瀽鐨勬枃浠跺悕銆?br>module.path
锛氳繑鍥炲瓧绗︿覆锛岃〃绀烘ā鍧楃殑鐩綍鍚嶇О锛岄€氬父涓?module.id
鐨?path.dirname()
鐩稿悓銆?br>module.exports
锛氭ā鍧楀澶栬緭鍑虹殑鎺ュ彛锛岄粯璁ゅ€间负{}
銆傞粯璁ゆ儏鍐典笅锛?code>module.exports 涓?exports
鏄浉绛夌殑銆?br>module.filename
锛氳繑鍥炲瓧绗︿覆锛岃〃绀烘ā鍧楃殑瀹屽叏瑙f瀽鏂囦欢鍚嶏紙鍚粷瀵硅矾寰勶級銆?br>module.loaded
锛氳繑鍥炲竷灏斿€硷紝琛ㄧず妯″潡鏄惁宸插畬鎴愬姞杞芥垨姝e湪鍔犺浇銆?br>module.children
锛氳繑鍥炴暟缁勶紝琛ㄧず褰撳墠妯″潡寮曠敤鐨勫叾浠栨ā鍧楃殑瀹炰緥瀵硅薄銆?br>module.parent
锛氳繑鍥?null
鎴栨暟缁勩€傝嫢杩斿洖鍊间负鏁扮粍鏃讹紝琛ㄧず褰撳墠妯″潡琚叾浠栨ā鍧楀紩鐢ㄤ簡锛岃€屼笖姣忎釜鏁扮粍鍏冪礌琛ㄧず琚紩鐢ㄦā鍧楀搴旂殑瀹炰緥瀵硅薄銆?br>module.paths
锛氳繑鍥炴暟缁勶紝琛ㄧず妯″潡鐨勬悳绱㈣矾寰勶紙鍚粷瀵硅矾寰勶級銆?br>module.isPreloading
锛氳繑鍥炲竷灏斿€硷紝濡傛灉妯″潡鍦?Node.js 棰勫姞杞介樁娈佃繍琛岋紝鍒欎负 true銆?/p>
娉ㄦ剰鐐?/strong>
- 璧嬪€肩粰
module.exports
蹇呴』绔嬪嵆瀹屾垚锛屼笉鑳藉湪浠讳綍鍥炶皟涓畬鎴愶紙搴斿湪鍚屾浠诲姟涓畬鎴愶級銆?br> 姣斿锛屽湪setTimeout
鍥炶皟涓module.exports
杩涜璧嬪€兼槸鈥滀笉璧蜂綔鐢ㄢ€濈殑锛屽師鍥犳槸 CommonJS 妯″潡鍖栨槸鍚屾鍔犺浇鐨勩€?/li>
璇风湅绀轰緥锛?/p>
// module-a.js
setTimeout(() => {
module.exports = { welcome: 'Hello World' }
}, 0)
// module-b.js
const a = require('./a')
console.log(a.welcome) // undefined
// 鉂?閿欒绀轰緥
鍐嶇湅涓ず渚嬶細
// module-a.js
const EventEmitter = require('events')
module.exports = new EventEmitter() // 鍚屾浠诲姟涓畬鎴愬 module.exports 鐨勮祴鍊?
setTimeout(() => {
module.exports.emit('ready') // 鉂?杩欎釜浼氱敓鏁堝悧锛?
}, 1000)
// module-b.js
const a = require('./module-a')
a.on('ready', () => {
console.log('module a is ready')
})
// 鈿狅笍 鎵ц `node module-b.js` 鍛戒护杩愯鑴氭湰锛屼互涓?ready 浜嬩欢鍙互姝e父鍝嶅簲锛?
// 鍘熷洜 require() 浼氬妯″潡杈撳嚭鍊艰繘琛屸€滄祬鎷疯礉鈥濓紝鍥犳 module-a.js 涓殑 setTimeout 鏄彲浠ユ洿鏂?EventEmitter 瀹炰緥瀵硅薄鐨勩€?
- 褰?
module.exports
灞炴€ц鏂板璞″畬鍏ㄦ浛鎹㈡椂锛岄€氬父涔熶細鈥滆嚜鍔ㄢ€濋噸鏂板垎閰?exports
锛堣嚜鍔ㄦ槸鎸囦笉鏄惧紡鍒嗛厤鏂板璞$粰exports
鍙橀噺鐨勫墠鎻愪笅锛夈€備絾鏄紝濡傛灉浣跨敤exports
鍙橀噺瀵煎嚭鏂板璞★紝鍒欏繀椤烩€滄墜鍔ㄢ€濆叧鑱?module.exprots
鍜?exports
锛屽惁鍒欐棤娉曟寜棰勬湡杈撳嚭妯″潡鍊笺€?/li>
璇风湅绀轰緥锛?/p>
// 1锔忊儯 浠ヨ繖绉嶆柟寮忚繘琛屾ā鍧楃殑杈撳嚭锛宮odule.exports 涓?exports 浼氳嚜鍔ㄥ垎閰嶏紝鍗?module.exports === exports
module.exports = {
// ...
}
// 2锔忊儯 浠ヨ繖绉嶆柟寮忓鍑虹殑鍊硷紝灏嗕細鏄┖瀵硅薄 {}锛岃€屼笉鏄?{ sayHi: <Function> }
// 姝ゆ椂 module.exports !== exports
exports = { sayHi: function () {} } // 鉂?
// 3锔忊儯 瑙e喅浠ヤ笂闂锛岄渶瑕佹墜鍔ㄥ叧鑱?module.exprots 鍜?exports锛屼娇寰椾簩鑰呯浉绛?
module.exports = exports = { sayHi: function () {} } // 鉁?
- 鐢变互涓婄ず渚嬩篃鍙互鐪嬪嚭锛?code>require() 鏂规硶寮曠敤鐨勬槸
module.exports
瀵硅薄锛岃€屼笉鏄?exports
鍙橀噺銆?/li> - 鍒╃敤
module.parent
杩斿洖null
鎴栨暟鍊肩殑鐗规€э紝鍙互鍒ゆ柇褰撳墠妯″潡鏄惁涓哄叆鍙h剼鏈€傚彟澶栵紝涔熷彲浠ラ€氳繃require.main
鏉ヨ幏鍙栧叆鍙h剼鏈殑瀹炰緥瀵硅薄銆?/li>
module.exports 涓?exports 鐨勬敞鎰忕偣
姝ゅ墠宸插啓杩囦竴绡囨枃绔犲幓浠嬬粛瀹冧咯鐨勫尯鍒簡銆?/p>
涓€鍙ヨ瘽鎬荤粨锛?strong>
exports
鍙橀噺鍙槸module.exports
灞炴€х殑涓€涓埆鍚嶏紝浠呮鑰屽凡銆?/strong>
鎴戜滑鍙互杩欐牱瀵规ā鍧楄繘琛岃緭鍑猴細
module.exports = {
name: 'Frankie',
age: 20,
sayHi: () => console.log('Hi~')
}
// 鐩稿綋浜?
exports.name = 'Frankie'
exports.age = 20
exports.sayHi = () => console.log('Hi~')
浣嗚娉ㄦ剰锛岃嫢妯″潡鍙澶栬緭鍑轰竴涓帴鍙o紝浣跨敤涓嶅綋锛屽彲鑳戒細鏃犳硶鎸夐鏈熷伐浣溿€傛瘮濡傦細
// 鉂?浠ヤ笅妯″潡鐨勮緭鍑烘槸鈥滄棤鏁堚€濈殑锛屾渶缁堣緭鍑哄€间粛鏄?{}
exports = function () { console.log('Hi~') }
鍘熷洜寰堢畝鍗曪紝鍦ㄩ粯璁ゆ儏鍐典笅 module.exports
灞炴€у拰 exports
鍙橀噺閮芥槸鍚屼竴涓┖瀵硅薄 {}
锛堥粯璁ゅ€硷級鐨?strong>寮曠敤锛坮eference锛夛紝鍗?module.exports === exports
銆?/p>
褰撳 exports
鍙橀噺閲嶆柊璧嬩簣涓€涓熀鏈€兼垨寮曠敤鍊肩殑鏃跺€欙紝 module.exports
鍜?exports
涔嬮棿鐨勮仈绯昏鍒囨柇浜嗭紝姝ゆ椂 module.exports !== exports
锛屽湪褰撳墠妯″潡涓?module.exports
鐨勫€间粛涓?{}
锛岃€?exports
鍙橀噺鐨勫€煎彉涓哄嚱鏁般€傝€?require()
鏂规硶鐨勮繑鍥炲€兼槸鎵€寮曠敤妯″潡鐨?module.exports
鐨勬祬鎷疯礉缁撴灉銆?/p>
姝g‘濮垮娍搴旇鏄細
module.exports = export = function () { console.log('Hi~') } // 鉁?
浣跨敤绫讳技澶勭悊锛屼娇寰?module.exports
涓?exports
閲嶆柊寤虹珛鍏宠仈鍏崇郴銆?/p>
杩欓噷骞朵笉瀛樺湪浠讳綍闅剧偣锛屼粎浠呮槸 JavaScript 鍩烘湰鏁版嵁绫诲瀷鍜屽紩鐢ㄦ暟鎹被鍨嬬殑鐗规€х舰浜嗐€傚鏋滀綘杩樻槸鍒嗕笉娓呮鐨勮瘽锛屽缓璁彧浣跨敤 module.exports
杩涜瀵煎嚭锛岃繖鏍风殑璇濓紝灏变笉浼氭湁闂浜嗐€?/p>
4.2 require 鏌ユ壘绠楁硶
require()
鍙傛暟寰堢畝鍗曪紝閭d箞 require()
鍐呴儴鏄浣曟煡鎵炬ā鍧楃殑鍛紵
绠€鍗曞彲浠ュ垎涓哄嚑绫伙細
鍔犺浇 Node 鍐呯疆妯″潡
褰㈠紡濡傦細require('fs')
銆?code>require('http') 绛夈€?/p>鐩稿璺緞銆佺粷瀵硅矾寰勫姞杞芥ā鍧?br> 褰㈠紡濡傦細
require('./file')
銆?code>require('../file')銆?code>require('/file')銆?/p>鍔犺浇绗笁鏂规ā鍧楋紙鍗抽潪鍐呯疆妯″潡锛?br> 褰㈠紡濡傦細
require('react')
銆?code>require('lodash/debounce')銆?code>require('some-library')銆?code>require('#some-library') 绛夈€?/p>
鍏朵腑锛岀粷瀵硅矾寰勫舰寮忓湪瀹為檯椤圭洰涓嚑涔庝笉浼氫娇鐢紙鍙嶆鎴戞槸娌$敤杩囷級銆佽€?require('#some-library')
褰㈠紡鐩墠浠嶅湪璇曢獙闃舵...
浠ヤ笅鍩轰簬 Node.js 瀹樼綉 鐩稿叧鍐呭缈昏瘧骞舵暣鐞嗙殑鐗堟湰锛堝瓨妗o級
鍦烘櫙锛氬湪 `Y.js` 鏂囦欢涓嬶紝`require(X)`锛孨ode.js 鍐呴儴妯″潡鏌ユ壘绠楁硶锛?
1. 濡傛灉 `X` 涓哄唴缃ā鍧楃殑璇濓紝绔嬪嵆杩斿洖璇ユā鍧楋紱
鍥犳锛屽線 NPM 骞冲彴涓婂彂鍖呯殑璇濓紝`package.json` 涓殑 `name` 瀛楁涓嶈兘涓?Node.js 鍐呯疆妯″潡鍚屽悕銆?
2. 濡傛灉 `X` 鏄互缁濆璺緞鎴栫浉瀵硅矾寰勫舰寮忥紝鏍规嵁 `Y` 鎵€鍦ㄧ洰褰曚互鍙?`X` 鐨勫€间互纭畾鎵€瑕佹煡鎵剧殑妯″潡璺緞锛堢О涓?`Z`锛夈€?
a. 灏?`Z` 褰撲綔銆屾枃浠躲€嶏紝鎸?`Z`銆乣Z.js`銆乣Z.json`銆乣Z.node` 椤哄簭鏌ユ壘鏂囦欢锛岃嫢鎵惧埌绔嬪嵆杩斿洖鏂囦欢锛屽惁鍒欑户缁線涓嬫煡鎵撅紱
b. 灏?`Z` 褰撲綔銆岀洰褰曘€嶏紝
1锛夋煡鎵?`Z/package.json` 鏄惁瀛樺湪锛岃嫢 `package.json` 瀛樺湪涓斿叾 `main` 瀛楁鍊间笉涓鸿櫄鍊硷紝灏嗕細鎸夌収鍏跺€肩‘瀹氭ā鍧椾綅缃紝鍚﹀垯缁х画寰€涓嬶紱
2锛夋寜 `Z/index.js`銆乣Z/index.json`銆乣Z/index.node` 椤哄簭鏌ユ壘鏂囦欢锛岃嫢鎵惧埌绔嬪嵆杩斿洖鏂囦欢锛屽惁鍒欎細鎶涘嚭寮傚父 "not found"銆?
3. 鑻?`X` 鏄互 `#` 鍙峰紑澶寸殑锛屽皢浼氭煡鎵炬渶闈犺繎 `Y` 鐨?`package.json` 涓殑 `imports` 瀛楁涓?`node`銆乣require` 瀛楁鐨勫€肩‘璁ゆā鍧楃殑鍏蜂綋浣嶇疆銆?
锛堣繖涓€绫荤幇闃舵鐢ㄥ緱姣旇緝灏戯紝鍚庨潰鍐嶅睍寮€浠嬬粛涓€涓嬶級
// https://github.com/nodejs/node/pull/34117
4. 鍔犺浇鑷韩寮曠敤 `LOAD_PACKAGE_SELF(X, dirname(Y))`
a. 濡傛灉褰撳墠鎵€鍦ㄧ洰褰曞瓨鍦?`package.json` 鏂囦欢锛岃€屼笖 `package.json` 涓瓨鍦?`exports` 瀛楁锛?
鍏朵腑 `name` 瀛楁鐨勫€艰繕瑕佹槸 `X` 寮€澶翠竴閮ㄥ垎锛?
婊¤冻鍓嶇疆鏉′欢涓嬶紝灏变細鍖归厤 subpath 瀵瑰簲鐨勬ā鍧楋紙鏃犲尮閰嶉」浼氭姏鍑哄紓甯革級銆?
锛堣繖閲屾彁鍒扮殑 subpath 涓?5.b.1).1.1 绫讳技锛?
b. 鑻ヤ笉婊¤冻 a 涓换鎰忎竴涓潯浠跺潎涓嶆弧瓒筹紝姝ラ 4 鎵ц瀹屾瘯锛岀户缁線涓嬫煡鎵俱€?
5. 鍔犺浇 node_modules `LOAD_NODE_MODULES(X, dirname(Y))`
a. 浠庡綋鍓嶆ā鍧楁墍鍦ㄧ洰褰曪紙鍗?`dirname(Y)`锛夊紑濮嬶紝閫愬眰鏌ユ壘鏄惁 `node_modules/X` 鏄惁瀛樺湪锛?
鑻ユ壘鍒板氨杩斿洖锛屽惁鍒欑户缁線鐖剁骇鐩綍鏌ユ壘 `node_modules/X` 锛屼緷娆$被鎺紝鐩村埌鏂囦欢绯荤粺鏍圭洰褰曘€?
b. 浠庡叏灞€鐩綍锛堟寚 `NODE_PATH` 鐜鍙橀噺鐩稿叧鐨勭洰褰曪級缁х画鏌ユ壘銆?
鑻?`LOAD_NODE_MODULES` 杩囩▼鏌ユ壘鍒版ā鍧?X锛堝彲寰楀埌 X 瀵瑰簲鐨勭粷瀵硅矾寰勶紝鍋囧畾涓?M锛夛紝灏嗘寜浠ヤ笅姝ラ鏌ユ壘鏌ユ壘锛?
1) 鑻?Node.js 鐗堟湰鏀寔 `exports` 瀛楁锛圢ode.js 12+锛夛紝
1.1 灏濊瘯灏?`M` 鎷嗗垎涓?name 鍜?subpath 褰㈠紡锛堜笅绉?name 涓?`NAME`锛?
姣斿 `my-pkg` 鎷嗗垎鍚庯紝name 涓?`my-pkg`锛宻ubpath 鍒欎负绌猴紙涓虹┖鐨勮瘽锛屽搴? `exports` 鐨?"." 瀵煎嚭锛夈€?
姣斿 `my-pkg/sub-module` 鎷嗗垎鍚庯紝name 涓?`my-pkg`锛宻ubpath 涓?`sub-module`銆?
璇锋敞鎰忓甫 Scope 鐨勫寘锛屾瘮濡?`@myorg/my-pkg/sub-module` 鎷嗗垎鍚?name 搴斾负 `@myorg/my-pkg`锛宻ubpath 涓?`sub-module`銆?
1.2 濡傛灉鍦?M 鐩綍涓嬪瓨鍦?`NAME/package.json` 鏂囦欢锛岃€屼笖 `package.json` 鐨?`exports` 瀛楁鏄湡鍊硷紝
鐒跺悗鏍规嵁 subpath 鍖归厤 `exports` 瀛楁閰嶇疆锛屾壘鍒板搴旂殑妯″潡锛堣嫢 subpath 鍖归厤涓嶄笂鐨勫皢浼氭姏鍑哄紓甯革級銆?
璇锋敞鎰忥紝鐢变簬 `exports` 鏀寔鏉′欢瀵煎嚭锛岃€屼笖杩欓噷鏌ユ壘鐨勬槸 CommonJS 妯″潡锛?
鍥犳 `exports` 鐨?`node`銆乣require`銆乣default` 瀛楁閮芥槸鏀寔鐨勶紝閿『搴忔洿鏃╁畾涔夌殑浼樺厛绾ф洿楂樸€?
1.3 濡傛灉浠ヤ笂浠绘剰涓€涓潯浠朵笉婊¤冻鐨勮瘽锛屽皢缁х画鎵ц 2) 姝ラ
2) 灏?X 浠ョ粷瀵硅矾寰勭殑褰㈠紡鏌ユ壘妯″潡锛堝嵆鍓嶉潰鐨勬楠?2锛夛紝鑻ユ壘涓嶅埌姝ラ 5 鎵ц瀹屾瘯锛屽皢浼氳窇鍒版楠?6銆?
6. 鎶涘嚭寮傚父 "not found"
濡傛灉涓嶆槸寮€鍙?NPM 鍖咃紝鍦ㄥ疄闄呬娇鐢ㄤ腑鐨勮瘽锛岃涓嶅苟娌℃湁浠ヤ笂閭d箞澶氬鏉傜殑姝ラ锛屽緢瀹规槗鐞嗚В銆備絾娣卞叆浜嗚В涔嬪悗鏈夊姪浜庡钩甯搁亣鍒伴棶棰樻洿蹇帓鏌ュ嚭鍘熷洜骞跺鐞嗘帀銆傚鏋滀綘鏄彂鍖呯殑璇濓紝鍙互鍒╃敤 exports
绛夋寜涓€瀹氱殑绛栫暐瀵煎嚭妯″潡銆?/p>
鎯充簡瑙?Node.js package.json 鐨勪袱涓瓧娈电殑鎰忎箟锛岃鐪嬶細
- exports锛圢ode.js 12 璧锋敮鎸侊級
- imports
4.3 require 婧愮爜
婧愮爜 馃憠 node/lib/internal/modules/cjs/loader.js锛圢ode.js v17.x锛?/p>
// Loads a module at the given file path. Returns that module's `exports` property.
Module.prototype.require = function (id) {
validateString(id, 'id')
if (id === '') {
throw new ERR_INVALID_ARG_VALUE('id', id, 'must be a non-empty string')
}
requireDepth++
try {
return Module._load(id, this, /* isMain */ false)
} finally {
requireDepth--
}
}
婧愮爜 馃憠 node/lib/internal/modules/cjs/loader.js锛圢ode.js v17.x锛?/p>
/**
* 妫€鏌ユ墍璇锋眰鏂囦欢鐨勭紦瀛?
* 1. 濡傛灉缂撳瓨涓凡瀛樺湪璇锋眰鐨勬枃浠讹紝杩斿洖鍏跺鍑哄璞★紙module.exports锛?
* 2. 濡傛灉璇锋眰鐨勬槸鍘熺敓妯″潡锛岃皟鐢?`NativeModule.prototype.compileForPublicLoader()` 骞惰繑鍥炲叾瀵煎嚭瀵硅薄
* 3. 鍚﹀垯锛屼负璇ユ枃浠跺垱寤轰竴涓柊妯″潡骞跺皢鍏朵繚瀛樺埌缂撳瓨涓€?鐒跺悗璁╁畠鍦ㄨ繑鍥炲叾瀵煎嚭瀵硅薄涔嬪墠鍔犺浇鏂囦欢鍐呭銆?
*/
Module._load = function (request, parent, isMain) {
let relResolveCacheIdentifier
if (parent) {
debug('Module._load REQUEST %s parent: %s', request, parent.id)
// Fast path for (lazy loaded) modules in the same directory. The indirect
// caching is required to allow cache invalidation without changing the old
// cache key names.
relResolveCacheIdentifier = `${parent.path}\x00${request}`
const filename = relativeResolveCache[relResolveCacheIdentifier]
if (filename !== undefined) {
const cachedModule = Module._cache[filename]
if (cachedModule !== undefined) {
updateChildren(parent, cachedModule, true)
if (!cachedModule.loaded) return getExportsForCircularRequire(cachedModule)
return cachedModule.exports
}
delete relativeResolveCache[relResolveCacheIdentifier]
}
}
// 1锔忊儯 鑾峰彇 require(id) 涓?id 鐨勭粷瀵硅矾寰勶紙filename 浣滀负妯″潡鐨勬爣璇嗙锛?
const filename = Module._resolveFilename(request, parent, isMain)
if (StringPrototypeStartsWith(filename, 'node:')) {
// Slice 'node:' prefix
const id = StringPrototypeSlice(filename, 5)
const module = loadNativeModule(id, request)
if (!module?.canBeRequiredByUsers) {
throw new ERR_UNKNOWN_BUILTIN_MODULE(filename)
}
return module.exports
}
// 2锔忊儯 缂撳姩鏄惁瀛樺湪缂撳瓨
// 鎵€鏈夊姞杞借繃鐨勬ā鍧楅兘缂撳瓨浜?Module._cache 涓紝浠ユā鍧楃殑缁濆璺緞浣滀负閿€硷紙cache key锛?
const cachedModule = Module._cache[filename]
if (cachedModule !== undefined) {
updateChildren(parent, cachedModule, true)
if (!cachedModule.loaded) {
const parseCachedModule = cjsParseCache.get(cachedModule)
if (!parseCachedModule || parseCachedModule.loaded) return getExportsForCircularRequire(cachedModule)
parseCachedModule.loaded = true
} else {
// 鑻ヨ妯″潡缂撳瓨杩囷紝鍒欑洿鎺ヨ繑鍥炶妯″潡鐨?module.exports 灞炴€?
return cachedModule.exports
}
}
// 3锔忊儯 鍔犺浇 Node.js 鍘熺敓妯″潡锛堝唴缃ā鍧楋級
const mod = loadNativeModule(filename, request)
if (mod?.canBeRequiredByUsers) return mod.exports
// 4锔忊儯 鑻ヨ姹傛ā鍧楁棤缂撳瓨锛岃皟鐢?Module 鏋勯€犲嚱鏁扮敓鎴愭ā鍧楀疄渚?module
const module = cachedModule || new Module(filename, parent)
// 濡傛灉鏄叆鍙h剼鏈紝灏嗗叆鍙fā鍧楃殑 id 缃负 "."
if (isMain) {
process.mainModule = module
module.id = '.'
}
// 5锔忊儯 灏嗘ā鍧楀瓨鍏ョ紦瀛樹腑
// 鈿狅笍鈿狅笍鈿狅笍 鍦ㄦā鍧楁墽琛屼箣鍓嶏紝鎻愬墠鏀惧叆缂撳瓨锛屼互澶勭悊銆屽惊鐜紩鐢ㄣ€嶇殑闂
// See, http://nodejs.cn/api/modules.html#cycles
Module._cache[filename] = module
if (parent !== undefined) {
relativeResolveCache[relResolveCacheIdentifier] = filename
}
let threw = true
try {
// 6锔忊儯 鎵ц妯″潡
module.load(filename)
threw = false
} finally {
if (threw) {
delete Module._cache[filename]
if (parent !== undefined) {
delete relativeResolveCache[relResolveCacheIdentifier]
const children = parent?.children
if (ArrayIsArray(children)) {
const index = ArrayPrototypeIndexOf(children, module)
if (index !== -1) {
ArrayPrototypeSplice(children, index, 1)
}
}
}
} else if (
module.exports &&
!isProxy(module.exports) &&
ObjectGetPrototypeOf(module.exports) === CircularRequirePrototypeWarningProxy
) {
ObjectSetPrototypeOf(module.exports, ObjectPrototype)
}
}
// 7锔忊儯 杩斿洖妯″潡鐨勮緭鍑烘帴鍙?
return module.exports
}
4.4 require 涓嚑涓父瑙佺殑闂
Q: Node.js 鏄浣曞疄鐜板悓姝ュ姞杞芥満鍒剁殑锛?br> A:
鏈畬寰呯画...
References
- ECMAScript 6 Modules
- Writing Modular JavaScript With AMD, CommonJS & ES Harmony
- Learning JavaScript Design Patterns by Addy Osmani
- Patterns for modules and namespaces in JavaScript