由来:

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

那么,在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. 測试Service

    <strong><span style="font-size:18px;">自己定义Service:</span></strong> ...

  2. 20 款免费的 JavaScript 游戏引擎

    使用 HTML5,CSS3 和 Javascript 可以帮助面向对象开发者开发拥有各种特性的游戏,比如:3D 动画效果,Canvas,数学,颜色,声音,WebGL 等等.最明显的优势在于使用 HTM ...

  3. 关于SQL语句的一些注意事项

    1.Into 表后要编辑-IntelliSense-刷新本地缓存 才能访问新表 2.Is null不是=null

  4. Ubuntu之Docker安装

    1.添加官方的GPG key到系统 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 2.添加D ...

  5. Batch Normalization原理及其TensorFlow实现——为了减少深度神经网络中的internal covariate shift,论文中提出了Batch Normalization算法,首先是对”每一层“的输入做一个Batch Normalization 变换

    批标准化(Bactch Normalization,BN)是为了克服神经网络加深导致难以训练而诞生的,随着神经网络深度加深,训练起来就会越来越困难,收敛速度回很慢,常常会导致梯度弥散问题(Vanish ...

  6. Ubuntu 12.04 root用户登录设置

    Ubuntu 12.04默认是不允许root登录的,在登录窗口只能看到普通用户和访客登录.以普通身份登陆Ubuntu后我们需要做一些修改,普通用户登录后,修改系统配置文件需要切换到超级用户模式,在终端 ...

  7. 科技发烧友之单反佳能700d中高端

    http://detail.zol.com.cn/series/15/15795_1.html 前三 佳能 尼康 索尼 佳能5d 1.6w 佳能70d 5k 佳能6d 9k 佳能d7100 5k 尼康 ...

  8. Linux shell 学习

    ·详细介绍Linux shell脚本基础学习(一) ·详细介绍Linux shell脚本基础学习(二) ·详细介绍Linux shell脚本基础学习(三) ·详细介绍Linux shell脚本基础学习 ...

  9. SharePoint 2010 讨论板列表内容的读取细节处理

    list.Folder表示subject,属于特殊列表,使用list.Folder遍历项,而不是使用list.Items;list.Items表示reply;list.Items[0]["P ...

  10. MFC中控件添加了变量后修改

    新增一个变量这个变量存在于两个位置,一个是头文件中项目名+Dlg.h文件,另一个是源文件中项目名+Dlg.cpp文件