模塊化開發(fā)一 seajs

模塊化開發(fā)

隨著團(tuán)隊開發(fā)的復(fù)雜化匈庭,我們依賴的代碼庫會越來越多;

安裝

npm install spm -g
spm install seajs

可以安裝:
安裝bower
npm install -g bower
安裝seajs
brwer install seajs
github:
http://github.com/seajs/seajs

也可以下載成一個js文件引入
<script src="../lib/sea.js"></script>
<script>
console.log(seajs.version)
</script>

知識

  • 前端這些模塊管理的實現(xiàn)是基于AMD規(guī)范(異步饼记、管理象迎、加載規(guī)范)荧嵌,在最終實現(xiàn)的時候尊重commndjs規(guī)范(nodejs就是這個),定義模塊時有兩種,第一個是只傳一個參數(shù)就是commndjs規(guī)范啦撮,傳遞多個參數(shù)的時候谭网,寫法尊重moduletransport規(guī)范;

  • 通常define只允許我們定義一個模塊逻族,當(dāng)定義多個模塊的時候蜻底,后面的會覆蓋掉前面的;

seajs文件路徑是以sea.js作為出發(fā)點的 , 如果是'./'則以自身文件夾為出發(fā)點

使用

建立一個de.js文件

seajs.use('de')

在控制面板networks里能看到de.js被加載進(jìn)來了

define

當(dāng)傳遞一個參數(shù)的時候聘鳞,參數(shù)就是一個模塊,參數(shù)可以是任意類型薄辅;

在de.js中:
console.log('hello')

index.html:
seajs.use('de',function(main){
})

控制臺輸出:hello 字符串

define傳遞:
de.js輸入define('hello')

index.html:
seajs.use('de',function(main){
console.log(main)
})
控制臺輸出:hello 字符串

de.js輸入

define({
    color:'red',
    say:function(){
        return 'hello'
    }
})

控制臺輸出一個對象

  • 如果不寫在define里就是一個undefined

我們還可以傳遞函數(shù),這是一種最復(fù)雜的方式抠璃,工作中基本是這種方法:

這個函數(shù)自帶三個參數(shù):
require:引用其它模塊的工廠方法
exports:返回的接口對象
module:模塊的module屬性集
define(function(require,exports,module){
    return {
        color:'yellow'
    }
})
  • 當(dāng)傳遞多個參數(shù)時站楚,兩個或者三個
    如果傳遞兩個參數(shù)的時候,第一個參數(shù)表示該模塊依賴的模塊數(shù)組集合搏嗡,最后一個參數(shù)是function窿春;
    如果傳遞三個參數(shù)的時候,第一個表示模塊的名稱采盒,第二個表示該模塊依賴的模塊集合旧乞,第三個參數(shù)就是個function;
define('main',[],function(require,exports,module){
    return {
        color:'yellow'
    }
})

模塊的依賴

  • 包就是前段說的模塊
  • 當(dāng)傳遞模塊名稱的時候磅氨,模塊的名稱就是該名稱尺栖,當(dāng)不傳遞模塊的名稱的時候,該模塊的名稱就是該文件的名稱烦租,通常我們將模塊的名稱與文件的名稱保持一致

我們再新建一個header.js文件:

define(function(){
    return {
        color:'orange'
    }
})

在main.js中引用:

define(function(require,exports,module){
    var header = require('./header/header');
    console.log(header)
    return {
        color:'yellow'
    }
})

index.html的代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script src="js/sea.js"></script>
    <script>
        seajs.use('main',function(main){
            console.log(main)
        })
    </script>
</body>
</html>

控制臺輸出兩個對象延赌;

use


seajs.use(['header/header','header/skin/skin'],function(header,skin){
    console.log(header,skin)
})

第一個參數(shù)可以是一個字符串,也可以是一個模塊數(shù)組叉橱,有多少個挫以,在回調(diào)函數(shù)的參數(shù)就有多少個;

我們可以使用header:

define(function(require,exports,module){
    var header = require('./header/header');
    document.body.style.background = header.color;
    return {
        color:'yellow'
    }
})
  • require規(guī)范:
    1. require不能簡寫窃祝;
    2. require不能被重新定義掐松;
      • 不能賦值 var req = requie;是不可以的
      • 不能定義函數(shù) function require 是不可以的
      • 不能在子函數(shù)中的參數(shù)中使用require
      • 不能在子函數(shù)的作用域內(nèi)重定義(重復(fù)上面三條)
    3. require的參數(shù)只能是完整的字符串,拼接也不行require('abc' + 'cde')是不可以的粪小;
  • require的參數(shù)值如何定義:
    參數(shù)值表示的是文件的路徑甩栈,相對于sea.js,當(dāng)然也可以./從自身目錄出發(fā)

項目目錄:
- index.html
- js文件夾
- sea.js
- main.js
- header文件夾
- header.js
- skin文件夾
- skin.js
skin.js:

define(function(){
    return 'haha'
})

在main.js中引用:

define(function(require,exports,module){
    var header = require('./header/header');
    var skin = require('header/skin/skin')
    console.log(skin)
    document.body.style.background = header.color;
    return {
        color:'yellow'
    }
})

控制臺輸出:haha
require:

  • 可以看到是以sea.js為路徑起始點,也就是根目錄糕再;
  • 加載js文件量没,后綴名不寫;
    define:
    require,exports,module不能更改

前面說到定義一個模塊的時候最好名字和文件名一樣突想,默認(rèn)不寫模塊名殴蹄;

如果我們寫了不一樣的名字會怎么樣呢究抓?
header.js中:

define('haha',[],function(){
    return {
        color:'orange'
    }
})

可以看到模塊的名字為haha,依賴為空數(shù)組,文件名是header.js

main.js:

define(['header/header'],function(require,exports,module){
    var a = require('haha');
    var skin = require('header/skin/skin')
    console.log(a,111)
    return {
        color:'yellow'
    }
})

可以看到控制臺可以輸出結(jié)果;
所以

  • define的數(shù)組參數(shù)為依賴的模塊路徑
  • require為引入的模塊名字
  • 如果兩者相同袭灯,就可以直接var header = require('header/header'),不要后綴名.js

exports

  • export是保留字刺下,所以使用exports;
  • 表示模塊的接口,
    第一種:直接對exports添加屬性稽荧,如exports.color = 'red';
    第二種:通過module來定義橘茉,module.exports.color = 'yellow';
    第三種:通過module來定義,module.exports = {color: 'orange'};
    第四種:通過return來定義姨丈,return {color:'green'};

我們在一個模塊中定義接口的時候畅卓,只能使用一種,不能混用蟋恬,后面的會覆蓋前面的翁潘;

我們不可以直接對exports賦值新對象

main.js

define(function(require,exports,module){
    var a = require('header/header')
    console.log(a)
})

header.js

define(function(require,exports,module){
    exports.color = 'red'
})

注意:使用exports接口的header模塊,require,exports,module三個參數(shù)必須寫上;

第二種方式header.js:

define(function(require,exports,module){
    module.exports.color = 'red'
})

第三種方式header.js:

define(function(require,exports,module){
    module.exports={
        color:'blue'
    }
})

第四種方式header.js:

define(function(require,exports,module){
    return {
        color:'white'
    }
})

module

我們console.log(module)歼争;
有四個屬性:

  1. id 模塊名 默認(rèn)為路徑一致 如果id不與uri一樣則要分開引用
  2. uri 路徑
  3. dependencies 依賴的模塊 放在數(shù)組里
    deps 依賴的模塊 放在對象里
  4. exports是我們返回的接口拜马;

小案例

  • 項目根目錄
    • index.html
    • js文件夾
      • main.js
      • sea.js
      • lib文件夾
        • dom.js
        • event.js
        • string.js

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button id="btn">猜一猜</button>
    <div id="out"></div>
    <script src="js/sea.js"></script>
    <script>
        seajs.use('main',function(){})
    </script>
</body>
</html>

main.js:

define(function(require,exports,module){
    var Evt = require('lib/event');
    var Dom = require('lib/dom');
    var Str = require('lib/string')
    var msg = 'i don\'t know'
    Evt.on('btn','click',function(){
        Dom.html('out',Str.upper(msg))
    })
})

dom.js

define(function(){
    var Dom = {
        g: function(id){
            return document.getElementById(id);
        },
        html:function(id,html){
            if(html){
                this.g(id).innerHTML = html;
            }else{
                return this.g(id).innerHTML;
            }
        }
    }
    return Dom;
})

event.js

define(function(require,exports,module){
    var Dom = require('lib/dom')
    var Evt={
        on: function(id,type,fn){
            Dom.g(id)["on"+type] = fn;
        }
    }
    return Evt;
})

string.js

define(function(){
    var Str = {
        upper:function(str){
            return str.toUpperCase();
        }
    }
    return Str;
})
require.async異步調(diào)用,跟use方法很像沐绒,我們在頁面初始化使用use異步加載模塊俩莽,在模塊內(nèi)部想實現(xiàn)模塊的異步加載,就要用require.async方法乔遮;

案例一:
header.js:

define(function(require,exports,module){
    return {
        color:'white'
    }
})

main.js:

define(function(require,exports,module){
    var header = require('header/header')
    return {
        color: header.color
    }
})

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        html,body{
            height:100%;
        }
    </style>
</head>
<body>
    <script src="js/sea.js"></script>
    <script>
        seajs.use('main',function(main){
            console.log(main)
        })
    </script>
</body>
</html>

就可以得到header的color為white;

如果采用require.async(第一個參數(shù)為字符串也可以是數(shù)組豹绪,第二個參數(shù)是回調(diào)函數(shù)),和use很像申眼;

define(function(require,exports,module){
    // var header = require('header/header')
    var header = require.async('header/header',function(header){
        console.log(111,header)
    })
    return {
        color:header.color
    }
})
  • 再來看下面的代碼:
var loadSkin = false;
    if(loadSkin){
        var skin = require('header/skin/shin')
    }else{
        var header = require('header/header')
    }

其實兩個文件都會加載請求回來,但是skin打印是undefined
如果換成異步加載:

var loadSkin = false;
    if(loadSkin){
        var skin = require.async('header/skin/shin')
    }else{
        var header = require.async('header/header')
    }

可以看到不會執(zhí)行的代碼文件不會加載蝉衣;

seajs.config({})

寫在index.html seajs.use上面

seajs.config接收一個對象參數(shù)括尸,用來配置一些選項參數(shù)的,接收一個對象病毡,里面的屬性值濒翻,就是我們配置的選項;

1. alias

alias:{
    util:'lib/unitl-2.0'
}

這個可以解決一個問題:lib里面版本庫文件啦膜,如果在main.js,header.js等等一大堆文件中引用:

var util = require('lib/util-2.0');

如果一天這個文件升級到了2.1有送,那么就要去打開這些引用了它的文件去修改,就會造成麻煩僧家,所以alias就是解決這個問題的雀摘;
在alias中把這個文件定義為util,在mainjs,headerjs等文件中要使用它八拱,只需要

define(function(require,exports,module){
    var util = require('util');
    console.log(util)

})

這樣如果文件版本升級阵赠,只需要更改alias里面的路徑即可涯塔;

2. paths

paths:{
    m:'module/header'
}

如果我們要引用module/header下面的header.js

var header = require('module/header/header');

如果按照上面定義好了的路徑,以后引用這個文件夾下的文件只需要:

var header = require('m/header')

3. vars

vars:{
    hd:'header'
}

如何使用:

// var a = require('module/header/skin/skin')

var a = require('module/{hd}/skin/skin')

如果:

vars:{
    hd:'header/skin'
}

var a = require('module/{hd}/skin')

通過{}來匹配

4. map

map:[
    ['.js','.min.js']
]

映射清蚀,把所有的js文件做匹配處理匕荸;
如果有文件打包后,文件名可能不同枷邪,可以通過這個來處理榛搔;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市东揣,隨后出現(xiàn)的幾起案子践惑,更是在濱河造成了極大的恐慌,老刑警劉巖救斑,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件童本,死亡現(xiàn)場離奇詭異,居然都是意外死亡脸候,警方通過查閱死者的電腦和手機(jī)穷娱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來运沦,“玉大人泵额,你說我怎么就攤上這事⌒恚” “怎么了嫁盲?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烈掠。 經(jīng)常有香客問我羞秤,道長,這世上最難降的妖魔是什么左敌? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任瘾蛋,我火速辦了婚禮,結(jié)果婚禮上矫限,老公的妹妹穿的比我還像新娘哺哼。我一直安慰自己,他們只是感情好叼风,可當(dāng)我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布取董。 她就那樣靜靜地躺著,像睡著了一般无宿。 火紅的嫁衣襯著肌膚如雪茵汰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天孽鸡,我揣著相機(jī)與錄音经窖,去河邊找鬼坡垫。 笑死,一個胖子當(dāng)著我的面吹牛画侣,可吹牛的內(nèi)容都是我干的冰悠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼配乱,長吁一口氣:“原來是場噩夢啊……” “哼溉卓!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起搬泥,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤桑寨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后忿檩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尉尾,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年燥透,在試婚紗的時候發(fā)現(xiàn)自己被綠了沙咏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡班套,死狀恐怖肢藐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吱韭,我是刑警寧澤吆豹,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站理盆,受9級特大地震影響痘煤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜猿规,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一衷快、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧坎拐,春花似錦、人聲如沸养匈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呕乎。三九已至积担,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猬仁,已是汗流浹背帝璧。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工先誉, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人的烁。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓褐耳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親渴庆。 傳聞我的和親對象是個殘疾皇子铃芦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容