SeaJS 是一个遵循 CommonJS 规范的 JavaScript 模块加载框架,可以实现 JavaScript 的模块化开发及加载机制, 本文给大家介绍 JavaScript 模块化开发之 SeaJS,需要的朋友参考下
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
前言
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 会赋值为 {aa0aa} ,没有特别的必要建议不要传入 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
- })
其中,
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 功能将作为一个插件存在。
使用方法
以上内容是小编给大家分享的 JavaScript 模块化开发之 SeaJS,希望对大家学习 javascript 模块化开发有所帮助,谢谢大家一直以来对 phperz 网站的支持。!
来源: