JavaScript模块化开发之SeaJS


Posted in Javascript onDecember 13, 2015

前言

  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模块化开发有所帮助,谢谢大家一直以来对三水点靠木网站的支持。!

Javascript 相关文章推荐
可缩放Reloaded-一个针对可缩放元素的复用组件
Mar 10 Javascript
JS中==与===操作符的比较
Mar 21 Javascript
JavaScript计算字符串中每个字符出现次数的小例子
Jul 02 Javascript
jQuery实现简单的图片查看器
Sep 11 Javascript
JavaScript来实现打开链接页面的简单实例
Jun 02 Javascript
bootstrap daterangepicker双日历时间段选择控件详解
Jun 15 Javascript
node.js 利用流实现读写同步,边读边写的方法
Sep 11 Javascript
vue-cli下的vuex的简单Demo图解(实现加1减1操作)
Feb 26 Javascript
Javascript的console['']常用输入方法汇总
Apr 26 Javascript
javaScript强制保留两位小数的输入数校验和小数保留问题
May 09 Javascript
JavaScript模板引擎应用场景及实现原理详解
Dec 14 Javascript
vue 里面的 $forceUpdate() 强制实例重新渲染操作
Sep 21 Javascript
node.js require() 源码解读
Dec 13 #Javascript
JavaScript 模块的循环加载实现方法
Dec 13 #Javascript
javascript日期验证之输入日期大于等于当前日期
Dec 13 #Javascript
详解JavaScript正则表达式之RegExp对象
Dec 13 #Javascript
详解JavaScript基于面向对象之继承
Dec 13 #Javascript
轻松使用jQuery双向select控件Bootstrap Dual Listbox
Dec 13 #Javascript
基于jQuery通过jQuery.form.js插件实现异步上传
Dec 13 #Javascript
You might like
mac下使用brew配置环境的步骤分享
2011/05/23 PHP
php的zip解压缩类pclzip使用示例
2014/03/14 PHP
php生成Android客户端扫描可登录的二维码
2016/05/13 PHP
Ubuntu 16.04下安装PHP 7过程详解
2017/03/28 PHP
offsetHeight在OnLoad中获取为0的现象
2013/07/22 Javascript
JS操作Cookie写入和读取实例代码
2013/10/20 Javascript
javascript中怎么做对象的类型判断
2013/11/11 Javascript
JavaScript实现查找字符串中第一个不重复的字符
2014/12/29 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
2016/07/11 Javascript
javascript数组去重方法分析
2016/12/15 Javascript
jQuery插件HighCharts实现2D柱状图、折线图的组合多轴图效果示例【附demo源码下载】
2017/03/09 Javascript
jquery.guide.js新版上线操作向导镂空提示jQuery插件(推荐)
2017/05/20 jQuery
jfinal与bootstrap的登出实战详解
2017/11/27 Javascript
详解基于vue的服务端渲染框架NUXT
2018/06/20 Javascript
微信小程序实现预览图片功能
2020/10/22 Javascript
微信小程序实现单选选项卡切换效果
2020/06/19 Javascript
vue自定义js图片碎片轮播图切换效果的实现代码
2019/04/28 Javascript
微信小程序实现录音功能
2019/11/22 Javascript
基于html+css+js实现简易计算器代码实例
2020/02/28 Javascript
浅谈Vuex的this.$store.commit和在Vue项目中引用公共方法
2020/07/24 Javascript
浅谈鸿蒙 JavaScript GUI 技术栈
2020/09/17 Javascript
python刷投票的脚本实现代码
2014/11/08 Python
Python 变量的创建过程详解
2019/09/02 Python
Python pip 安装与使用(安装、更新、删除)
2019/10/06 Python
基于python实现获取网页图片过程解析
2020/05/11 Python
Python HTMLTestRunner测试报告view按钮失效解决方案
2020/05/25 Python
HTML5拖放API实现自动生成相框功能
2020/04/07 HTML / CSS
德国大型的家具商店:Pharao24.de
2016/10/02 全球购物
学生个人求职自荐信格式
2013/09/23 职场文书
管理心得体会
2013/12/28 职场文书
酒店前厅员工辞职信
2014/01/08 职场文书
中学教师请假制度
2014/02/03 职场文书
个人四风对照检查材料
2014/09/26 职场文书
教师节主持词开场白
2015/05/29 职场文书
新闻通讯稿范文
2015/07/22 职场文书
分享mysql的current_timestamp小坑及解决
2021/11/27 MySQL