摘要:模塊化編程,已經(jīng)成為一個(gè)迫切的需求。隨著網(wǎng)站功能逐漸豐富,網(wǎng)頁中的也變得越來越復(fù)雜和臃腫,原有通過標(biāo)簽來導(dǎo)入一個(gè)個(gè)的文件這種方式已經(jīng)不能滿足現(xiàn)在互聯(lián)網(wǎng)開發(fā)模式,我們需要團(tuán)隊(duì)協(xié)作模塊復(fù)用單元測(cè)試等等一系列復(fù)雜的需求。
從CommonJS說起隨著網(wǎng)站逐漸變成"互聯(lián)網(wǎng)應(yīng)用程序",嵌入網(wǎng)頁的Javascript代碼越來越龐大,越來越復(fù)雜。網(wǎng)頁越來越像桌面程序,需要一個(gè)團(tuán)隊(duì)分工協(xié)作、進(jìn)度管理、單元測(cè)試等等......開發(fā)者不得不使用軟件工程的方法,管理網(wǎng)頁的業(yè)務(wù)邏輯。
Javascript模塊化編程,已經(jīng)成為一個(gè)迫切的需求。
CommonJS團(tuán)隊(duì)定義了module格式來解決JavaScript作用域問題,這樣確保了每一個(gè)module都在自己的命名空間下執(zhí)行。
根據(jù)CommonJS的規(guī)范,每個(gè)文件就是一個(gè)模塊,有自己的作用域。在一個(gè)文件里面定義的變量、函數(shù)、類,都是私有的,對(duì)其他文件不可見。
CommonJS規(guī)范規(guī)定,每個(gè)模塊內(nèi)部,module變量代表當(dāng)前模塊。這個(gè)變量是一個(gè)對(duì)象,它的exports屬性(即module.exports)是對(duì)外的接口。加載某個(gè)模塊,其實(shí)是加載該模塊的module.exports屬性。
CommonJS給出2個(gè)工具來實(shí)現(xiàn)模塊之間的依賴:
require() 用于在當(dāng)前作用域引入已有的模塊
module object 用于從當(dāng)前作用域?qū)С鲆恍〇|東
那就先搞一個(gè)Hello world的小栗子來試下吧!
編寫簡(jiǎn)單的JavaScript模塊新建一個(gè)項(xiàng)目文件夾吧,雖然項(xiàng)目很小。。。起名commonjs,在里邊新建2個(gè)JavaScript文件,分別命名為world.js和salute.js,代碼如下:
// salute.js 打招呼 var MySalute = "Hello"; module.exports = MySalute; /*注意上下是分別寫在2個(gè)文件js文件里哦*/ // world.js var MySalute = require("./salute"); var Result = MySalute + " world!"; console.log(Result);
然后無知的我有新建了一個(gè)demo.html,(想要在瀏覽器里打開看看是什么樣子)內(nèi)容如下:
Document
結(jié)果在瀏覽器中打開,查看控制臺(tái)大失所望,報(bào)了一個(gè)錯(cuò)誤
world.js:2 Uncaught ReferenceError: require is not defined
發(fā)現(xiàn)瀏覽器不兼容CommonJS的根本原因,在于缺少四個(gè)Node.js環(huán)境的變量:
module
exports
require
global
只要能夠提供這四個(gè)變量,瀏覽器就能加載 CommonJS 模塊,問題是可以解決的,但是好像并不怎么好玩,有興趣的朋友可以去阮老師博客里逛逛啊傳送門
現(xiàn)在我決定要去Node.js里邊玩一下了
Node.js環(huán)境里玩一把打開命令行工具cd到項(xiàng)目目錄:
結(jié)果順利打印出了Hello world!果然很有搞頭啊,呵呵.
那么寫到為止簡(jiǎn)單實(shí)現(xiàn)了模塊之間的引用,到底這個(gè)CommonJS規(guī)范下還可以做些什么呢?到CommonJS官網(wǎng)看了一下,發(fā)現(xiàn)如下內(nèi)容:
JavaScript是強(qiáng)調(diào)大面向?qū)ο笳Z言,而且?guī)в凶羁斓慕忉屍鳎抑暗腏avaScript定義的APIs僅僅用于構(gòu)建瀏覽器端的應(yīng)用,然而呢有了這個(gè)CommonJS就可以構(gòu)建更寬范圍的應(yīng)用了,具體點(diǎn)就是可以用JavaScript來寫:
服務(wù)器端應(yīng)用Server-side JavaScript applications
命令行工具Command line tools
基于GUI的桌面應(yīng)用Desktop GUI-based applications
Hybrid applications (Titanium, Adobe AIR)(這個(gè)是什么?雖然我現(xiàn)在還不知道,但感覺它很牛逼)
AMD是用來干甚么的?AMD (Asynchronous Module Definition)膚淺的理解異步模塊定義。。。
一開始大家可能以為CommonJS的天性就是同步,它的模塊系統(tǒng)并不適用于瀏覽器,而這個(gè)AMD就是指定了一個(gè)標(biāo)準(zhǔn),證明給別人看模塊化的JavaScript可以異步加載依賴,解決同步加載出現(xiàn)的問題。
define函數(shù)是AMD定義模塊的方法: define(id?: String, dependencies?: String[], factory: Function|Object); id:指定模塊名字 dependencies:指明依賴 factory:是定義模塊的,可以是function或object,如果是function那么函數(shù)的返回值就是module 導(dǎo)出的值。examples
define("myModule", ["jquery"], function($) { // $ is the export of the jquery module. $("body").text("hello world"); }); // and use it require(["myModule"], function(myModule) {});RequireJS
隨著網(wǎng)站功能逐漸豐富,網(wǎng)頁中的js也變得越來越復(fù)雜和臃腫,原有通過script標(biāo)簽來導(dǎo)入一個(gè)個(gè)的js文件這種方式已經(jīng)不能滿足現(xiàn)在互聯(lián)網(wǎng)開發(fā)模式,我們需要團(tuán)隊(duì)協(xié)作、模塊復(fù)用、單元測(cè)試等等一系列復(fù)雜的需求。
RequireJS是一個(gè)非常小巧的JavaScript模塊載入框架,是AMD規(guī)范最好的實(shí)現(xiàn)者之一。最新版本的RequireJS壓縮后只有14K,堪稱非常輕量。它還同時(shí)可以和其他的框架協(xié)同工作,使用RequireJS必將使您的前端代碼質(zhì)量得以提升。此段出處
CommonJS規(guī)范加載模塊是同步的,也就是說,只有加載完成,才能執(zhí)行后面的操作。AMD規(guī)范則是非同步加載模塊,允許指定回調(diào)函數(shù)。由于Node.js主要用于服務(wù)器編程,模塊文件一般都已經(jīng)存在于本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以CommonJS規(guī)范比較適用。但是,如果是瀏覽器環(huán)境,要從服務(wù)器端加載模塊,這時(shí)就必須采用非同步模式,因此瀏覽器端一般采用AMD規(guī)范。
瀏覽器同步加載js模塊新建a.js
(function(){ function test(){ alert("it works"); } test(); })()
新建demo1.html
Document body
在瀏覽器中運(yùn)行demo1.html,alert執(zhí)行的時(shí)候,html內(nèi)容是一片空白的,即body并未被顯示,當(dāng)點(diǎn)擊確定后,才出現(xiàn),這就是JS阻塞瀏覽器渲染導(dǎo)致的結(jié)果。
RequireJS異步加載js模塊把a(bǔ).js改寫如下:
define(function(){ function test(){ alert("it works"); } test(); })
到githug下載require.jsRequireJS download修改demo1.html如下:
!DOCTYPE html>Document body
瀏覽器提示了"it works",說明運(yùn)行正確,但是有一點(diǎn)不一樣,這次瀏覽器并不是一片空白,body已經(jīng)出現(xiàn)在頁面中,目前為止可以知道requirejs具有如下優(yōu)點(diǎn):
防止js加載阻塞頁面渲染
管理模塊之間的依賴性,便于代碼的編寫和維護(hù),使得代碼更加優(yōu)雅。
CMD規(guī)范CMD(Common Module Definition) 模塊定義規(guī)范。該規(guī)范明確了模塊的基本書寫格式和基本交互規(guī)則。在 CMD 規(guī)范中,一個(gè)模塊就是一個(gè)文件。代碼的書寫格式如下:
define(factory);
define 是一個(gè)全局函數(shù),用來定義模塊。define 接受 factory 參數(shù),factory 可以是一個(gè)函數(shù),也可以是一個(gè)對(duì)象或字符串。
factory 為對(duì)象、字符串時(shí),表示模塊的接口就是該對(duì)象、字符串。比如可以如下定義一個(gè) JSON 數(shù)據(jù)模塊:
define({ "foo": "bar" });
require 是一個(gè)方法,接受 模塊標(biāo)識(shí) 作為唯一參數(shù),用來獲取其他模塊提供的接口。
define(function(require, exports) { // 獲取模塊 a 的接口 var a = require("./a"); // 調(diào)用模塊 a 的方法 a.doSomething(); });
require.async 方法用來在模塊內(nèi)部異步加載模塊,并在加載完成后執(zhí)行指定回調(diào)。callback 參數(shù)可選。
define(function(require, exports, module) { // 異步加載一個(gè)模塊,在加載完成時(shí),執(zhí)行回調(diào) require.async("./b", function(b) { b.doSomething(); }); // 異步加載多個(gè)模塊,在加載完成時(shí),執(zhí)行回調(diào) require.async(["./c", "./d"], function(c, d) { c.doSomething(); d.doSomething(); }); });
require 是同步往下執(zhí)行,require.async 則是異步回調(diào)執(zhí)行。require.async 一般用來加載可延遲異步加載的模塊。
更詳細(xì)內(nèi)容請(qǐng)查看CMD 模塊定義規(guī)范
RequireJS 和 Sea.js 都是模塊加載器,倡導(dǎo)模塊化開發(fā)理念,核心價(jià)值是讓 JavaScript 的模塊化開發(fā)變得簡(jiǎn)單自然。
在 SeaJS 中,所有 JavaScript 文件都應(yīng)該用模塊的形式來書寫,并且一個(gè)文件只包含一個(gè)模塊。
使用全局函數(shù) define 來定義模塊:
define(id?, dependencies?, factory);
id
當(dāng)前模塊的唯一標(biāo)識(shí)。該參數(shù)可選。如果沒有指定,默認(rèn)為模塊所在文件的訪問路徑。如果指定的話, 必須是頂級(jí)或絕對(duì)標(biāo)識(shí)(不能是相對(duì)標(biāo)識(shí))。
dependencies
當(dāng)前模塊所依賴的模塊,是一個(gè)由模塊標(biāo)識(shí)組成的數(shù)組。該參數(shù)可選。如果沒有指定,模塊加載器會(huì)從 factory.toString() 中解析出該數(shù)組。
factory
模塊的工廠函數(shù)。模塊初始化時(shí),會(huì)調(diào)用且僅調(diào)用一次該工廠函數(shù)。factory 可以是函數(shù), 也可以是對(duì)象、字符串等任意值,這時(shí) module.exports 會(huì)直接設(shè)置為 factory 值。
factory 函數(shù)在調(diào)用時(shí),會(huì)始終傳入三個(gè)參數(shù): require、exports 和 module, 這三個(gè)參數(shù)在所有模塊代碼里可用。
define(function(require, exports, module) { // The module code goes here });
more
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/82895.html
摘要:因?yàn)闉g覽器環(huán)境里是單線程的,所以異步編程在前端領(lǐng)域尤為重要。除此之外,它還有兩個(gè)特性,使它可以作為異步編程的完整解決方案函數(shù)體內(nèi)外的數(shù)據(jù)交換和錯(cuò)誤處理機(jī)制。 showImg(https://segmentfault.com/img/bVz9Cy); 在我們?nèi)粘>幋a中,需要異步的場(chǎng)景很多,比如讀取文件內(nèi)容、獲取遠(yuǎn)程數(shù)據(jù)、發(fā)送數(shù)據(jù)到服務(wù)端等。因?yàn)闉g覽器環(huán)境里Javascript是單線程的,...
摘要:為了防止某些文檔或腳本加載別的域下的未知內(nèi)容,防止造成泄露隱私,破壞系統(tǒng)等行為發(fā)生。模式構(gòu)建函數(shù)響應(yīng)式前端架構(gòu)過程中學(xué)到的經(jīng)驗(yàn)?zāi)J降牟煌幵谟冢饕獙W⒂谇‘?dāng)?shù)貙?shí)現(xiàn)應(yīng)用程序狀態(tài)突變。嚴(yán)重情況下,會(huì)造成惡意的流量劫持等問題。 今天是編輯周刊的日子。所以文章很多和周刊一樣。微信不能發(fā)鏈接,點(diǎn)了也木有用,所以請(qǐng)記得閱讀原文~ 發(fā)個(gè)動(dòng)圖娛樂下: 使用 SVG 動(dòng)畫制作游戲 使用 GASP ...
摘要:原文地址詳解的類博主博客地址的個(gè)人博客從當(dāng)初的一個(gè)彈窗語言,一步步發(fā)展成為現(xiàn)在前后端通吃的龐然大物。那么,的類又該怎么定義呢在面向?qū)ο缶幊讨校愂菍?duì)象的模板,定義了同一組對(duì)象又稱實(shí)例共有的屬性和方法。這個(gè)等同于的屬性現(xiàn)已棄用。。 前言 生活有度,人生添壽。 原文地址:詳解javascript的類 博主博客地址:Damonare的個(gè)人博客 ??Javascript從當(dāng)初的一個(gè)彈窗語言,一...
摘要:原文地址詳解的類博主博客地址的個(gè)人博客從當(dāng)初的一個(gè)彈窗語言,一步步發(fā)展成為現(xiàn)在前后端通吃的龐然大物。那么,的類又該怎么定義呢在面向?qū)ο缶幊讨校愂菍?duì)象的模板,定義了同一組對(duì)象又稱實(shí)例共有的屬性和方法。這個(gè)等同于的屬性現(xiàn)已棄用。。 前言 生活有度,人生添壽。 原文地址:詳解javascript的類 博主博客地址:Damonare的個(gè)人博客 ??Javascript從當(dāng)初的一個(gè)彈窗語言,一...
閱讀 1937·2021-11-24 09:39
閱讀 3522·2021-09-28 09:36
閱讀 3291·2021-09-06 15:10
閱讀 3446·2019-08-30 15:44
閱讀 1159·2019-08-30 15:43
閱讀 1802·2019-08-30 14:20
閱讀 2719·2019-08-30 12:51
閱讀 2038·2019-08-30 11:04