摘要:模塊化規(guī)范有的模塊系統(tǒng)。規(guī)范是服務(wù)器端模塊的規(guī)范,由推廣使用。對于依賴的模塊,是提前執(zhí)行,是延遲執(zhí)行。瀏覽器廠商和都宣布要原生支持該規(guī)范。它將逐漸取代和規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。
本文由云+社區(qū)發(fā)表
模塊化是指把一個復(fù)雜的系統(tǒng)分解到一個一個的模塊。
模塊化開發(fā)的優(yōu)點:
(1)代碼復(fù)用,讓我們更方便地進行代碼管理、同時也便于后面代碼的修改和維護。
(2)一個多帶帶的文件就是一個模塊,是一個多帶帶的作用域,只向外暴露特定的變量和函數(shù)。這樣可以避免污染全局變量,減少變量命名沖突。
js模塊化規(guī)范有:CommonJS、AMD、CMD、ES6的模塊系統(tǒng)。本文將依次介紹下每個規(guī)范。
0.早期:用script來引入js模塊缺點:
(1)加載的時候會停止渲染網(wǎng)頁,引入的js文件越多,網(wǎng)頁失去響應(yīng)的時間越長;
(2)會污染全局變量;
(3)js文件之間存在依賴關(guān)系,加載是有順序的,依賴性最大的要放到最后去加載;當項目規(guī)模較大時,依賴關(guān)系變得錯綜復(fù)雜。
(4)要引入的js文件太多,不美觀,代碼難以管理。
1.CommonJS 規(guī)范是服務(wù)器端模塊的規(guī)范,由nodejs推廣使用。該規(guī)范的核心思想是:允許模塊通過require方法來同步加載所要依賴的其他模塊,然后通過 exports 或module.exports 來導(dǎo)出需要暴露的接口。
CommonJS 還可以細分為 CommonJS1 和 CommonJS2,區(qū)別在于 CommonJS1 只能通過 exports.xx = xx 的方式導(dǎo)出,CommonJS2 在 CommonJS1 的基礎(chǔ)上加入了module.exports = xx 的導(dǎo)出方式。 CommonJS 通常指 CommonJS2。
采用CommonJS 規(guī)范導(dǎo)入導(dǎo)出:
// 導(dǎo)出 module.exports = moduleA.someFunc; // 導(dǎo)入 const moduleA = require("./moduleA");
實例:
//math.js var num = 0; function add(a, b) { return a + b; } module.exports = { //需要向外暴露的變量、函數(shù) num: num, add: add }
可以這樣加載:
//引入自定義的模塊時,參數(shù)包含路徑,可省略.js //引入核心模塊時,不需要帶路徑,如var http = require("http"); var math = require("./math"); math.add(1, 2)//3
實際上,從上面的例子就可以看出,math.add(1,2)必須要等待math.js加載完成,即require是同步的。
在服務(wù)器端,模塊文件保存在本地磁盤,等待時間就是磁盤的讀取時間。但對于瀏覽器而言,由于模塊都放在服務(wù)器端,等待時間取決于網(wǎng)上的快慢。因此更合理的方案是異步加載模塊。
缺點:
(1)不能并行加載模塊,會阻塞瀏覽器加載;
(2)代碼無法直接運行在瀏覽器環(huán)境下,必須通過工具轉(zhuǎn)換成標準的 ES5;
2.AMD和require.jsAMD:異步模塊定義。上面已經(jīng)介紹過,CommonJS是服務(wù)器端模塊的規(guī)范,主要是為了JS在后端的表現(xiàn)制定的,不太適合前端。而AMD就是要為前端JS的表現(xiàn)制定規(guī)范。由于不是JavaScript原生支持,使用AMD規(guī)范進行頁面開發(fā)需要用到對應(yīng)的庫函數(shù),也就是require.js(還有個js庫:curl.js)。實際上AMD 是 require.js在推廣過程中對模塊定義的規(guī)范化的產(chǎn)出。
AMD采用異步方式加載模塊,模塊的加載不影響它后面語句的運行。所有依賴這個模塊的語句,都定義在一個回調(diào)函數(shù)中,等到加載完成之后,這個回調(diào)函數(shù)才會運行。
require.js也采用require()語句加載模塊,但是不同于CommonJS:
// 定義一個模塊 define("module", ["dep"], function (dep) { return exports; }); // 導(dǎo)入和使用 require(["module"], function (module) { });
上面示例中的代碼改寫成AMD形式:
math.js定義一個模塊:
define("math", ["jquery"], function (jquery) {//引入jQuery模塊 return { add: function (x, y) { return x + y; } }; });
導(dǎo)入和使用:
require(["math"], function (math) { math.add(1, 2) })
math.add()與加載math模塊不是同步的,不會阻塞瀏覽器的加載。
3.CMD和sea.jsCMD:通用模塊定義。
國內(nèi)的玉伯大佬寫了sea.js,實際上CMD就是 sea.js在推廣過程中對模塊定義的規(guī)范化的產(chǎn)出。
define(function (require, exports, module) { // 模塊代碼 });
說明:
require:可以把其他模塊導(dǎo)入進來的一個參數(shù);
exports:可以把模塊內(nèi)的一些屬性和方法導(dǎo)出的;
module: 是一個對象,上面存儲了與當前模塊相關(guān)聯(lián)的一些屬性和方法。
上面示例中的代碼改寫成AMD形式:
define(function (require, exports, module) { var add = function (a, b) { return a + b; } exports.add = add; }) //導(dǎo)入和使用 seajs.use(["math.js"], function (math) { var sum = math.add(1, 2); });
CMD與AMD的不同的在于:
(1)AMD推崇依賴前置;CMD推崇依賴就近,只有在用到某個模塊的時候再去require:
//AMD推崇的依賴關(guān)系前置:在定義模塊時就要聲明要依賴的模塊 define(["a", "b", "c", "d"], function (a, b, c, d) { // 依賴必須一開始就寫好 a.doSomething() // 此處省略100行 ... b.doSomething() ... }) //CMD推崇依賴就近,按需加載,只有在用到某個模塊時再去require define(function (require, exports, modules) { var a = require("a"); a.doSomething(); // 此處省略100行 ... var b = require("b");//按需加載 b.doSomething(); ... })
(2)AMD 的 API 默認是一個當多個用,CMD 的 API 嚴格區(qū)分,推崇職責(zé)單一。
對于依賴的模塊,AMD是提前執(zhí)行,CMD是延遲執(zhí)行。
具體細節(jié)可點擊參考
4.ES6模塊化ES6在語言的層面上實現(xiàn)了模塊化。瀏覽器廠商和 Node.js 都宣布要原生支持該規(guī)范。它將逐漸取代 CommonJS 和 AMD 規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。
在 ES6 中,使用export關(guān)鍵字來導(dǎo)出模塊,使用import關(guān)鍵字引用模塊。但是瀏覽器還沒有完全兼容,需要使用babel轉(zhuǎn)換成ES5。
// 導(dǎo)出 export function hello() { }; export default { // ... }; // 導(dǎo)入 import { readFile } from "fs"; import React from "react";
使用import導(dǎo)入模塊時,需要知道要加載的變量名或函數(shù)名。
在ES6中還提供了export default,為模塊指定默認輸出.對應(yīng)導(dǎo)入模塊import時,不需要使用大括號。
上面示例中的代碼改寫成ES6形式:
//math.js var num = 0; var add = function (a, b) { return a + b; }; export { num, add }; //導(dǎo)入 import { num, add } from "./math"; function test(ele) { ele.textContent = add(1 + num); }
缺點
瀏覽器還沒有完全兼容,必須通過工具轉(zhuǎn)換成標準的 ES5 后才能正常運行。
5.小結(jié)本文從script引入js文件講起,到服務(wù)器端模塊的規(guī)范CommonJs,再到推崇依賴前置的瀏覽器端模塊的規(guī)范AMD、推崇依賴就近的瀏覽器端模塊的規(guī)范CMD,最后介紹了ES6的模塊化。每個介紹中都有各規(guī)范基本的用法和一個示例。如有問題,歡迎指正。
此文已由作者授權(quán)騰訊云+社區(qū)發(fā)布
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/100347.html
摘要:復(fù)雜數(shù)據(jù)類型變量,賦值給之后,只讀引用與關(guān)聯(lián),和中存儲的是同一個對象的堆內(nèi)存地址,當這個對象的值發(fā)生改變時,此時的值也會發(fā)生變化。 不積跬步無以至千里。 關(guān)于【Step-By-Step】 Step-By-Step (點擊進入項目) 是我于 2019-05-20 開始的一個項目,每個工作日發(fā)布一道面試題。每個周末我會仔細閱讀大家的答案,整理最一份較優(yōu)答案出來,因本人水平有限,有誤的地方...
摘要:靜態(tài)類型系統(tǒng)能幫助你有效防止許多潛在的運行時錯誤,而且隨著你的應(yīng)用日漸豐滿會更加顯著。選擇,會生成符合規(guī)范的文件,使用,會生成滿足規(guī)范的文件,使用會生成使用的的代碼。使用或者是會生產(chǎn)包含特性的代碼。 showImg(https://segmentfault.com/img/bVbbhsr?w=800&h=800); 靜態(tài)類型系統(tǒng)能幫助你有效防止許多潛在的運行時錯誤,而且隨著你的應(yīng)用日漸...
摘要:若不存在則模塊標識應(yīng)該默認定義為在加載器中被請求腳本的標識。這也是目前很多插件頭部的寫法,就是用來兼容各種不同模塊化的寫法。語句輸出的值是動態(tài)綁定的,綁定其所在的模塊。 前言 歷史上,js沒有模塊化的概念,不能把一個大工程分解成很多小模塊。這對于多人開發(fā)大型,復(fù)雜的項目形成了巨大的障礙,明顯降低了開發(fā)效率,java,Python有import,甚至連css都有@import,但是令人費...
摘要:目前通行的的模板規(guī)范共有兩種和的模塊系統(tǒng),是參照規(guī)范實現(xiàn)的即為服務(wù)器端模塊的規(guī)范。規(guī)范則是非同步加載模塊,允許指定回調(diào)函數(shù)。 目前通行的Javascript的模板規(guī)范共有兩種:CommonJS 和 AMD commonjs nodejs的模塊系統(tǒng),是參照commonjs規(guī)范實現(xiàn)的 commonjs即為服務(wù)器端模塊的規(guī)范。 commonjs的規(guī)范: 根據(jù)commonjs規(guī)范,一個單獨的...
閱讀 2664·2021-11-24 09:39
閱讀 3509·2021-11-15 11:37
閱讀 2469·2021-10-08 10:04
閱讀 4088·2021-09-09 11:54
閱讀 1948·2021-08-18 10:24
閱讀 1180·2019-08-30 11:02
閱讀 1866·2019-08-29 18:45
閱讀 1765·2019-08-29 16:33