当前位置: 首页>后端>正文

细读 JS - JavaScript 模块化之路

细读 JS - JavaScript 模块化之路,第1张
閰嶅浘婧愯嚜 Freepik

瀛︿範涓嶈兘鍋滐紝閮界粰鎴戝嵎璧锋潵...

涓€銆佸墠涓栦粖鐢?/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 妯″潡閲岄潰閮藉寘鎷竴浜涗粈涔堜俊鎭細

细读 JS - JavaScript 模块化之路,第2张

濡傛灉鏈変竴浜涚湅涓嶆噦鎴栦笉浜嗚В鍏剁敤澶勭殑锛屽厛涓嶆€ワ紝涓嬮潰濞撳〒閬撴潵銆?/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

https://www.xamrdz.com/backend/3nw1940846.html

相关文章: