摘要:以后需要引用模塊的變量函數(shù)類(lèi)就在這個(gè)模塊對(duì)象的取出,即使再次進(jìn)來(lái)模塊也不會(huì)重新執(zhí)行,只會(huì)從緩存獲取。所以對(duì)相同模塊的再次加載都是優(yōu)先緩存方式,核心模塊的緩存檢查依然優(yōu)先于文件模塊。內(nèi)建模塊導(dǎo)出啟動(dòng)會(huì)生成全局變量,提供方法協(xié)助加載內(nèi)建模塊。
原始時(shí)代
作為一門(mén)語(yǔ)言的引入代碼方式,相較于其他如PHP的include和require,Ruby的require,Python的import機(jī)制,Javascript是直接使用
出于需要社區(qū)制定了一些模塊加載方案,最主要的有 CommonJS 和 AMD 兩種。前者用于服務(wù)器,后者用于瀏覽器。
CommonJS規(guī)范CommonJS規(guī)范為Javascript制定的美好愿景是希望Javascript能夠在任何地方運(yùn)行,具備跨宿主環(huán)境執(zhí)行的能力,例如:
富客戶端應(yīng)用
服務(wù)器端Javascript應(yīng)用程序(如Nodejs )
命令行工具
桌面圖形界面應(yīng)用程序
混合應(yīng)用(Titanium和Adobe AIR等形式應(yīng)用)
這些規(guī)范基本覆蓋了模塊,二進(jìn)制,Buffer,字符集編碼,I/O流,進(jìn)程環(huán)境,文件系統(tǒng),套接字,單元測(cè)試,Web服務(wù)器網(wǎng)關(guān)接口,包管理等。
模塊規(guī)范1, 引用
模塊上下文提供 require() 方法引入外部模塊,一般如下
var fs = require("fs");
2, 定義
模塊中存在一個(gè)上下文 module對(duì)象 ,它代表模塊自身, module對(duì)象 提供了 exports對(duì)象 用于導(dǎo)出當(dāng)前模塊的變量、函數(shù)、類(lèi),并且是唯一的導(dǎo)出出口。
//a.js模塊 exports.a = 1; //引用a.js模塊 var a = require("a");
3, 標(biāo)識(shí)
require() 方法接受小駝峰命名的字符串,或者相對(duì)/絕對(duì)路徑,并且可以省略文件后綴,它有自己一套匹配規(guī)則,后面再講。
"./" 開(kāi)頭表示相對(duì)路徑引用模塊;
"/" 開(kāi)頭表示絕對(duì)路徑引用模塊;
不帶上面符號(hào)開(kāi)頭的小駝峰字符串表示默認(rèn)提供的核心模塊或者 node_modules 下安裝模塊;
不帶上面符號(hào)開(kāi)頭的路徑字符串表示 node_modules 下安裝模塊對(duì)應(yīng)后續(xù)路徑;
//a.js模塊 var a = require("./a"); var a = require("/a"); var a = require("a"); var a = require("a/a");
至此看來(lái)使用相當(dāng)簡(jiǎn)單,模塊的意義在于將類(lèi)聚的變量、函數(shù)、類(lèi)等限定在私有作用域中,同時(shí)支持引入導(dǎo)出功能連接上下游依賴,避免了變量污染等問(wèn)題。
module.exports 和exports的關(guān)系?exports 是引用 module.exports 的值,而真正導(dǎo)出的是 module.exports ,接著就是基本類(lèi)型和引用類(lèi)型的區(qū)別。
如果直接替換 module.exports 或者exports相當(dāng)于切斷了和原有對(duì)象之間的關(guān)聯(lián),后續(xù)兩者互不影響了。
第一次 require() 一個(gè)腳本的時(shí)候會(huì)執(zhí)行代碼然后在內(nèi)存中會(huì)生成一個(gè)模塊對(duì)象緩存起來(lái),類(lèi)似
{ id: "...",//模塊的識(shí)別符,通常是帶有絕對(duì)路徑的模塊文件名 filename: "",//模塊的文件名,帶有絕對(duì)路徑 exports: {...},//導(dǎo)出變量、函數(shù)、類(lèi) loaded: true,//模塊是否已經(jīng)完成加載 parent: {},//調(diào)用該模塊的模塊 children: [],//該模塊要用到的其他模塊 ... }
例如你創(chuàng)建一個(gè)文件腳本代碼執(zhí)行就可以查看到這些信息。
exports.a = 1; console.log(module); // Module { // id: ".", // exports: { a: 1 }, // parent: null, // // filename: "C:project estmodule_demo est1.js", // loaded: false, // children: [], // paths: // [ "C:project estmodule_demo ode_modules", // "C:project est ode_modules", // "C:project ode_modules", // "C: ode_modules" ] }
以后需要引用模塊的變量、函數(shù)、類(lèi)就在這個(gè)模塊對(duì)象的 exports 取出,即使再次 require() 進(jìn)來(lái)模塊也不會(huì)重新執(zhí)行,只會(huì)從緩存獲取。
CommonJS優(yōu)點(diǎn)模塊引用順序決定加載順序;
每個(gè)模塊只會(huì)加載一次,然后將運(yùn)行結(jié)果緩存起來(lái)二次利用,以后再次加載就直接讀取緩存。要想讓模塊再次運(yùn)行,必須清除緩存;
每個(gè)模塊都有其多帶帶的作用域,不會(huì)污染全局;
Nodejs 模塊實(shí)現(xiàn)Nodejs 借鋻了 CommonJS 但不完全按照規(guī)范實(shí)現(xiàn)了自己的模塊系統(tǒng)。
在Nodejs 引入模塊會(huì)經(jīng)歷三個(gè)步驟:
路徑分析;
文件定位;
編譯執(zhí)行;
在 Nodejs 中有兩種模塊
Nodejs 提供的核心模塊;
這部分模塊在 Nodejs 源代碼編譯過(guò)程中編譯進(jìn)了二進(jìn)制執(zhí)行文件。在 Nodejs 進(jìn)程啟動(dòng)時(shí)部分核心模塊被直接加載進(jìn)了內(nèi)存中,所以在引用的時(shí)候可以省去文件定位和編譯執(zhí)行的步驟,并且在路徑分析優(yōu)先判斷,所以加載速度是最快的。
由用戶編寫(xiě)的文件模塊;
這部分模塊在運(yùn)行時(shí)動(dòng)態(tài)加載,需要經(jīng)歷完整步驟。
Nodejs 會(huì)對(duì)引用過(guò)的模塊進(jìn)行緩存以減少二次引入的開(kāi)銷(xiāo)。而且緩存的是模塊編譯和執(zhí)行之后的對(duì)象。所以 require() 對(duì)相同模塊的再次加載都是優(yōu)先緩存方式,核心模塊的緩存檢查依然優(yōu)先于文件模塊。
Nodejs 模塊標(biāo)識(shí)前面提過(guò)的模塊標(biāo)識(shí),例如:
核心模塊fs等
優(yōu)先級(jí)僅次于緩存加載,如果直接引用自己編寫(xiě)的和核心模塊具有相同標(biāo)識(shí)的模塊會(huì)引用失敗,必須選擇不同標(biāo)識(shí)符或者使用路徑方式加載。
路徑形式文件模塊
分析過(guò)程中 rerquire() 會(huì)將路徑轉(zhuǎn)換成真實(shí)路徑,并以此為索引將編譯后結(jié)果緩存起來(lái),因?yàn)橹该髁四K位置所以查找過(guò)程會(huì)省點(diǎn)時(shí)間,速度慢于核心模塊。
自定義模塊
可能是以包或者文件形式的特殊模塊,查找費(fèi)時(shí)速度最慢的一種,因?yàn)樗麜?huì)用到模塊路徑的查找方法。
Nodejs在定位文件模塊有自己的一套查找策略,你可以隨便一個(gè)文件夾執(zhí)行一個(gè)腳本如下看看打印信息,我是 Windows 系統(tǒng)結(jié)果如下
console.log(module.paths); // [ "C:workproject est ode_modules", // "C:workproject ode_modules", // "C:work ode_modules", // "C: ode_modules" ]
從中可以看出他會(huì)從當(dāng)前執(zhí)行文件所在目錄下的 node_modules,沿路徑向上逐層遞歸查找 node_modules 直到根目錄為止。
模塊加載過(guò)程會(huì)逐個(gè)嘗試直到符合條件或者沒(méi)有符合為止,你可以看出里面有著很明顯的問(wèn)題。
層級(jí)越深查找起來(lái)越費(fèi)時(shí)費(fèi)力;
可能你衹想查看當(dāng)前目錄,但是它失敗后會(huì)自動(dòng)嘗試其他路徑;
這就是自定義模塊最慢的原因。
文件定位擴(kuò)展名分析
Nodejs 在標(biāo)識(shí)符不包含后綴情況下會(huì)以.js, .json, .node的次序逐個(gè)嘗試匹配,而且過(guò)程中需要利用fs模塊以同步阻塞方式去判斷是否匹配,所以在非.js文件情況指明后綴能減少性能損耗的問(wèn)題。
目錄分析和包
還有一種情況是經(jīng)過(guò)上面步驟之后都匹配不到對(duì)應(yīng)文件但是有符合的目錄,此時(shí)Nodejs 會(huì)將其作為一個(gè)包的方式處理。
1)查找包下的 package.json 文件(包描述文件),通過(guò) JSON.parse() 解析出文件讀取里面的 main 屬性定位對(duì)應(yīng)的文件,省略后綴情況下需要執(zhí)行擴(kuò)展名分析步驟。
2)如果沒(méi)有 package.json 或者 main 屬性不對(duì),會(huì)用默認(rèn)值 index 去查找匹配文件,這一步需要擴(kuò)展名分析步驟逐個(gè)嘗試。
3)如果還是失敗就會(huì)根據(jù)模塊路徑規(guī)則往上層路徑尋找,直到全部路徑都沒(méi)有匹配文件就拋出失敗。
這是引入模塊的最后階段,定位到目標(biāo)文件之后會(huì)新建一個(gè)模塊對(duì)象,然后根據(jù)路徑載入進(jìn)行編譯,不同后綴文件載入方式不同:
js通過(guò)fs模塊同步讀取文件之后編譯執(zhí)行;
node是C/C++編寫(xiě)的擴(kuò)展文件,通過(guò) dlopen()方法 加載最后編譯生成的對(duì)象;
json通過(guò)fs模塊同步讀取文件之后用 JSON.parse() 解析返回結(jié)果;
其余默認(rèn)js處理方式;
每個(gè)編譯成功之后的模塊都會(huì)以其文件路徑作為索引緩存在 Module_cache。根據(jù)不同的擴(kuò)展后綴 Nodejs 有不同的讀取方式。
1, Javascript模塊編譯
在編譯過(guò)程中,Nodejs 會(huì)對(duì)獲取的模塊進(jìn)行包裝,如下:
(function(exports, require, module, __filename, __dirname) { //模塊源碼 })
2, C/C++模塊編譯
Nodejs 調(diào)用 process.dlopen() 方法進(jìn)行加載執(zhí)行,通過(guò) libuv封裝庫(kù) 支持 Windows 和 *nix 平臺(tái)下實(shí)現(xiàn),因?yàn)?node本身就是C/C++寫(xiě)的,所以它不需要編譯,衹要加載執(zhí)行就可以了,執(zhí)行效率較高。
3, JSON文件編譯
上面說(shuō)過(guò)通過(guò)fs模塊同步讀取文件之后用 JSON.parse() 解析返回結(jié)果,賦值給模塊對(duì)象的 exports。
除了配置文件,如果你開(kāi)發(fā)中有需要用到j(luò)son文件的時(shí)候可以不用 fs模塊 去讀取,而是直接 require() 引入更好,因?yàn)槟芟硎艿骄彺婕虞d的便利。
上面說(shuō)過(guò) Nodejs 模塊分為核心模塊和文件模塊,剛才講的都是文件模塊的編譯過(guò)程,而 Nodejs 的核心模塊在編譯成可執(zhí)行文件過(guò)程中會(huì)被編譯進(jìn)二進(jìn)制文件。核心模塊也分Javascript和C/C++編寫(xiě),前者在Node的lib目錄,后者在Node的src目錄。
Javascript核心模塊編譯 轉(zhuǎn)存為C/C++代碼Nodejs 采用V8附帶的 js2c.py工具 將內(nèi)置的Javascript代碼(src/node.js和lib/*.js)轉(zhuǎn)成C++的數(shù)組,生成 node_natives.h 頭文件,Javascript代碼以字符串形式存儲(chǔ)在nodejs命名空間里,此時(shí)還不能直接執(zhí)行。等 Nodejs 啟動(dòng)進(jìn)程時(shí)候才被直接加載進(jìn)內(nèi)存中,所以不需要引入就能直接使用。
編譯Javascript核心模塊和文件模塊一樣也會(huì)被包裝成模塊對(duì)象,區(qū)別在于獲取源代碼的方式以及緩存執(zhí)行結(jié)果的位置。
核心模塊源文件通過(guò) process.binding("natives") 取出,編譯完成后緩存到 NativeModule._cache 對(duì)象上,而文件模塊會(huì)被緩存到 Module._cache。
每個(gè)內(nèi)建模塊在定義之后會(huì)通過(guò) NODE_MODULE宏 將模塊定義到nodejs命名空間,模塊的具體初始化方法被掛載在結(jié)構(gòu)的 register_func 成員。
node_extensions.h 文件將散列的內(nèi)建模塊統(tǒng)一放進(jìn) node_module_list數(shù)組 中,Nodejs 提供了 get_builtin_module() 方法從中取出。
內(nèi)建模塊優(yōu)勢(shì)在于本身C/C++編寫(xiě)性能優(yōu)異,編譯成二進(jìn)制文件時(shí)候被直接加載進(jìn)內(nèi)存,無(wú)需再做標(biāo)識(shí)符定位,文件定位,編譯等過(guò)程。
Nodejs 啟動(dòng)會(huì)生成全局變量 process,提供 Binding() 方法協(xié)助加載內(nèi)建模塊。
加載過(guò)程中我們會(huì)先生成 exports空對(duì)象 ,然后調(diào)用 get_builtin_module() 方法去取內(nèi)建模塊,通過(guò)執(zhí)行 register_func 填充空對(duì)象,最后按模塊名緩存起來(lái)并返回給調(diào)用方使用。
至此我們已經(jīng)有個(gè)大概概念了,梳理一下各種模塊之間的關(guān)系:
C/C++內(nèi)建模塊是最底層核心模塊,主要提供API給Javascript核心模塊和第三方Javascript模塊使用;
Javascript核心模塊分兩類(lèi),一類(lèi)作為C/C++內(nèi)建模塊的封裝層和橋接層,一類(lèi)純粹的功能模塊;
文件模塊分Javascript模塊和C/C++擴(kuò)展模塊;
ES6模塊加載直到ES6標(biāo)準(zhǔn)化模塊功能,統(tǒng)一替代了之前多種模塊實(shí)現(xiàn)庫(kù),成為瀏覽器和服務(wù)器通用的模塊解決方案。ES6 模塊的設(shè)計(jì)思想是盡量的靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量、函數(shù)、類(lèi)。CommonJS 和 AMD 模塊,都只能在運(yùn)行時(shí)確定這些東西。
ES6 的模塊有幾個(gè)需要注意的地方:
自動(dòng)采用嚴(yán)格模式,即使你沒(méi)有使用"use strict";
頂層的this指向undefined;
// CommonJS模塊 let {readFile} = require("fs"); // ES6模塊 import {readFile} from "fs";
以上為例。
CommonJS加載整個(gè) fs模塊 生成一個(gè)模塊對(duì)象,然后從對(duì)象中導(dǎo)出 readFile方法 。
ES6 模塊通過(guò) import命令 從 fs模塊 加載輸入的變量、函數(shù)、類(lèi)。
結(jié)果就是ES6模塊效率高,但是拿不到模塊對(duì)象本身。
加載方案 | 加載 | 輸出 |
---|---|---|
CommonJS | 運(yùn)行時(shí)加載 | 拷貝 |
ES6 模塊 | 編譯時(shí)輸出接口 | 引用 |
由于 ES6 模塊是編譯時(shí)加載,使得靜態(tài)分析成為可能。比如引入宏(macro)和類(lèi)型檢驗(yàn)(type system)這些只能靠靜態(tài)分析實(shí)現(xiàn)的功能。
ES6 模塊還有以下好處:
不再需要UMD模塊格式了,將來(lái)服務(wù)器和瀏覽器都會(huì)支持 ES6 模塊格式。目前,通過(guò)各種工具庫(kù),其實(shí)已經(jīng)做到了這一點(diǎn)。
將來(lái)瀏覽器的新 API 就能用模塊格式提供,不再必須做成全局變量或者 navigator對(duì)象 的屬性。
不再需要對(duì)象作為命名空間(比如Math對(duì)象),未來(lái)這些功能可以通過(guò)模塊提供。
ES6模塊提供了 export導(dǎo)出命令 和 import導(dǎo)入命令 ,它們同樣具有全局提升的效果,只要在頂層使用即可。
export導(dǎo)出命令支持輸出變量、函數(shù)、類(lèi)。
//變量 export var a = 1; //函數(shù) export function log(n) { console.log(n); } //類(lèi) export class Num {}
我習(xí)慣寫(xiě)法是使用對(duì)象方式輸出,整個(gè)模塊導(dǎo)出什么一目了然。
//變量 var a = 1; //函數(shù) function log(n) { console.log(n); } //類(lèi) class Num {} export {a, log, Num};
這種寫(xiě)法也支持as關(guān)鍵字對(duì)外重命名
export {a as b, log as cng, Num as Digit};
這里有一個(gè)隱藏比較深的概念性知識(shí),export命令規(guī)定的是對(duì)外的接口必須與模塊內(nèi)部的變量、函數(shù)、類(lèi)建立一一對(duì)應(yīng)關(guān)系。這種寫(xiě)法是OK的。
export var a = 1; //或者 var a = 1; export { a, //或者 a as b, }
但是你不能這么寫(xiě),盡管看起來(lái)沒(méi)什么問(wèn)題,不過(guò)沒(méi)有提供對(duì)外的接口,只是直接或者間接輸出1。
export 1; //或者 var a = 1; export a
特別容易讓人混淆的是這一句,所以要特別注意
//正確 export var a = 1; //錯(cuò)誤 var a = 1; export a
這不僅僅是針對(duì)變量,包括函數(shù)和類(lèi)也遵循這種寫(xiě)法,之所以會(huì)有這種要求是因?yàn)?export語(yǔ)句 輸出的接口,與其對(duì)應(yīng)的值是動(dòng)態(tài)綁定關(guān)系,即通過(guò)該接口,可以取到模塊內(nèi)部實(shí)時(shí)的值。
export var a = 1 setTimeout(() => a = 2, 3000); //后續(xù)引用a會(huì)得到2import 導(dǎo)入命令
和expor相對(duì)應(yīng)的按需引入寫(xiě)法如下
//直接引入寫(xiě)法 import {a, log, Num} from "xx";
import也支持使用as關(guān)鍵字
import {a as b, log as cng, Num as Digit} from "xx";
和 export 動(dòng)態(tài)綁定值不同,import 是只讀靜態(tài)執(zhí)行,即你不能修改引用的模塊變量、函數(shù)、類(lèi)等,也不能使用表達(dá)式和變量這種運(yùn)行時(shí)才能引入靜態(tài)分析階段沒(méi)法得到值的寫(xiě)法。
//修改屬性 import{a} from "xx" a = 2//error
//表達(dá)式引入 import{"l" + "og"} from "xx" //變量引入 var module = "xx"; import {} from module//error
//判斷引入 //error if (true) { import {} from "xx1"; } else { import {} from "xx2"; }
因?yàn)槎啻我靡仓粫?huì)執(zhí)行一次,盡管不推薦,但是這種寫(xiě)法也是可以的
import {a} from "xx"; import {log} from "xx"; //等價(jià)于 import {a, log} from "xx";
import也支持這種寫(xiě)法,僅僅執(zhí)行模塊,但是不輸入任何變量、函數(shù)、類(lèi)。
import "xx";關(guān)鍵字default
export 支持 關(guān)鍵字default 設(shè)置默認(rèn)導(dǎo)出的變量、函數(shù)、類(lèi):
1, 每個(gè)模塊只支持一個(gè)關(guān)鍵字default默認(rèn)導(dǎo)出;
2, 可以使用函數(shù)名或匿名函數(shù)導(dǎo)出,即使指定了函數(shù)名也不能在模塊外部引用,等同視為匿名函數(shù)加載;
//函數(shù) function log(n) { console.log(n); } export default log; //或者 export default function(n) { console.log(n); } //或者 export default function log(n) { console.log(n); }
其他模塊加載該模塊時(shí),import命令可以為該默認(rèn)導(dǎo)出函數(shù)指定任意名字。
export default function log(n) { console.log(n); } //加載 import anyName from "xx";
如果想在一條 import語(yǔ)句 中,同時(shí)輸入默認(rèn)函數(shù)和其他接口,可以寫(xiě)成下面這樣。
import log, {a, Num as Digit} from "xx";
本質(zhì)上這也只是一種語(yǔ)法糖,與下面寫(xiě)法等價(jià)
export default log; import log from "xx"; //==等價(jià)== export { log as default} import { default as log } from "xx";
因?yàn)閐efault也是變量,所以不能后面再加變量
export default var a = 1;
但是可以直接輸出
export default 1; export default a;關(guān)鍵字*
用星號(hào)(*)指定一個(gè)對(duì)象,所有輸出值都加載在這個(gè)對(duì)象上面。
import * as all from "xx"; const {a, log, Num} = all;export 與 import 的復(fù)合寫(xiě)法
這里提供了兩種寫(xiě)法,他們之間會(huì)有些不同。
//引入后導(dǎo)出 import {log} from "xx"; export {log}; //直接導(dǎo)出 export {log} from "xx"; //或者 export {log as default} from "xx";
區(qū)別在于第二三種是沒(méi)有導(dǎo)入動(dòng)作,所以不能在該模塊引用對(duì)應(yīng)的變量、函數(shù)、類(lèi)。
需要注意的是下面三種寫(xiě)法ES6目前還不支持。
export * as all from "xx"; export all from "xx"; export log, {a, Digit as Num} from "xx";Nodejs 使用問(wèn)題
import命令 會(huì)被 JavaScript引擎靜態(tài)分析,先于模塊內(nèi)的其他語(yǔ)句執(zhí)行,而 Nodejs 的 require() 是運(yùn)行時(shí)加載模塊,import命令無(wú)法取代require的動(dòng)態(tài)加載功能,所以如果在Nodejs 中使用ES6模塊語(yǔ)法要注意這一點(diǎn)。
//成功 var fs = require("f"+"s"); //報(bào)錯(cuò) import fs from ("f"+"s");
有一個(gè)提案,建議引入 import() 函數(shù),完成動(dòng)態(tài)加載,已經(jīng)有實(shí)現(xiàn)方案了,我沒(méi)用過(guò)就不說(shuō)了。
參考資料nodejs 深入淺出
ES6 標(biāo)準(zhǔn)入門(mén)(第3版)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/106521.html
摘要:要求模塊編寫(xiě)必須在真正的代碼之外套上一層規(guī)定的代碼包裝,樣子看起來(lái)是這樣的模塊代碼通過(guò)傳遞一個(gè)簽名為的回調(diào)函數(shù)給函數(shù),就可以把需要注入的變量和函數(shù)注入到模塊代碼內(nèi)。 之前寫(xiě)的文章急速Js全棧教程得到了不錯(cuò)的閱讀量,霸屏掘金頭條3天,點(diǎn)贊過(guò)千,閱讀近萬(wàn),甚至還有人在評(píng)論區(qū)打廣告,可見(jiàn)也是一個(gè)小小的生態(tài)了;)。看來(lái)和JS全棧有關(guān)的內(nèi)容,還是有人頗有興趣的。 showImg(https://...
摘要:提倡依賴前置,在定義模塊的時(shí)候就要聲明其依賴的模塊。適用場(chǎng)景按需加載條件加載動(dòng)態(tài)的模塊路徑注關(guān)于模塊化,詳細(xì)見(jiàn)阮一峰的入門(mén)模塊與模塊化區(qū)別模塊化的規(guī)范和兩種。 模塊化開(kāi)發(fā)方便代碼的管理,提高代碼復(fù)用性,降低代碼耦合,每個(gè)模塊都會(huì)有自己的作用域。當(dāng)前流行的模塊化規(guī)范有CommonJS,AMD,CMD,ES6的import/export CommonJS的主要實(shí)踐者就是nodejs,一般...
摘要:模塊的加載第一個(gè)參數(shù),是一個(gè)數(shù)組,里面的成員就是要加載的模塊第二個(gè)參數(shù),則是加載成功之后的回調(diào)函數(shù)。異步加載,瀏覽器不會(huì)失去響應(yīng)它指定的回調(diào)函數(shù),只有前面的模塊都加載成功后,才會(huì)運(yùn)行,解決了依賴性的問(wèn)題。 什么是模塊化? 模塊化就是把系統(tǒng)分離成獨(dú)立功能的方法,這樣我們需要什么功能,就加載什么功能。 優(yōu)點(diǎn):可維護(hù)性:根據(jù)定義,每個(gè)模塊都是獨(dú)立的,良好設(shè)計(jì)的模塊會(huì)盡量與外部的代碼撇清關(guān)系,...
摘要:常見(jiàn)前端構(gòu)建工具的分類(lèi)和對(duì)比是附帶的包管理器,是內(nèi)置的一個(gè)功能,允許在文件里面使用字段定義任務(wù)在這里,一個(gè)屬性對(duì)應(yīng)一段腳本,原理是通過(guò)調(diào)用去運(yùn)行腳本命令。 前文 端技術(shù)范圍不斷發(fā)展,前端開(kāi)發(fā)不僅限于直接編寫(xiě)html,css和javascript,Web應(yīng)用日益龐大,代碼也更加龐大,因此許多新的思想(例如模塊化和工程化等)和框架(React和Vue等),以及新的語(yǔ)言(Es6 TypeSc...
摘要:也就是說(shuō),外部模塊輸出值變了,當(dāng)前模塊的導(dǎo)入值不會(huì)發(fā)生變化。三規(guī)范的出現(xiàn),使得模塊化在環(huán)境中得到了施展機(jī)會(huì)。模塊化這種加載稱為編譯時(shí)加載或者靜態(tài)加載。總結(jié)的模塊化規(guī)范經(jīng)過(guò)了模塊模式的演進(jìn),利用現(xiàn)在常用的打包工具,非常方便我們編寫(xiě)模塊化代碼。 前言 什么是模塊化? 模塊就是實(shí)現(xiàn)特定功能的一組方法,而模塊化是將模塊的代碼創(chuàng)造自己的作用域,只向外部暴露公開(kāi)的方法和變量,而這些方法之間高度解耦...
閱讀 654·2021-09-24 09:48
閱讀 2499·2021-08-26 14:14
閱讀 524·2019-08-30 13:08
閱讀 1450·2019-08-29 15:22
閱讀 3084·2019-08-29 11:06
閱讀 1011·2019-08-26 18:26
閱讀 1062·2019-08-26 13:53
閱讀 2538·2019-08-26 12:21