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