亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

SeaJS入門教程系列之使用SeaJS(二)

2019-11-20 21:01:26
字體:
來源:轉載
供稿:網友

下載及安裝

要在項目中使用SeaJS,你所有需要做的準備工作就是下載sea.js然后放到你項目的某個位置。
SeaJS項目目前托管在GitHub上,主頁為 https://github.com/seajs/seajs/ 。可以到其git庫的build目錄下下載sea.js(已壓縮)或sea-debug.js(未壓縮)。
下載完成后放到項目的相應位置,然后在頁面中通過<script>標簽引入,你就可以使用SeaJS了。

SeaJS基本開發原則

在討論SeaJS的具體使用前,先介紹一下SeaJS的模塊化理念和開發原則。
使用SeaJS開發JavaScript的基本原則就是:一切皆為模塊。引入SeaJS后,編寫JavaScript代碼就變成了編寫一個又一個模塊,SeaJS中模塊的概念有點類似于面向對象中的類――模塊可以擁有數據和方法,數據和方法可以定義為公共或私有,公共數據和方法可以供別的模塊調用。
另外,每個模塊應該都定義在一個單獨js文件中,即一個對應一個模塊。
下面介紹模塊的編寫和調用。

模塊的定義及編寫

模塊定義函數define
SeaJS中使用“define”函數定義一個模塊。因為SeaJS的文檔并沒有關于define的完整參考,所以我閱讀了SeaJS源代碼,發現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…
}

上面是我從SeaJS源碼中摘錄出來的,define可以接收的參數分別是模塊ID,依賴模塊數組及工廠函數。我閱讀源代碼后發現define對于不同參數個數的解析規則如下:
如果只有一個參數,則賦值給factory。
如果有兩個參數,第二個賦值給factory;第一個如果是array則賦值給deps,否則賦值給id。
如果有三個參數,則分別賦值給id,deps和factory。
但是,包括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解析

工廠函數是模塊的主體和重點。在只傳遞一個參數給define時(推薦寫法),這個參數就是工廠函數,此時工廠函數的三個參數分別是:
1.require――模塊加載函數,用于記載依賴模塊。
2.exports――接口點,將數據或方法定義在其上則將其暴露給外部調用。
3.module――模塊的元數據。
這三個參數可以根據需要選擇是否需要顯示指定。
下面說一下module。module是一個對象,存儲了模塊的元信息,具體如下:
1.module.id――模塊的ID。
2.module.dependencies――一個數組,存儲了此模塊依賴的所有模塊的ID列表。
3.module.exports――與exports指向同一個對象。

三種編寫模塊的模式

第一種定義模塊的模式是基于exports的模式:

復制代碼 代碼如下:

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上,也可以直接返回一個對象表示模塊,如下面的代碼與上面的代碼功能相同:

復制代碼 代碼如下:
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';
        }
    };
});

如果模塊定義沒有其它代碼,只返回一個對象,還可以有如下簡化寫法:

復制代碼 代碼如下:
define({
    data: 1,
    func: function() {
        return 'hello';
    }
});

第三種方法對于定義純JSON數據的模塊非常合適。

模塊的載入和引用

模塊的尋址算法
上文說過一個模塊對應一個js文件,而載入模塊時一般都是提供一個字符串參數告訴載入函數需要的模塊,所以就需要有一套從字符串標識到實際模塊所在文件路徑的解析算法。SeaJS支持如下標識:
絕對地址――給出js文件的絕對路徑。

如:

復制代碼 代碼如下:
require("http://example/js/a");

就代表載入 http://example/js/a.js 。
相對地址――用相對調用載入函數所在js文件的相對地址尋找模塊。
例如在 http://example/js/b.js 中載入
復制代碼 代碼如下:
require("./c");

則載入 http://example/js/c.js 。
基址地址――如果載入字符串標識既不是絕對路徑也不是以”./”開頭,則相對SeaJS全局配置中的“base”來尋址,這種方法稍后討論。
注意上面在載入模塊時都不用傳遞后綴名“.js”,SeaJS會自動添加“.js”。但是下面三種情況下不會添加:
載入css時,如:
復制代碼 代碼如下:
require("./module1-style.css");

路徑中含有”?”時,如:
復制代碼 代碼如下:
require(<a href="http://example/js/a.json?cb=func">http://example/js/a.json?cb=func</a>);

路徑以”#”結尾時,如:
復制代碼 代碼如下:
require("http://example/js/a.json#");

根據應用場景的不同,SeaJS提供了三個載入模塊的API,分別是seajs.use,require和require.async,下面分別介紹。

seajs.use

seajs.use主要用于載入入口模塊。入口模塊相當于C程序的main函數,同時也是整個模塊依賴樹的根。上面在TinyApp小例子中,init就是入口模塊。seajs.use用法如下:

復制代碼 代碼如下:

//單一模式
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,例如,上面TinyApp的index.html也可以改為如下寫法:
復制代碼 代碼如下:

<!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>

這種寫法會令html更加簡潔。

require

require是SeaJS主要的模塊加載方法,當在一個模塊中需要用到其它模塊時一般用require加載:

復制代碼 代碼如下:
var m = require('/path/to/module/file');

這里簡要介紹一下SeaJS的自動加載機制。上文說過,使用SeaJS后html只要包含sea.js即可,那么其它js文件是如何加載進來的呢?SeaJS會首先下載入口模塊,然后順著入口模塊使用正則表達式匹配代碼中所有的require,再根據require中的文件路徑標識下載相應的js文件,對下載來的js文件再迭代進行類似操作。整個過程類似圖的遍歷操作(因為可能存在交叉循環依賴所以整個依賴數據結構是一個圖而不是樹)。
明白了上面這一點,下面的規則就很好理解了:
傳給require的路徑標識必須是字符串字面量,不能是表達式,如下面使用require的方法是錯誤的:
復制代碼 代碼如下:
require('module' + '1');
require('Module'.toLowerCase());

這都會造成SeaJS無法進行正確的正則匹配以下載相應的js文件。

require.async

上文說過SeaJS會在html頁面打開時通過靜態分析一次性記載所有需要的js文件,如果想要某個js文件在用到時才下載,可以使用require.async:

復制代碼 代碼如下:
require.async('/path/to/module/file', function(m) {
    //code of callback...
});

這樣只有在用到這個模塊時,對應的js文件才會被下載,也就實現了JavaScript代碼的按需加載。

SeaJS的全局配置
SeaJS提供了一個seajs.config方法可以設置全局配置,接收一個表示全局配置的配置對象。具體使用方法如下:

復制代碼 代碼如下:
seajs.config({
    base: 'path/to/jslib/',
    alias: {
      'app': 'path/to/app/'
    },
    charset: 'utf-8',
    timeout: 20000,
    debug: false
});

其中base表示基址尋址時的基址路徑。例如base設置為 http://example.com/js/3-party/ ,則:
復制代碼 代碼如下:
var $ = require('jquery');

會載入 http://example.com/js/3-party/jquery.js 。
alias可以對較長的常用路徑設置縮寫。
charset表示下載js時script標簽的charset屬性。
timeout表示下載文件的最大時長,以毫秒為單位。
debug表示是否工作在調試模式下。

SeaJS如何與現有JS庫配合使用

要將現有JS庫如jQuery與SeaJS一起使用,只需根據SeaJS的的模塊定義規則對現有庫進行一個封裝。例如,下面是對jQuery的封裝方法:

復制代碼 代碼如下:
define(function() {

//{{{jQuery原有代碼開始
/*! 
 * jQuery JavaScript Library v1.6.1
 * http://jquery.com/
 *
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 * Copyright 2011, The Dojo Foundation
 * Released under the MIT, BSD, and GPL Licenses.
 *
 * Date: Thu May 12 15:04:36 2011 -0400
 */
//...
//}}}jQuery原有代碼結束

return $.noConflict();
});


SeaJS項目的打包部署

SeaJS本來集成了一個打包部署工具spm,后來作者為了更KISS一點,將spm拆出了SeaJS而成為了一個單獨的項目。spm的核心思想是將所有模塊的代碼都合并壓縮后并入入口模塊,由于SeaJS本身的特性,html不需要做任何改動就可以很方便的在開發環境和生產環境間切換。但是由于spm目前并沒有發布正式版本,所以本文不打算詳細介紹,有興趣的朋友可以參看其github項目主頁 https://github.com/seajs/spm/。
其實,由于每個項目所用的JS合并和壓縮工具不盡相同,所以spm可能并不是完全適合每個項目。在了解了SeaJS原理后,完全可以自己寫一個符合自己項目特征的合并打包腳本。


 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
性欧美xxxx| 亚洲综合在线中文字幕| 欧美成人一区二区三区电影| 欧美午夜精品久久久久久久| 欧美猛男性生活免费| 日韩大片在线观看视频| 国产精品啪视频| 成人观看高清在线观看免费| 中文字幕少妇一区二区三区| 国产日本欧美一区二区三区在线| 98午夜经典影视| www.欧美免费| 91久久嫩草影院一区二区| 欧美最猛性xxxxx免费| 国产综合久久久久| 国语对白做受69| 亚洲免费伊人电影在线观看av| 国产一区深夜福利| 69av视频在线播放| 欧美午夜精品久久久久久浪潮| 性欧美亚洲xxxx乳在线观看| 亚洲一区中文字幕在线观看| 日韩精品视频在线观看免费| 欧美性xxxxx| 亚洲第一视频网| 国产97在线|日韩| 亚洲一区二区日本| 亚洲大胆人体av| 国内揄拍国内精品| 91在线高清视频| 欧美性一区二区三区| 久久久久久69| 欧美日韩国产黄| 色综合久久天天综线观看| 亚洲已满18点击进入在线看片| 午夜精品在线视频| 国产日产欧美精品| 伊人伊成久久人综合网站| 欧美电影免费观看高清完整| 国产精品伦子伦免费视频| 国产有码在线一区二区视频| 欧美激情精品久久久久久大尺度| 国产精品永久免费视频| 九九热精品视频国产| 欧美精品成人91久久久久久久| 在线精品国产成人综合| 久久亚洲精品视频| 在线观看国产精品淫| 7m第一福利500精品视频| 91免费国产网站| 黄色精品在线看| 欧美极品少妇xxxxⅹ裸体艺术| 日韩欧美亚洲国产一区| 91高清免费视频| 国模视频一区二区三区| 久热爱精品视频线路一| 欧美性高跟鞋xxxxhd| 日韩电影免费在线观看中文字幕| 2019最新中文字幕| 国产成人亚洲精品| 91深夜福利视频| 国产精品永久免费在线| 欧美性生活大片免费观看网址| 国产91在线高潮白浆在线观看| 亚洲人成网站色ww在线| 精品一区二区电影| 中文字幕日韩视频| 欧美成人精品在线播放| 亚洲国产中文字幕久久网| 亚洲欧洲高清在线| 国产精品久久99久久| 九九热视频这里只有精品| 亚洲欧美国产日韩中文字幕| 亚洲免费av网址| 国产精品电影久久久久电影网| 久久久精品视频成人| 中文字幕日韩视频| 亚州国产精品久久久| 亚洲精品成人久久电影| 亚洲精品久久久久中文字幕欢迎你| 欧美一级淫片播放口| 在线一区二区日韩| 一本一道久久a久久精品逆3p| 日韩一二三在线视频播| 亚洲www永久成人夜色| 日本精品免费观看| 国产精品极品尤物在线观看| 91啪国产在线| 精品国产乱码久久久久酒店| 欧美激情视频在线观看| 欧美影院久久久| 2019中文字幕在线免费观看| 欧洲精品久久久| 国产精品网站视频| 精品国产一区二区三区久久久| 久久久久久欧美| 一区国产精品视频| 午夜剧场成人观在线视频免费观看| 最近2019年中文视频免费在线观看| 国产日韩在线观看av| 午夜精品蜜臀一区二区三区免费| 国产一区红桃视频| 亚洲午夜精品久久久久久久久久久久| 国产一区二区成人| 亚洲精品短视频| 日韩在线小视频| 成人免费看吃奶视频网站| 日韩电视剧在线观看免费网站| 成人免费看片视频| 日韩美女av在线免费观看| 久久男人资源视频| 亚洲国产精品一区二区三区| 国产亚洲精品一区二区| 亚洲欧洲在线观看| 欧美资源在线观看| 国产日韩欧美在线| 日韩禁在线播放| 欧美日韩国产页| 国产激情视频一区| 亚洲一区二区三区成人在线视频精品| 国产精品久久久久久久av电影| 秋霞成人午夜鲁丝一区二区三区| 亚洲精美色品网站| 亚洲电影免费观看高清完整版| 91精品国产亚洲| 97精品国产91久久久久久| 永久555www成人免费| 久久精品国产免费观看| 91九色国产在线| 国产精品久久久久久婷婷天堂| 日韩av手机在线观看| 欧美精品性视频| 色综合久久天天综线观看| 自拍偷拍免费精品| 日韩av在线免播放器| 中文字幕国产精品久久| 久久久女人电视剧免费播放下载| 国产一区二区三区三区在线观看| 欧美激情综合亚洲一二区| 国产美女久久精品香蕉69| 国产美女主播一区| 日韩在线高清视频| 日韩电影视频免费| 97国产suv精品一区二区62| 久久精品一偷一偷国产| 日本高清视频精品| 国产一区二区三区欧美| 久久亚洲精品成人| 日本午夜人人精品| 91高清视频免费观看| 色哟哟网站入口亚洲精品| 精品一区二区三区电影| 影音先锋欧美精品| 国产亚洲欧洲黄色| 欧美色视频日本版| 热99精品里视频精品| 欧美在线视频免费播放| 国产精品盗摄久久久| 亚洲人成欧美中文字幕| 97视频免费在线看| 国产91在线高潮白浆在线观看| 一区二区国产精品视频| 亚洲xxxxx| 中文字幕在线观看亚洲|