首頁  >  文章  >  web前端  >  JavaScript模組化開發之SeaJS_javascript技巧

JavaScript模組化開發之SeaJS_javascript技巧

WBOY
WBOY原創
2016-05-16 15:25:591387瀏覽

前言

  SeaJS是遵循CommonJS規格的JavaScript模組載入框架,可以實作JavaScript的模組化開發與載入機制。使用SeaJS可以提高JavaScript程式碼的可讀性和清晰度,解決目前JavaScript程式設計中普遍存在的依賴關係混亂和程式碼糾纏等問題,方便程式碼的編寫和維護。

SeaJS本身遵循KISS(Keep it Simple,Stupid)理念進行開發,後續的幾個版本更新也都是吵著這個方向邁進。

如何使用SeaJS

下載及安裝在這裡不贅述了,不了解的請查詢官網。

基本開發原則
 •一切皆為模組:SeaJS中的模組概念有點類似於物件導向中的類別--模組可以擁有資料和方法,資料和方法可以定義為公共或私有,公共資料和方法可以供別的模組呼叫。

 •每個模組應該定義在單獨的js檔案中,也就是一個對應一個模組。

模組的定義與編寫

模組定義函數define

SeaJS中使用define函數定義一個模組。 define可以接收三個參數:

/**
* Defines a module.
* @param {string=} id The module id.
* @param {Array.|string=} deps The module dependencies.
* @param {function()|Object} factory The module factory function.
*/
fn.define = function(id, deps, factory) {
  //code of function…
}

define可以接收的參數分別是模組ID,依賴模組數組及工廠函數。

 •如果只有一個參數,則賦值給factory

 •如果有兩個參數,第二個賦值給factory,第一個如果是數組則賦值給deps,否則賦值給id

•如果有三個參數,則分別賦值

但是,包括SeaJS官網範例在內幾乎所有用到define的地方都只傳遞一個工廠函數進去,類似於如下程式碼:

define(function(require,exports,module){
  //code of the module
}) 

個人建議遵循SeaJS官方範例的標準,用一個參數的define定義模組。那麼id和deps會怎麼處理呢?

  id是一個模組的識別字串,define只有一個參數時,id會被預設賦值為此js檔案的絕對路徑。如example.com下的a.js檔案中使用define定義模組,則這個模組的ID會賦值為http://example.com/a.js ,沒有特別的必要建議不要傳入id。 deps一般也不需要傳入,需要用到的模組用require載入即可。

工廠函數factory解析

  工廠函數是模組的主體和重點。它的三個參數分別是:

 •require:模組載入函數,用於記載依賴模組
 •exports:介面點,將資料或方法定義在其上則將其暴露給外部呼叫
 •module:模組的元資料

這三個參數可以根據需要選擇是否需要顯示指定。

module是一個對象,儲存了模組的元訊息,具體如下:
 •module.id:模組的ID
 •module.dependencies:一個數組,儲存了這個模組所依賴的所有模組的ID列表。
 •module.exports:與exports指向同一個物件

三種編寫模組的模式

第一種是基於exports的模式:

define(function(require,exports,module){
  var a=require('a');
  var b=require('b'); //引入模块
  var data1=1; //私有数据
  var fun1=function(){//私有方法
    return a.run(data1);
  }
  exports.data2=2; //公有数据
  exports.fun2=function(){
    return 'hello';
  }
})

上面是一種比較「正宗」的模組定義模式。除了講公共資料和方法附加在exports上,也可以直接傳回一個物件表示模組,如下面的程式碼與上面的程式碼功能相同:

define(function(require){
  var a=require('a');
  var b=require('b'); //引入模块
  var data1=1;
  var fun1=function(){
    return a.run(data1);
  }
  return{
    data2:2,
    fun2:function(){
      return 'hello';
    }
  }
})

如果模組定義沒有其他程式碼,只回傳一個對象,還可以有以下簡化寫法:

define({
  data2:2,
    fun2:function(){
      return 'hello';
    }
  }) 

第三種寫法對於定義純JSON資料的模組非常合適。

根據應用程式場景的不同,SeaJS提供了三個載入模組的API,分別是:seajs.use,require和require.async。

seajs.use

seajs.use主要用於載入入口模組。入口模組相當於C語言的main函數,同時也是整個模組依賴樹的根。 seajs.use
 的用法如下:

//第一模式
seajs.use('./a');
//回调模式
seajs.use('./a',function(a){
  a.run();
})
//多模块模式
seajs.use(['./a','./b'],function(a,b){
  a.run();
  b.run();
}) 

其中多模組的用法和KISSY中的模組載入方法類似,不虧是一個人寫的啊!

 一般seajs.use只用在頁面載入入口模組,SeaJS會順著入口模組解析所有依賴模組並將它們載入。如果入口模組只有一個,也可以透過將引入seajs的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載入:

var m=require('./a'); 
require.async

上文说过seajs会在html页面打开时通过静态分析一次性记载所有需要的js文件,如果想要某个js文件在用时才加载,可以使用require.async。

 这样只有在用到这个模块时,对应的js文件才会被下载,也就实现了JavaScript代码的按需加载。

SeaJS的全局配置

seajs提供了一个seaj.configd的方法可以设置全局配置,接收一个表示全局配置的配置对象,具体方法如下:

seajs.config({
base:'path',
alias:{
  'app':'path/app/'
},
charset:'utf-8',
timeout:20000,
debug:false
})

其中,

 •base表示基址路径
 •alias可以对较长的常用路径设置缩写
 •charset表示下载js时script标签的charset属性。
 •timeout表示下载文件的最大时长,以毫秒为单位。

Seajs如何与现有的JS库配合使用

要将现有的JS库与seajs一起使用,只需根据seajs的模块定义规则对现有库进行一个封装。例如,下面是对jQuery的封装方法:

define(function(){
  /*
  此处为jquery源码
  */
  }) 

一个完整的例子:

 上文说了那么多,知识点比较分散,所以最后我打算用一个完整的SeaJS例子把这些知识点串起来,方便朋友们归纳回顾。这个例子包含如下文件:
 •index.html 主页面

 •sea.js
 •jquery.js
 •init.js init模块,入口模块,依赖data、jquery、style三个模块,又主页面载入
 •data.js data模块,纯json数据模块
 •style.css css样式表

html:
<!DOCTYPE HTML>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="content">
  <p class="author"></p>
  <p class="blog"><a href="#">Blog</a></p>
</div>
<script src="sea.js"></script>
<script>
    seajs.use('init');
</script>
</body>
</html> 
javascript:
//init.js
define(function(require, exports, module) {
  var $ = require('./jquery');
  var data = require('./data');
  var css = require('./style.css');
  $('.author').html(data.author);
  $('.blog').attr('href', data.blog);
});
//data.js
define({
  author: 'ZhangYang',
  blog: 'http://blog.codinglabs.org'
}); 
css:
.author{color:red;font-size:10pt;}
.blog{font-size:10pt;} 

请注意:

1.请讲jquery.js源码文件包含在seajs模块加载代码中;

2.在Sea.js < 2.3.0版本之前是可以加载css文件的,新版本中此功能移除,为了兼容考虑,加载css功能将作为一个插件存在。

使用方法

 •可以在sea.js标签后引入这个插件使用
 •也可以将插件代码混入sea.js当中
 •和seajs-style的区别 •seajs-css是使 Sea.js 能够加载一个css文件,和link标签一样
 •seajs-style是指提供一个seajs.importStyle方法用于加载一段 css 字符串

以上内容是小编给大家分享的JavaScript模块化开发之SeaJS,希望对大家学习javascript模块化开发有所帮助,谢谢大家一直以来对脚本之家网站的支持。!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn