seajs的价值

原生javascript的一个弱项,就是不支持模块化,说白了就是没有其他语言的import,include等语句。所以开发者就只有2个选择:把所有的东西写到一起,或者通过全局变量来交互 这至少造成以下几个问题: 1、污染全局变量,容易发生命名空间冲突,难以维护 2、无法按需加载 由于javascript官方迟迟未能解决这些问题,所以就有民间的社区提出标准,希望能自行解决,弥补语言的不足。主要有2种规范,一种是 CommonJS提出的CMD规范,另一种是AMD规范,server端的node就是CMD的一种实现,seajs实现的也是CMD规范。所以熟悉 node的用户会发现,seajs的API和node的API非常类似,这就是因为它们是同一种规范的不同实现 关于seajs的价值;

SeaJS 是一个适用于 Web 浏览器端的模块加载器。使用 SeaJS,可以更好地组织 JavaScript 代码。

SeaJS 具有核心特性:

  • 简单一致的模块格式。
  • 依赖的自动管理。
  • 脚本的异步并行加载。
  • 丰富的插件。
  • 友好的调试。

兼容性

SeaJS 兼容所有 PC 和 Mobile 端的主流浏览器:

IE 5.5+           ✔
Chrome 3+         ✔
Firefox 2+        ✔
Safari 3.2+       ✔
Opera 10+         ✔

下载与安装

要在项目中使用SeaJS,你所有需要做的准备工作就是下载sea.js然后放到你项目的某个位置。 
SeaJS项目目前托管在GitHub上,主页为 https://github.com/seajs/seajs/ 。可以到其git库的build目录下下载sea.js(已压缩)或sea-debug.js(未压缩)。 
下载完成后放到项目的相应位置,然后在页面中通过<script>标签引入,你就可以使用SeaJS了。

SeaJS基本开发原则

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

Sea.js的配置

<script src="sea.js"></script>
<script>seajs.use("main");
</script>

用script标签引入 sea.js,然后用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,例如上面的代码也可以改为如下写法:

<script src="sea.js" data-main="main.js"></script>
  • 1

不过我一直没有成功过,具体原因不明。

seajs.config seajs.config(options)

用来进行配置的方法。

seajs.config({

// 别名配置 
alias: { 
‘es5-safe’: ‘gallery/es5-safe/0.9.3/es5-safe’, 
‘json’: ‘gallery/json/1.0.2/json’, 
‘jquery’: ‘jquery/jquery/1.10.1/jquery’ 
},

// 路径配置 
paths: { 
‘gallery’: ‘https://a.alipayobjects.com/gallery’ 
},

// 变量配置 
vars: { 
‘locale’: ‘zh-cn’ 
},

// 映射配置 
map: [ 
[‘http://example.com/js/app/‘, ‘http://localhost/js/app/‘] 
],

// 预加载项 
preload: [ 
Function.prototype.bind ? ” : ‘es5-safe’, 
this.JSON ? ” : ‘json’ 
],

// 调试模式 
debug: true,

// Sea.js 的基础路径 
base: ‘http://example.com/path/to/base/‘,

// 文件编码 
charset: ‘utf-8’ 
});

支持以下配置选项: 
alias Object

当模块标识很长时,可以使用 alias 来简化。

seajs.config({ 
alias: { 
‘jquery’: ‘jquery/jquery/1.10.1/jquery’, 
‘app/biz’: ‘http://path/to/app/biz.js‘, 

});

define(function(require, exports, module) {

var $ = require(‘jquery’); 
//=> 加载的是 http://path/to/base/jquery/jquery/1.10.1/jquery.js

var biz = require(‘app/biz’); 
//=> 加载的是 http://path/to/app/biz.js

});

使用 alias,可以让文件的真实路径与调用标识分开,有利于统一维护。 
paths Object

当目录比较深,或需要跨目录调用模块时,可以使用 paths 来简化书写。

seajs.config({ 
paths: { 
‘gallery’: ‘https://a.alipayobjects.com/gallery‘, 
‘app’: ‘path/to/app’, 

});

define(function(require, exports, module) {

var underscore = require(‘gallery/underscore’); 
//=> 加载的是 https://a.alipayobjects.com/gallery/underscore.js

var biz = require(‘app/biz’); 
//=> 加载的是 path/to/app/biz.js

});

paths 配置可以结合 alias 配置一起使用,让模块引用非常方便。 
vars Object

有些场景下,模块路径在运行时才能确定,这时可以使用 vars 变量来配置。

seajs.config({ 
vars: { 
‘locale’: ‘zh-cn’ 

});

define(function(require, exports, module) {

var lang = require(‘./i18n/{locale}.js’); 
//=> 加载的是 path/to/i18n/zh-cn.js

});

vars 配置的是模块标识中的变量值,在模块标识中用 {key} 来表示变量。 
map Array

该配置可对模块路径进行映射修改,可用于路径转换、在线调试等。

seajs.config({ 
map: [ 
[ ‘.js’, ‘-debug.js’ ] 

});

define(function(require, exports, module) {

var a = require(‘./a’); 
//=> 加载的是 path/to/a-debug.js

});

更多用法可参考:调试实践 
preload Array

使用 preload 配置项,可以在普通模块加载前,提前加载并初始化好指定模块。

// 在老浏览器中,提前加载好 ES5 和 json 模块 
seajs.config({ 
preload: [ 
Function.prototype.bind ? ” : ‘es5-safe’, 
this.JSON ? ” : ‘json’ 

});

preload 中的空字符串会被忽略掉。

注意:preload 中的配置,需要等到 use 时才加载。比如:

seajs.config({ 
preload: ‘a’ 
});

// 在加载 b 之前,会确保模块 a 已经加载并执行好 
seajs.use(‘./b’);

preload 配置不能放在模块文件里面:

seajs.config({ 
preload: ‘a’ 
});

define(function(require, exports) { 
// 此处执行时,不能保证模块 a 已经加载并执行好 
});

debug Boolean

值为 true 时,加载器不会删除动态插入的 script 标签。插件也可以根据 debug 配置,来决策 log 等信息的输出。 
base String

Sea.js 在解析顶级标识时,会相对 base 路径来解析。详情请参阅 模块标识

注意:一般请不要配置 base 路径,把 sea.js 放在合适的路径往往更简单一致。 
charset String | Function

获取模块文件时,

模块的定义及编写

模块定义函数define

SeaJS中使用“define”函数定义一个模块。define可以接收三个参数: 
复制代码 代码如下:

上面是我从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数据的模块非常合适。

简单的实例

helloworld.html源码如下:

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hello Sea.js</title>
</head>
<body>
<script src="sea.js"></script>
<script>seajs.use("main");
</script>
</body>
</html>

main.js源代码如下:

define("main", //可以不要[], //可以不要function test() {       alert("Hello world!");}
);

Seajs相关知识

seajs.Use 引入入口文件

第一个参数表示模块id

字符串表示一个模块id

数组,数组每个成员表示一个模块

第二个参数表示回调函数(可有可无的)

作用就是当模块加载完成执行回调函数

作用域是全局作用域

参数与前面加载的模块是一致的

Use方法返回值是seajs对象,因此可以链式调用

Seajs默认根目录是seajs文件所在的目录,因此我们通常要将seajs文件放在最外面

文件只需要引入seajs文件,其他的是要通过seajs引入的

通常来说入口文件只有一个,所以链式调用时候,很少见,在一个use方法回调函数内部不能知道其他use方法什么时候加载完毕

Define 定义模块的,根据传递的参数我们分成三类

第一类 传递一个参数

如果是一个值类型的数据,那么这个数据直接作为接口暴漏出来

如果是一个对象,那么这个对象就是暴漏的接口

如果是一个函数(最常见的一种方式,它符合commonjs规范),

作用域是全局作用域

参数有三个

Require 加载模块的

Exports 定义接口的

Module 模块的对象

第二类 传递两个参数

第一个参数

如果是字符串 表示模块的id

如果是数组 表示模块的依赖集合

此时不论模块有没有使用该模块都会去加载它,并且不会去解析模块内部require方法

第二个参数表示模块函数(对象等其他数据)这个函数的使用方式跟上面函数式一致的

第三类 传递三个参数

第一个参数 是字符串,表示模块id

第二个参数 是数组,表示依赖集合

第三个参数 函数(其他数据),模块函数,函数的使用方式跟上面的函数式一致

通常来说一个文件只能添加一个模块(模块没有定义id),如果定义了多个模块,后面的覆盖前面的

如果模块定义了id,此时这些模块是兼容的,引用这些模块的时候,一定要通过这些id引用

Require加载模块

1 不能简写,在模块函数的参数中

2 不能修改

不能赋值

不能定义变量

不能作为函数参数

在子函数中不能修改

3 使用时不能使用表达式

当我们定义模块id时候,此时我们不能直接引入该模块

想使用模块要分成两步

第一步 在依赖模块集合中引入该模块

第二步 在模块内部用require引入模块id

接口exports 包含commonjs规范定义接口的语法

1 exports.接口

可以继续添加接口

2 module.exports.接口

可以继续添加接口,并且1和2是可以混用的

3 module.exports = {}

定义全部的接口,不能在使用前面两种定义接口方式

4 return {}

定义全部的接口,此时会将前面所有接口覆盖掉

5 return function () {}

定义接口函数,使用时候,必须调用它

6 module.exports = function () {}

定义接口函数

7 define(值类型)

定义一个值类型的数据接口

8 module.exports = 值类型

定义一个值类型的数据接口

9 return 值类型

定义一个值类型的数据接口

10 define({})

定义一个对象接口

注意

定义接口的优先级

Return  > module.exports = {}或者function > module.exports.接口 或者exports.接口

Exports绝对不能赋值对象 exports = {}

定义接口函数时候,有两种方式

第一种

Return function 或者module.exports = function

第二种

Var demo = function () {}或者function demo (){}

Return demo 或者module.exports = demo

模块module

Id 表示模块的id,如果定义模块没有添加id的时候,模块的id就是uri

Uri表示模块所在文件的地址

Exports表示模块暴漏的接口

Status 模块的状态

Dependencies 依赖的模块,是一个数组 每个成员表示一个模块的id

Deps 依赖的模块,是个对象,对象属性表示模块的id,对象属性值表示模块的信息对象

异步加载模块 require.async

与use方法很像,只不过一个在模块外部使用,一个在模块内部使用

与require的区别,require遵守commonjs规范是同步加载的,require.async是异步加载的

Require引入就可以使用

Require.async 在引入后,的回调函数中才能使用,函数返回值就是require对象

在if语句中

如果条件成立

Require会加载并执行该模块

Require.async 会一步加载模块,并执行

如果条件不成立

Require会加载模块,但不会执行

Require.async 不会加载模块,也不会执行

在异步操作中

例如在定时器中

Require会立即加载文件,但是等到定时器执行的时候才会执行模块函数

Require.async 会等到异步操作执行的时候,加载并执行模块

配置config

配置是seajs为我们提供的功能,但是我们想使用就要配置这些信息

Alias 创建模块的别名

作用简化对模块的引用

值是一个对象

对象的属性名称表示别名

对象的属性值表示真实路径

Path 定义路径

作用 简化对模块路径书写

值是一个对象

Key表示简化的路径

Value表示真实的路径

Map 定义模块映射关系的

批处理模块的

值是一个二维数组

数组的每个成员表示一组映射规则,每个映射规则是一个数组

第一个成员表示匹配的规则

第二个成员表示处理的规则

Debug 进入调试模块,可以看到js加载过程

Vars 定义路径模板变量

作用可以是引入的模块动态会

模板语法 {}, 在路径的{}中我们可以使用vars中定义的变量

值是一个对象

Key 表示变量

Value表示变量的值

Charset 定义js文件加载时候的编码格式,

Base 定义模块的根路径,它的值是个字符串,此时根路径就是个字符串指向的目录,此时seajs文件可以随意的防止了

Seajs插件

我们需要的功能,seajs没有帮我们实现,别人帮我们了,我们使用别人提供的代码,这些代码就是插件,我们使用这些插件就要去加载这些插件文件

在seajs中使用插件,一定要写在seajs标签后面(插件依赖于seajs),对于一些插件是需要写配置的,例如预加载插件

预加载插件

在模块加载过程中有限加载某些文件(通常这些文件都是一些代码工具库,或者框架)

这些文件的特征是,都会提供一个全局变量方便我们使用它

这个插件的作用

1 我们不用在每一个模块内显性的引入它,而可以直接使用他们(因为他们提供了全局变量)

2 我们不需要修改这些文件的源代码,因为他们提供全局变量

3 在更新代码库的时候成本低,我们只需要更改配置就可以了,因为每个版本提供的全局变量的,

预加载插件加载时间(让我们知道,我们什么时候可以使用这些预加载的库)

在调用use方法之后,模块加载之前开始加载这些库的

所以配置项要写在use方法之前(所有的配置都要写在use方法之前,或者整个项目的最前面)

在配置中,我们通过preload属性加载库

Preload是一个数组,每一个成员代编一个文件

1

Css插件

到目前为止,我们学的加载文件都是加载的js文件,有时我们在工作中开发项目时候,我们写的不仅仅是js,还有css,此时如果对于一个搜索框,我们通常将他们的js与css写在一起,此时如果js是一个模块化开发文件,我们通常需要将css引入进来,这样就会是css与js产生依赖。使他们形成一个整体

使用css插件就要加载seajs-css文件

使用方式:

第一步在seajs标签后面引入该文件标签

第二步,哪个js模块需要什么css文件就通过require引入它

注意引入的css文件一定要加上.css后缀名

Use方法不仅仅可以引入js文件,还可以引入css文件,所以对于一些在渲染之前就要加载的css文件我们可以写在这里。

SeaJS 是什么?相关推荐

  1. SeaJS基本开发原则

    SeaJS基本开发原则 在讨论SeaJS的具体使用前,先介绍一下SeaJS的模块化理念和开发原则. 使用SeaJS开发JavaScript的基本原则就是:一切皆为模块.引入SeaJS后,编写JavaS ...

  2. 使用SeaJS实现模块化JavaScript开发

    2019独角兽企业重金招聘Python工程师标准>>> 前言 SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加 ...

  3. 【SeaJS】【3】seajs.data相关的源码阅读

    在SeaJS官网上推荐了源码阅读顺序,本文并没有采用这个顺序,而是按个人习惯以调试官方示例的方式进行源码阅读.早期版本作者玉伯使用了几个闭包形式,本文源码版本为2.1.1,它的编码方式个人认为更加脚本 ...

  4. seajs学习心得和新产品福利

    今天看了seajs官网的入门教程,以及博客园的教程http://www.cnblogs.com/leoo2sk/archive/2011/06/27/write-javascript-with-sea ...

  5. seaJs api 帮助文档

    前言 SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制.与jQuery等JavaScript框架不同,SeaJS不会扩展封 ...

  6. 深入探寻seajs的模块化与加载方式

    由于一直在使用,所以了解了下seajs的源代码.这里是我对下面几个问题的理解: 1.seajs的require(XXX)的方法是怎样实现模块加载的? 2.为什么需要预加载? 3.为什么需要构建工具? ...

  7. 模块化以及requirejs和seajs

    我们用模块化的思想进行网页的编写是为了更好的管理我们的项目 模块与模块之间是独立存在的,每个模块可以独立的完成一个子功能. 模块化所涉及的规范commonjs,AMD,CMD,UMD 其中的commo ...

  8. 简单的 基于seajs一个base基础库

    define(function(require,exports,module){ var base = {};var isIE_v=(function(){if (!!(window.attachEv ...

  9. 快速上手seajs——简单易用Seajs

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接前端小尚,谢谢! 背景 一个网站必然会涉及很多功能,tab选项卡.slide轮播图.pop弹出层.美化alert.paging分页等等等等,如果 ...

  10. Angular JS - 9 - SeaJS加载js模块

    seajs加载模块的三种方式 1.seajs.use() 加载入口模块,类似于Java的main函数 2.require:      当在一个模块中需要用到其它模块时一般用require加载 1)   ...

最新文章

  1. Go中的Socket编程
  2. 通过本地IIS SMTP服务器发送邮件时提示“邮箱不可用”的解决办法
  3. Ubuntu 18.04 安装 redis入门使用
  4. windows不能访问linux服务器,window的vnc客户端无法访问Linux服务端的问题之一
  5. 协方差代表的意义是什么?
  6. TensorFlow错误:TypeError: __init__() got an unexpected keyword argument 'serialized_options'
  7. SAP CRM WebClient UI cross component跳转中有一个硬编码的CROSSNAV
  8. 关于mysql的change和modify
  9. java erlang 游戏_游戏中最近可达点(用erlang写一个简单算法)
  10. group by很多字段是不是会很慢_3分钟短文 | MySQL在分组时,把多列合并为一个字段!
  11. 【网络安全工程师面试合集】— 渗透资源 操作系统大合集
  12. MTK 10A常用函数集锦
  13. 国外巨头鏖战的新领域——语音识别
  14. 百度移动搜索主要有如下几类结果构成
  15. Oozie 集成 Ssh
  16. CLion程序编译错误 0xC0000135
  17. 正版软件汇集,遥感集市
  18. Java零基础P20使用IDEA开发
  19. Ultra Fast Structure-aware Deep Lane Detection论文解读
  20. 基于cc2530超声波测距报警系统

热门文章

  1. 支持html邮件,HTML邮件兼容问题与解决方案
  2. 洛谷 P1135奇怪的电梯
  3. 徒手撸设计模式-抽象工厂模式
  4. 周易哲学(一):干支纪年法和四柱八字
  5. 12 月浏览器市场份额:量子火狐后劲不足
  6. 跨考西电计算机科学与技术专业介绍,2021年西安电子科技大学计算机科学与技术(081200)人工智能交叉研究方向_考研专业目录_考试科目_考试范围 - 学途吧...
  7. VNC Timed out waiting for a response from the computer
  8. flutter 键盘挡住输入框问题
  9. 《禅与计算机程序设计艺术》/ By 禅与计算机程序设计艺术GPT-4
  10. 相同和相等的区别。。。