摘要:依賴全部加載完成后,調(diào)用回調(diào)函數(shù)規(guī)范異步加載模塊規(guī)范和很相似,簡單,并與和的規(guī)范保持了很大的兼容性在規(guī)范中,一個模塊就是一個文件。
拋出問題:
在開發(fā)中在導(dǎo)入模塊時經(jīng)常使用require和import;
導(dǎo)出模塊時使用module.exports/exports或者export/export default;
有時候為了引用一個模塊會使用require奇怪的是也可以使用import????它們之間有何區(qū)別呢?
于是有了菜鳥解惑的搜嘍過程。。。。。。追溯根源,來到Js模塊化規(guī)范 1、CommonJS規(guī)范(同步加載模塊)
允許模塊通過require方法來同步加載所要依賴的其他模塊,然后通過exports或module.exports來導(dǎo)出需要暴露的接口。
使用方式:
// 導(dǎo)入 require("module"); require("../app.js"); // 導(dǎo)出 exports.getStoreInfo = function() {}; module.exports = someValue;
優(yōu)點:
簡單容易使用
服務(wù)器端模塊便于復(fù)用
缺點:
同步加載方式不適合在瀏覽器環(huán)境中使用,同步意味著阻塞加載,瀏覽器資源是異步加載的
不能非阻塞的并行加載多個模塊
?為什么瀏覽器不能使用同步加載,服務(wù)端可以?
因為模塊都放在服務(wù)器端,對于服務(wù)端來說模塊加載時
而對于瀏覽器端,因為模塊都放在服務(wù)器端,加載的時間還取決于網(wǎng)速的快慢等因素,如果需要等很長時間,整個應(yīng)用就會被阻塞。
因此,瀏覽器端的模塊,不能采用"同步加載"(CommonJs),只能采用"異步加載"(AMD)。
參照CommonJs模塊代表node.js的模塊系統(tǒng)
AMD(異步加載模塊)采用異步方式加載模塊,模塊的加載不影響后面語句的運行。所有依賴模塊的語句,都定義在一個回調(diào)函數(shù)中,等到加載完成之后,回調(diào)函數(shù)才執(zhí)行。
使用實例:
// 定義 define("module", ["dep1", "dep2"], function(d1, d2) {...}); // 加載模塊 require(["module", "../app"], function(module, app) {...});
加載模塊require([module], callback);第一個參數(shù)[module],是一個數(shù)組,里面的成員就是要加載的模塊;第二個參數(shù)callback是加載成功之后的回調(diào)函。
優(yōu)點:
適合在瀏覽器環(huán)境中異步加載模塊
可以并行加載多個模塊
缺點:
提高了開發(fā)成本,代碼的閱讀和書寫比較困難,模塊定義方式的語義不順暢
不符合通用的模塊化思維方式,是一種妥協(xié)的實現(xiàn)
實現(xiàn)AMD規(guī)范代表require.js
RequireJS對模塊的態(tài)度是預(yù)執(zhí)行。由于 RequireJS 是執(zhí)行的 AMD 規(guī)范, 因此所有的依賴模塊都是先執(zhí)行;即RequireJS是預(yù)先把依賴的模塊執(zhí)行,相當(dāng)于把require提前了
RequireJS執(zhí)行流程:
require函數(shù)檢查依賴的模塊,根據(jù)配置文件,獲取js文件的實際路徑
根據(jù)js文件實際路徑,在dom中插入script節(jié)點,并綁定onload事件來獲取該模塊加載完成的通知。
依賴script全部加載完成后,調(diào)用回調(diào)函數(shù)
CMD規(guī)范(異步加載模塊)CMD規(guī)范和AMD很相似,簡單,并與CommonJS和Node.js的 Modules 規(guī)范保持了很大的兼容性;在CMD規(guī)范中,一個模塊就是一個文件。
定義模塊使用全局函數(shù)define,其接收 factory 參數(shù),factory 可以是一個函數(shù),也可以是一個對象或字符串;
factory 是一個函數(shù),有三個參數(shù),function(require, exports, module):
require 是一個方法,接受模塊標(biāo)識作為唯一參數(shù),用來獲取其他模塊提供的接口:require(id)
exports 是一個對象,用來向外提供模塊接口
module 是一個對象,上面存儲了與當(dāng)前模塊相關(guān)聯(lián)的一些屬性和方法
實例:
define(function(require, exports, module) { var a = require("./a"); a.doSomething(); // 依賴就近書寫,什么時候用到什么時候引入 var b = require("./b"); b.doSomething(); });
優(yōu)點:
依賴就近,延遲執(zhí)行
可以很容易在 Node.js 中運行
缺點:
依賴 SPM 打包,模塊的加載邏輯偏重
實現(xiàn)代表庫sea.js:SeaJS對模塊的態(tài)度是懶執(zhí)行, SeaJS只會在真正需要使用(依賴)模塊時才執(zhí)行該模塊
AMD 與 CMD 的區(qū)別對于依賴的模塊,AMD 是提前執(zhí)行,CMD 是延遲執(zhí)行。不過 RequireJS 從2.0開始,也改成了可以延遲執(zhí)行(根據(jù)寫法不同,處理方式不同)。CMD 推崇 as lazy as possible.
AMD推崇依賴前置;CMD推崇依賴就近,只有在用到某個模塊的時候再去require。
// AMD define(["./a", "./b"], function(a, b) { // 依賴必須一開始就寫好 a.doSomething() // 此處略去 100 行 b.doSomething() ... }); // CMD define(function(require, exports, module) { var a = require("./a") a.doSomething() // 此處略去 100 行 var b = require("./b") // 依賴可以就近書寫 b.doSomething() // ... });UMD
UMD是AMD和CommonJS的糅合
AMD 以瀏覽器第一原則發(fā)展異步加載模塊。
CommonJS 模塊以服務(wù)器第一原則發(fā)展,選擇同步加載,它的模塊無需包裝。
UMD先判斷是否支持Node.js的模塊(exports)是否存在,存在則使用Node.js模塊模式;在判斷是否支持AMD(define是否存在),存在則使用AMD方式加載模塊。
(function (window, factory) { if (typeof exports === "object") { module.exports = factory(); } else if (typeof define === "function" && define.amd) { define(factory); } else { window.eventUtil = factory(); } })(this, function () { //module ... });ES6模塊化
ES6 在語言標(biāo)準(zhǔn)的層面上,實現(xiàn)了模塊功能,而且實現(xiàn)得相當(dāng)簡單,完全可以取代 CommonJS 和 AMD 規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。
ES6 模塊設(shè)計思想:盡量的靜態(tài)化、使得編譯時就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量(CommonJS和AMD模塊,都只能在運行時確定這些東西)。
使用方式:
// 導(dǎo)入 import "/app"; import React from “react”; import { Component } from “react”; // 導(dǎo)出 export function multiply() {...}; export var year = 2018; export default ... ...
優(yōu)點:
容易進(jìn)行靜態(tài)分析
面向未來的 EcmaScript 標(biāo)準(zhǔn)
缺點:
原生瀏覽器端還沒有實現(xiàn)該標(biāo)準(zhǔn)
全新的命令字,新版的 Node.js才支持。
回到問題“require與import的區(qū)別”require使用與CommonJs規(guī)范,import使用于Es6模塊規(guī)范;所以兩者的區(qū)別實質(zhì)是兩種規(guī)范的區(qū)別;
CommonJS:
對于基本數(shù)據(jù)類型,屬于復(fù)制。即會被模塊緩存;同時,在另一個模塊可以對該模塊輸出的變量重新賦值。
對于復(fù)雜數(shù)據(jù)類型,屬于淺拷貝。由于兩個模塊引用的對象指向同一個內(nèi)存空間,因此對該模塊的值做修改時會影響另一個模塊。
當(dāng)使用require命令加載某個模塊時,就會運行整個模塊的代碼。
當(dāng)使用require命令加載同一個模塊時,不會再執(zhí)行該模塊,而是取到緩存之中的值。也就是說,CommonJS模塊無論加載多少次,都只會在第一次加載時運行一次,以后再加載,就返回第一次運行的結(jié)果,除非手動清除系統(tǒng)緩存。
循環(huán)加載時,屬于加載時執(zhí)行。即腳本代碼在require的時候,就會全部執(zhí)行。一旦出現(xiàn)某個模塊被"循環(huán)加載",就只輸出已經(jīng)執(zhí)行的部分,還未執(zhí)行的部分不會輸出。
ES6模塊
ES6模塊中的值屬于【動態(tài)只讀引用】。
對于只讀來說,即不允許修改引入變量的值,import的變量是只讀的,不論是基本數(shù)據(jù)類型還是復(fù)雜數(shù)據(jù)類型。當(dāng)模塊遇到import命令時,就會生成一個只讀引用。等到腳本真正執(zhí)行時,再根據(jù)這個只讀引用,到被加載的那個模塊里面去取值。
對于動態(tài)來說,原始值發(fā)生變化,import加載的值也會發(fā)生變化。不論是基本數(shù)據(jù)類型還是復(fù)雜數(shù)據(jù)類型。
循環(huán)加載時,ES6模塊是動態(tài)引用。只要兩個模塊之間存在某個引用,代碼就能夠執(zhí)行。
最后:require/exports 是必要通用且必須的;因為事實上,目前你編寫的 import/export 最終都是編譯為 require/exports 來執(zhí)行的。
參考
AMD與CMD規(guī)范詳解
CommonJS模塊和ES6模塊的區(qū)別
Js模塊規(guī)范
理解Js模塊化
Require與import的區(qū)別
“積跬步、行千里”—— 不時的分享更新中~,喜歡留下個贊哦!
往期經(jīng)典:
團(tuán)隊合作必備的Git操作
一個頁面從輸入URL到加載顯示完成,發(fā)生了什么?
相關(guān)好文推薦:
網(wǎng)絡(luò)篇—瀏覽器緩存(一)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/96894.html
摘要:依賴全部加載完成后,調(diào)用回調(diào)函數(shù)規(guī)范異步加載模塊規(guī)范和很相似,簡單,并與和的規(guī)范保持了很大的兼容性在規(guī)范中,一個模塊就是一個文件。 拋出問題: 在開發(fā)中在導(dǎo)入模塊時經(jīng)常使用require和import; 導(dǎo)出模塊時使用module.exports/exports或者export/export default; 有時候為了引用一個模塊會使用require奇怪的是也可以使用import?...
摘要:當(dāng)年的加載在沒有前端工程化之前,基本上是我們是代碼一把梭,把所需要的庫和自己的代碼堆砌在一起,然后自上往下的引用就可以了。而且對于前后端的技術(shù)要求較高,所以對于項目未必是最有效的方案。 當(dāng)年的 js 加載 在沒有 前端工程化之前,基本上是我們是代碼一把梭,把所需要的庫和自己的代碼堆砌在一起,然后自上往下的引用就可以了。 那個時代我們沒有公用的cdn,也沒有什么特別好的方法來優(yōu)化加載j...
摘要:特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會及時更新,平時業(yè)務(wù)工作時也會不定期更...
摘要:作為構(gòu)造函數(shù)使用,綁定到新創(chuàng)建的對象。內(nèi)部實現(xiàn)類和類的繼承構(gòu)造函數(shù)構(gòu)造函數(shù)調(diào)用父類構(gòu)造函數(shù)參考請盡可能詳盡的解釋的工作原理的原理簡單來說通過對象來向服務(wù)器發(fā)異步請求,從服務(wù)器獲得數(shù)據(jù),然后用來操作而更新頁面。 1 . 請解釋事件代理 (event delegation) 當(dāng)需要對很多元素添加事件的時,可以通過將事件添加到它們的父節(jié)點通過委托來觸發(fā)處理函數(shù)。其中利用到了瀏覽器的事件冒泡機...
閱讀 1177·2021-11-24 09:39
閱讀 2685·2021-09-28 09:35
閱讀 1078·2019-08-30 15:55
閱讀 1370·2019-08-30 15:44
閱讀 884·2019-08-29 17:00
閱讀 1979·2019-08-29 12:19
閱讀 3317·2019-08-28 18:28
閱讀 695·2019-08-28 18:10