摘要:提倡依賴前置,在定義模塊的時候就要聲明其依賴的模塊。適用場景按需加載條件加載動態(tài)的模塊路徑注關(guān)于模塊化,詳細(xì)見阮一峰的入門模塊與模塊化區(qū)別模塊化的規(guī)范和兩種。
模塊化開發(fā)方便代碼的管理,提高代碼復(fù)用性,降低代碼耦合,每個模塊都會有自己的作用域。當(dāng)前流行的模塊化規(guī)范有CommonJS,AMD,CMD,ES6的import/export
CommonJS的主要實(shí)踐者就是nodejs,一般對模塊輸出用module.exports去輸出,用require去引入模塊,CommonJS一般采用同步加載【require / module.exports / exports】
AMD遵從RequireJs規(guī)范,推崇依賴前置(提前執(zhí)行)【require / defined】
CMD遵從SeaJs規(guī)范,推崇依賴就近(延遲執(zhí)行)【require / defined】
ES6 可靜態(tài)分析,提前編譯,不是在運(yùn)行時確認(rèn)【import / export】
發(fā)展歷程簡單封裝 -> 命名空間/modules -> script loader/modules loader -> 同步加載CommonJS/AMD/CMD -> ES6 import export/export default -> 模塊打包工具browserify/webpack
簡單封裝用法:把不同的函數(shù)簡單地放在一起,看作一個模塊
缺點(diǎn):
"污染"了全局變量,無法保證不與其他模塊發(fā)生變量名沖突;
模塊成員之間看不出直接關(guān)系
對象(命名空間)用法:把功能代碼放入對象中,當(dāng)作對象的屬性
優(yōu)點(diǎn):減少了全局上的變量數(shù)目,避免變量全局污染
缺點(diǎn):本質(zhì)是對象,而這個對象會暴露所有模塊成員,內(nèi)部狀態(tài)可以被外部改寫
聲明一個匿名函數(shù)
馬上調(diào)用這個匿名函數(shù)
作用:創(chuàng)建一個獨(dú)立的作用域。數(shù)據(jù)是私有的, 外部只能通過暴露的方法操作
這個作用域里面的變量,外面訪問不到(即避免「變量污染」)
導(dǎo)入導(dǎo)出:require & exports/module.exports
主要實(shí)踐者:NodeJS
模塊導(dǎo)入
語法:require(module)
eg: var math = require("math"); math.add(2, 3);
如果模塊輸出的是一個函數(shù),那就不能定義在exports對象上面,而要定義在module.exports變量上面。
// example2.js module.exports = function () { console.log("hello world") } // main.js require("./example2.js")()AMD(Asynchronous Module Definition)
提倡依賴前置,在定義模塊的時候就要聲明其依賴的模塊。在requireJs推廣過程中產(chǎn)生的規(guī)范
模塊定義
define(id?, dependencies?, factory)
id:字符串,模塊名稱(可選)
dependencies:數(shù)組,是我們要載入的依賴模塊(可選),使用相對路徑
factory:工廠方法,返回一個模塊函數(shù)
模塊導(dǎo)入
require([module], callback)
module:是一個數(shù)組,里面的成員就是要加載的模塊
callback:則是加載成功之后的回調(diào)函數(shù)
requireJS 優(yōu)點(diǎn)
實(shí)現(xiàn)js文件的異步加載,避免網(wǎng)頁失去響應(yīng);
管理模塊之間的依賴性,按照依賴關(guān)系加載,便于代碼的編寫和維護(hù)。
采用異步方式加載模塊,通過define來定義一個模塊,通過require來引入模塊,模塊的加載不影響后面語句的執(zhí)行,所有依賴于這些模塊的語句都寫在一個回調(diào)函數(shù)中,加載完畢后,這個回調(diào)函數(shù)才運(yùn)行
CMD(Common Module Definition)提倡就近依賴(按需加載),在用到某個模塊的時候再去require進(jìn)來。在Sea.js推廣過程中產(chǎn)生的規(guī)范
模塊定義
define(id?, dependencies?, factory) 與AMD類似
// eg define("hello", ["jquery"], function(require, exports, module) { // 模塊代碼 // return 模塊對象 });
模塊導(dǎo)入導(dǎo)出
與 AMD 類似
導(dǎo)入導(dǎo)出:import/export/export default
export defalut默認(rèn)輸出是一個函數(shù)/變量
其他模塊加載該模塊時,import命令可以為該匿名函數(shù)指定任意名字
需要注意的是,這時import命令后面,不使用大括號
// export-fn.js export default function () { console.log("foo"); } import foo from "export-fn.js"
export default命令也可以用在非匿名函數(shù)前,視同匿名函數(shù)加載
export default 命令用于指定模塊的默認(rèn)輸出。一個模塊只能有一個默認(rèn)輸出,因此export default 命令只能使用一次。所以,import命令后面才不用加大括號,因?yàn)橹豢赡芪ㄒ粚?yīng)export default命令。
本質(zhì)上,export default就是輸出一個叫做default的變量或方法,然后系統(tǒng)允許你為它取任意名字
使用export default時,對應(yīng)的import語句不需要使用大括號,默認(rèn)輸出
使用export時,對應(yīng)的import語句需要使用大括號
// 第一組 export default export default function crc32() { // 輸出 // ... } import crc32 from "crc32"; // 輸入 // 第二組 export export function crc32() { // 輸出 // ... }; import {crc32} from "crc32"; // 輸入ES6、AMD和CommonJS區(qū)別
ES6模塊使得編譯時就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。
CommonJS 和 AMD 模塊,都只能在運(yùn)行時確定這些東西;
CommonJS 模塊就是對象,輸入時必須查找對象屬性
CommonJS模塊
let { stat, exists, readFile } = require("fs")
整體加載fs模塊(即加載fs的所有方法),生成一個對象(_fs),然后再從這個對象上面讀取 3 個方法。這種加載稱為“運(yùn)行時加載”
ES6模塊
import { stat, exists, readFile } from "fs"
從fs模塊加載 3 個方法,其他方法不加載,這種加載稱為“編譯時加載”或者靜態(tài)加載
CommonJS模塊
const path = "./" + fileName const myModual = require(path)
動態(tài)加載,require到底加載哪一個模塊,只有運(yùn)行時才知道
import()動態(tài)加載,正在提案階段,import()返回一個 Promise 對象
import()加載模塊成功以后,這個模塊會作為一個對象,當(dāng)作then方法的參數(shù)
import()類似于 Node 的require方法,區(qū)別主要是前者是異步加載,后者是同步加載。
適用場景
(1)按需加載
(2)條件加載
(3)動態(tài)的模塊路徑
注:關(guān)于ES6模塊化,詳細(xì)見 阮一峰的es6入門 module模塊
es6 與 commonJS/AMD 模塊化區(qū)別模塊化的規(guī)范:CommonJS和AMD兩種。前者用于服務(wù)器,后者用于瀏覽器。
而ES6 中提供了簡單的模塊系統(tǒng),完全可以取代現(xiàn)有的CommonJS和AMD規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。
ES6 模塊的設(shè)計(jì)思想,是盡量的靜態(tài)化,使得編譯時就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運(yùn)行時確定這些東西。
require與import的區(qū)別(commonJS與ES6模塊化區(qū)別)require/exports是CommonJS的一部分;import/export是ES6的新規(guī)范
require支持 動態(tài)導(dǎo)入,import不支持,正在提案 (babel 下可支持)
require是 同步 導(dǎo)入,import屬于 異步 導(dǎo)入
require是 值拷貝,導(dǎo)出值變化不會影響導(dǎo)入值;import是值引用,指向 內(nèi)存地址,導(dǎo)入值會隨導(dǎo)出值而變化
參考:
前端工程師必備:前端的模塊化
阮一峰的es6入門 module模塊
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103938.html
摘要:課程制作和案例制作都經(jīng)過精心編排。對于開發(fā)者意義重大,希望對有需要的開發(fā)者有所幫助。是從提案轉(zhuǎn)為正式加入的新特性。并不需要用繼承,而是推薦用嵌套。大型項(xiàng)目中模塊化與功能解耦困難。從而更加易于復(fù)用和獨(dú)立測試。但使用會減少這種幾率。 showImg(https://segmentfault.com/img/bVbpNRZ?w=1920&h=1080); 講師簡介 曾任職中軟軍隊(duì)事業(yè)部,參與...
摘要:例如我們導(dǎo)入模塊,可以這么導(dǎo)入桃翁歡迎關(guān)注公眾號前端桃園報錯不能定義相同名字變量報錯,不能重新賦值小豬可以看到導(dǎo)入綁定這里不理解綁定,文章后面會解釋時,形式類似于對象解構(gòu),但實(shí)際上并無關(guān)聯(lián)。 歡迎訪問個人站點(diǎn) 簡介 何為模塊 一個模塊只不過是一個寫在文件中的 JavaScript 代碼塊。 模塊中的函數(shù)或變量不可用,除非模塊文件導(dǎo)出它們。 簡單地說,這些模塊可以幫助你在你的模塊中編寫...
摘要:依舊采取傳統(tǒng)的開發(fā)技術(shù)棧進(jìn)行開發(fā),同時在終端的運(yùn)行體驗(yàn)不輸。首先來看下前端開發(fā)框架目前與構(gòu)成了三大最流行的前端開發(fā)框架,具有組件化以及三大特性,還學(xué)習(xí)的,引入了狀態(tài)管理模塊。 摘要: WEEX依舊采取傳統(tǒng)的web開發(fā)技術(shù)棧進(jìn)行開發(fā),同時app在終端的運(yùn)行體驗(yàn)不輸native app。其同時解決了開發(fā)效率、發(fā)版速度以及用戶體驗(yàn)三個核心問題。那么WEEX是如何實(shí)現(xiàn)的?目前WEEX已經(jīng)完全開...
閱讀 2742·2021-11-22 13:54
閱讀 1082·2021-10-14 09:48
閱讀 2305·2021-09-08 09:35
閱讀 1569·2019-08-30 15:53
閱讀 1180·2019-08-30 13:14
閱讀 619·2019-08-30 13:09
閱讀 2533·2019-08-30 10:57
閱讀 3345·2019-08-29 13:18