由來:javascript
在軟件開發過程當中,模塊化編程思想已經習覺得常了,模塊化編程不只僅給開發團隊帶來效率方面上的好處,還可以讓開發的項目或者產品維護成本大大下降。html
那麼,在WEB開發過程當中JS腳本語言已經不可或缺了,經過JS腳本語言可以帶來更加溫馨的人機交互和用戶體驗。可是,JS腳本的使用過程當中也會有出現引用依賴的混亂,那麼JS腳本語言的模塊化思想勢必會獲得你們普遍的承認,在這樣的一個背景下,淘寶前端工程師玉伯帶來了SeaJS腳本語言,讓模塊化編程思想進入到JS腳本的世界裏。前端
特色:java
SeaJS是一個遵循CommonJS規範的JavaScript模塊加載框架,能夠實現JavaScript的模塊化開發及加載機制。與jQuery等JavaScript框架不一樣,SeaJS不會擴展封裝語言特性,而只是實現JavaScript的模塊化及按模塊加載。SeaJS的主要目的是令JavaScript開發模塊化並能夠輕鬆愉悅進行加載,將前端工程師從繁重的JavaScript文件及對象依賴處理中解放出來,能夠專一於代碼自己的邏輯。SeaJS能夠與jQuery這類框架完美集成。使用SeaJS能夠提升JavaScript代碼的可讀性和清晰度,解決目前JavaScript編程中廣泛存在的依賴關係混亂和代碼糾纏等問題,方便代碼的編寫和維護。jquery
SeaJS自己遵循KISS(Keep It Simple, Stupid)理念進行開發,其自己僅有個位數的API,所以學習起來毫無壓力。在學習SeaJS的過程當中,到處能感覺到KISS原則的精髓——僅作一件事,作好一件事。算法
優點:從一個例子中來看SeaJS優點,編程
傳統模式:前端工程師
var M1={ run:function(){ alert('M1'); M2.run(); } } var M2={ run:function(){ alert('M2'); } } <script src="./M2.js"></script> <script src="./M1.js"></script>
使用SeaJS以後:app
//init.js define(function(require, exports, module) = { var m1=require('M1'); exports.init=function(){ m1.run(); } }); //M1.js define(function(require,exports,module)={ var m2=require('M2'); exports.run=function(){ alert('M1'); m2.run(); } }); define(function(require,exports,module)={ exports.run=function(){ alert('M2'); } }); <script src="./sea.js"></script> <script> seajs.use('./init', function(init) { init.init(); }); </script>
經過兩個簡單的實例可以看出使用SeaJS以後代碼的模塊化很是清晰,而且在HTML頁面中僅僅引用一個./sea.js文件而且僅僅調用init便可,具體init後面實現的邏輯對用戶是透明的。框架
經過這篇博客可以對SeaJS腳本語言有所瞭解,後面文章介紹利用SeaJS編寫模塊。
在介紹SeaJS模塊編寫和引用以前先介紹一下關於SeaJS模塊化的使用原則。
使用SeaJS開發JavaScript的基本原則就是:一切皆爲模塊。引入SeaJS後,編寫JavaScript代碼就變成了編寫一個又一個模塊,SeaJS中模塊的概念有點相似於面向對象中的類——模塊能夠擁有數據和方法,數據和方法能夠定義爲公共或私有,公共數據和方法能夠供別的模塊調用。另外,每一個模塊應該都定義在一個單獨js文件中,即一個對應一個模塊。
知道了這些以後咱們再來學習模塊的編寫,載入和引用。
模塊編寫:
SeaJS中使用define函數定義一個模塊。define能夠接收三個參數:require, exports, module。
require——模塊加載函數,用於記載依賴模塊。
exports——接口點,將數據或方法定義在其上則將其暴露給外部調用。
module——模塊的元數據。
關於模塊的幾種寫法:
第一種是教科書式的寫法,也是最經常使用的一種寫法。
define(function(require, exports, module) { var a = require('a'); //引入a模塊 var b = require('b'); //引入b模塊 var data1 = 1; //私有數據 var func1 = function() { //私有方法 return a.run(data1); } exports.data2 = 2; //公共數據 exports.func2 = function() { //公共方法 return 'hello'; } });
第二種方法是拋棄exports和module的方式:
define(function(require) { var a = require('a'); //引入a模塊 var b = require('b'); //引入b模塊 var data1 = 1; //私有數據 var func1 = function() { //私有方法 return a.run(data1); } return { data2: 2, func2: function() { return 'hello'; } }; });
第三種方式:相似於JSON寫法,其實就是沒有方法的一種寫法。
define({ data: 1, func: function() { return 'hello'; } });
經過這三種方式應該對模塊的編寫有所瞭解了,估計你已經火燒眉毛的想去寫幾個模塊嘗試一下了,那就快點來寫吧。
SeaJS支持以下幾種方式:
第一種:絕對路徑--給出js文件的絕對路徑
require("http://example/js/a");
第二種:相對路徑--用相對調用載入函數所在js文件的相對地址尋找模塊
require("./c");
第三種:經過全局變量來匹配相對路徑:相對SeaJS全局配置中的「base」來尋址(後面文章會介紹到)
SeaJS提供了三種載入的方式:seajs.use,require和require.async
第一種:seajs.use
seajs.use主要用於載入入口模塊。入口模塊至關於JAVA程序的main函數,同時也是整個模塊依賴樹的根。
這種方式有幾種寫法:
//單一模式 seajs.use('./a'); //回調模式 seajs.use('./a', function(a) { a.run(); }); //多模塊模式 seajs.use(['./a', './b'], function(a, b) { a.run(); b.run(); });
通常seajs.use只用在頁面載入入口模塊,SeaJS會順着入口模塊解析全部依賴模塊並將它們加載。若是入口模塊只有一個,也能夠經過給引入sea.js的script標籤加入」data-main」屬性來省略seajs.use。
來個小實例來講明一下:
<!DOCTYPE HTML> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>TinyApp</title> </head> <body> <p class="content"></p> <script src="./sea.js" data-main="./init"></script> </body> </html>
第二種:require
require是SeaJS主要的模塊加載方法,當在一個模塊中須要用到其它模塊時通常用require加載:ar a = require('a'); //引入a模塊
第三種:require.async
以前的require方式是一次把全部依賴的JS文件都加載進來,若是想何時用到何時加載的話就會用這種方式,這種方式效率比require高一些。
經過上面的介紹,應該對SeaJS的模塊載入和引用有所瞭解了,其實者經過這幾篇的介紹會發現SeaJS的模塊化編程思想和它帶給開發人員的簡單易用的特色。下篇博客介紹一下SeaJS的全局配置。
SeaJS提供了一個seajs.config方法能夠設置全局配置,接收一個表示全局配置的配置對象。具體使用方法以下:
seajs.config({ base: 'path/to/jslib/', alias: { 'app': 'path/to/app/' }, charset: 'utf-8', timeout: 20000, debug: false });
若是在JS腳本中引入模塊jquery的話,var $ = require('jquery');那麼這時候在上篇博客中說道的引入模塊的方式之三就能夠用全局配置來操做了。
在全局配置中base表示基址尋址時的基址路徑。base設置爲 http://example.com/js/3-party/ ,那麼就會載入base路徑下的juery模塊。
另外的一些屬性的用途爲:
alias能夠對較長的經常使用路徑設置縮寫。
charset表示下載js時script標籤的charset屬性。
timeout表示下載文件的最大時長,以毫秒爲單位。
debug表示是否工做在調試模式下。
經過這樣的一個全局配置,開發者可以很輕鬆的將一些很長很繁瑣的公用的路徑等來提取到全局配置中,減輕了開發者的繁瑣的CV(複製、黏貼)操做。
到這裏,關於SeaJS簡介就介紹完了,咱們會發現這個腳本語言模塊化的特色很是突出,而且語言自己比較簡單而且上手容易。