由来:

在软件开发过程中,模块化编程思想已经习以为常了,模块化编程不仅仅给开发团队带来效率方面上的好处,还能够让开发的项目或者产品维护成本大大降低。

那么,在WEB开发过程中JS脚本语言已经不可或缺了,通过JS脚本语言能够带来更加舒适的人机交互和用户体验。但是,JS脚本的使用过程中也会有出现引用依赖的混乱,那么JS脚本语言的模块化思想势必会得到大家广泛的认可,在这样的一个背景下,淘宝前端工程师玉伯带来了SeaJS脚本语言,让模块化编程思想进入到JS脚本的世界里。

特点:

SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制。与jQuery等JavaScript框架不同,SeaJS不会扩展封装语言特性,而只是实现JavaScript的模块化及按模块加载。SeaJS的主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载,将前端工程师从繁重的JavaScript文件及对象依赖处理中解放出来,可以专注于代码本身的逻辑。SeaJS可以与jQuery这类框架完美集成。使用SeaJS可以提高JavaScript代码的可读性和清晰度,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便代码的编写和维护。

SeaJS本身遵循KISS(Keep It Simple, Stupid)理念进行开发,其本身仅有个位数的API,因此学习起来毫无压力。在学习SeaJS的过程中,处处能感受到KISS原则的精髓——仅做一件事,做好一件事。

优势:从一个例子中来看SeaJS优势,

传统模式:

  1. var M1={
  2. run:function(){
  3. alert('M1');
  4. M2.run();
  5. }
  6. }
  7. var M2={
  8. run:function(){
  9. alert('M2');
  10. }
  11. }
  12. <script src="./M2.js"></script>
  13. <script src="./M1.js"></script>
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之后:

  1. //init.js
  2. define(function(require, exports, module) = {
  3. var m1=require('M1');
  4. exports.init=function(){
  5. m1.run();
  6. }
  7. });
  8. //M1.js
  9. define(function(require,exports,module)={
  10. var m2=require('M2');
  11. exports.run=function(){
  12. alert('M1');
  13. m2.run();
  14. }
  15. });
  16. define(function(require,exports,module)={
  17. exports.run=function(){
  18. alert('M2');
  19. }
  20. });
  21. <script src="./sea.js"></script>
  22. <script>
  23. seajs.use('./init', function(init) {
  24. init.init();
  25. });
  26. </script>
//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模块化的使用原则。

使用SeaJS开发JavaScript的基本原则就是:一切皆为模块。引入SeaJS后,编写JavaScript代码就变成了编写一个又一个模块,SeaJS中模块的概念有点类似于面向对象中的类——模块可以拥有数据和方法,数据和方法可以定义为公共或私有,公共数据和方法可以供别的模块调用。另外,每个模块应该都定义在一个单独js文件中,即一个对应一个模块。

知道了这些之后我们再来学习模块的编写,载入和引用。

模块编写:

SeaJS中使用define函数定义一个模块。define可以接收三个参数:require, exports, module。

require——模块加载函数,用于记载依赖模块。

exports——接口点,将数据或方法定义在其上则将其暴露给外部调用。

module——模块的元数据。

关于模块的几种写法:

第一种是教科书式的写法,也是最常用的一种写法。

  1. define(function(require, exports, module) {
  2. var a = require('a'); //引入a模块
  3. var b = require('b'); //引入b模块
  4. var data1 = 1; //私有数据
  5. var func1 = function() { //私有方法
  6. return a.run(data1);
  7. }
  8. exports.data2 = 2; //公共数据
  9. exports.func2 = function() { //公共方法
  10. return 'hello';
  11. }
  12. });
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的方式:

  1. define(function(require) {
  2. var a = require('a'); //引入a模块
  3. var b = require('b'); //引入b模块
  4. var data1 = 1; //私有数据
  5. var func1 = function() { //私有方法
  6. return a.run(data1);
  7. }
  8. return {
  9. data2: 2,
  10. func2: function() {
  11. return 'hello';
  12. }
  13. };
  14. });
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写法,其实就是没有方法的一种写法。

  1. define({
  2. data: 1,
  3. func: function() {
  4. return 'hello';
  5. }
  6. });
define({
data: 1,
func: function() {
return 'hello';
}
});

通过这三种方式应该对模块的编写有所了解了,估计你已经迫不及待的想去写几个模块尝试一下了,那就快点来写吧。

SeaJS简介三:模块载入和引用

之前对模块有过介绍,一个模块对应一个js文件,而载入模块时一般都是提供一个字符串参数告诉载入函数需要的模块,所以就需要有一套从字符串标识到实际模块所在文件路径的解析算法。

SeaJS支持如下几种方式:

第一种:绝对路径--给出js文件的绝对路径

  1. require("http://example/js/a");
require("http://example/js/a");

第二种:相对路径--用相对调用载入函数所在js文件的相对地址寻找模块

  1. require("./c");
require("./c");

第三种:通过全局变量来匹配相对路径:相对SeaJS全局配置中的“base”来寻址(后面文章会介绍到)

SeaJS提供了三种载入的方式:seajs.use,require和require.async

第一种:seajs.use

seajs.use主要用于载入入口模块。入口模块相当于JAVA程序的main函数,同时也是整个模块依赖树的根。

这种方式有几种写法:

  1. //单一模式
  2. seajs.use('./a');
  3. //回调模式
  4. seajs.use('./a', function(a) {
  5. a.run();
  6. });
  7. //多模块模式
  8. seajs.use(['./a', './b'], function(a, b) {
  9. a.run();
  10. b.run();
  11. });
//单一模式
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。

来个小实例来说明一下:

  1. <!DOCTYPE HTML>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>TinyApp</title>
  6. </head>
  7. <body>
  8. <p class="content"></p>
  9. <script src="./sea.js" data-main="./init"></script>
  10. </body>
  11. </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>

第二种:require

require是SeaJS主要的模块加载方法,当在一个模块中需要用到其它模块时一般用require加载:ar a = require('a'); //引入a模块

第三种:require.async

之前的require方式是一次把所有依赖的JS文件都加载进来,如果想什么时候用到什么时候加载的话就会用这种方式,这种方式效率比require高一些。

通过上面的介绍,应该对SeaJS的模块载入和引用有所了解了,其实者通过这几篇的介绍会发现SeaJS的模块化编程思想和它带给开发人员的简单易用的特点。下篇博客介绍一下SeaJS的全局配置。

SeaJS简介四:全局配置

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

  1. seajs.config({
  2. base: 'path/to/jslib/',
  3. alias: {
  4. 'app': 'path/to/app/'
  5. },
  6. charset: 'utf-8',
  7. timeout: 20000,
  8. debug: false
  9. });
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简介就介绍完了,我们会发现这个脚本语言模块化的特点非常突出,并且语言本身比较简单并且上手容易。

SeaJS简介一:由来,特点以及优势的更多相关文章

  1. Redis简介,应用场景,优势

    Redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化 ...

  2. 转: 模块化开发框架seajs简介

    JavaScript模块化开发库之SeaJSSeaJS由国内的牛人lifesinger开发.目前版本是1.1.1,源码不到1500行,压缩后才4k,质量极高.这篇会讲述SeaJS的一些基本用法,不会面 ...

  3. seaJS简介和完整实例

    什么是 seaJS ? 和requireJS相似的,seaJS 也是用JavaScript编写的JS框架,主要功能是可以按不同的先后依赖关系对 JavaScript 等文件的进行加载工作,可简单理解为 ...

  4. Seajs是什么及sea.js 由来,特点以及优势

    Seajs是什么及sea.js 由来,特点以及优势 这篇文章主要介绍了Seajs的相关知识和和学习心得,适合刚接触SeaJS的同学,需要的朋友可以参考下,有更好的新手教程或文档,欢迎推荐.分享   1 ...

  5. Seajs是什么及其优缺点&如何使用?

    这篇文章主要介绍了Seajs的相关知识和和学习心得,适合刚接触SeaJS的同学,需要的朋友可以参考下,有更好的新手教程或文档,欢迎推荐.分享! 1.Seajs简介   Seajs,一个Web模块加载框 ...

  6. React系列(一):React入门

    React简介 1.由来 React是有Facebook开发出来用于构建前端界面的JS组件库,由于其背后的强大背景,使得这款库在技术开发上完全没有问题. 2.React的优势 解决大规模项目开发中数据 ...

  7. js模块化规范—概念和模块化进化史以及模块化的问题

    模块的概念 一个复杂的项目开发中,会写很多js文件,一个js文件执行某些特定的功能,那么每个js都可以称为一个模块,这就是模块的概念 每个js模块内部数据/实现是私有的, 只是向外部暴露一些接口(方法 ...

  8. Redis学习手册(目录)

    为什么自己当初要选择Redis作为数据存储解决方案中的一员呢?现在能想到的原因主要有三.其一,Redis不仅性能高效,而且完全免费.其二,是基于C/C++开发的服务器,这里应该有一定的感情因素吧.最后 ...

  9. Redis学习手册——转载

    转载出处:http://www.cnblogs.com/stephen-liu74/archive/2012/04/16/2370212.html 为什么自己当初要选择Redis作为数据存储解决方案中 ...

随机推荐

  1. iOS开发小技巧--取消按钮的选中状态

    首先要自定义按钮,并且实现如下方法,对,就是这么实现!!

  2. 5G的7位电话号码,去重,内存20mb,代码实现。

    转自:http://www.aboutyun.com/thread-11139-1-1.html 答案:首先,这个题考的不是分布式7位数,至少要用int来保存,那么int为4字节,20MB内存 10^ ...

  3. thinkphp 查询指定分类下的文章

    $list = $Dao->query("SELECT xp_wztj.bt,xp_wztj.time,xp_wztj.gjz,xp_wztj.wz,xp_wzfl.name FROM ...

  4. 关于Cocos2d-x随机数的生成

    1.使用前必须下一个随机种子,可以让每一次生成的随机数是不一样的,这里的每一次指的是时间上的每一次,如果是同一时间的随机数就不能这样写了 srand((unsigned)time(NULL));--- ...

  5. e660. 用一组像素创建图像

    This example demonstrates how to convert a byte array of pixel values that are indices to a color ta ...

  6. (转)typedef 函数指针的用法

    typedef 函数指针的用法   在网上搜索函数指针,看到一个例子.开始没看懂,想放弃,可是转念一想,这个用法迟早要弄懂的,现在多花点时间看懂它,好过以后碰到了要再花一倍时间来弄懂它.其实很多时候都 ...

  7. 直接拿来用!最火的Android开源项目(转)

    摘要:对于开发者而言,了解当下比较流行的开源项目很是必要.利用这些项目,有时能够让你达到事半功倍的效果.为此,CSDN特整理了GitHub上最受欢迎的Android及iOS开源项目,本文详细介绍了20 ...

  8. 文件名中含有连续字符abc,相应文件中也含有字符串abc

    find ./ -name '*abc*' -exec grep 'abc' {} -H \; find ./ -name '*abc*' | xargs -I '{}' grep abc {} -H ...

  9. 设置div滚动条

    这个是很常见的一个任务了,基本是通过CSS去实现滚动条. 滚动条 设置是否显示滚动条主要是在CSS中设置下列的属性: 代码如下: overflow:visible|auto|hidden|scroll ...

  10. android:json解析的两个工具:Gson和Jackson的使用小样例

    1.简单介绍 json是android与server通信过程中经常使用的数据格式,比如.例如以下是一个json格式的字符串: {"address":"Nanjing&qu ...