seajs是what?

先看段代码:
 var loder = {};
var define = loder.define = function(id,deps,factory){
loader[id] = factory;
};
上述代码干了什么?这就是一个最简单的加载器,但离实际应用还有很大差距,需要添加很多功能,seajs就是一个成熟的方案。
 
当一个页面集合了越来越多的js,这些js由不同的小组维护而且js包含了众多的组件,于是相同的函数可能命名冲突,为了解决命名冲突,大家可能会加上命名空间,记忆命名空间是一个负担,另外各种组件之间的引用,造成了复杂的依赖的关系,如何管理好依赖文件的加载问题也是个烦恼的问题。
 
seajs很好地解决了命名空间,依赖等问题。简单的说seajs是模块加载器,它将命名空间、组件解释为模块。按照seajs规则编写的代码符合CMD规范,使用它有两个好处:二是让模块定义变得简单,二是让模块发布变得简单。它是如何做到的这两方面的?
  1. 首先模块定义的方式,模块源代码中是这样编写模块的define(factory),非常简单,但是如果直接合并合并后多个define就会造成不知道如何引用具体的模块,于是涉及到第二个部分,如何让模块发布过程变得简单。
  2. 模块提取过程是,将源代码转换成seajs能正确解释的代码,即define(id,deps,factory)需要借助于grunt-cmd-transport或spm-build工具。
让这两个方面变得简单的秘诀在于seajs采用了路径即模块标识,于是在提取依赖过程中,根据模块标识找到依赖模块的文件将其合并,并且将模块定义转换为这种形式define(id,deps,factory)。上线后的代码中define(id,deps,factory)的id和deps模块标识用的是路径,根据路径即模块标识,就可以找到相应的完整模块标识。
 

模块标识

seajs的模块定义方式非常simple,主要的难点在于不同项目有不同的部署要求,因此会因为模块标识理解不够造成进入各种坑。下面详细分析下模块标识!
模块标识命名规则
  1. 一个模块标识由斜线(/)分隔的多项组成。
  2. 每一项必须是小驼峰字符串、 . 或 .. 。
  3. 模块标识可以不包含文件后缀名,比如 .js 。
  4. 模块标识可以是 相对 或 顶级 标识。如果第一项是 . 或 ..,则该模块标识是相对标识
解释一下其中的几种概念
  1. 相对路径,以. 或 ..开头
  2. 顶级路径,不以.或 ..及斜线(/)开头
  3. 普通路径,除相对和顶级路径外的,比如/(根路径)开头的,"http://""https://""file:///" 等协议标识开头的
  4. 模块命名空间是seajs所在文件的根路径即所谓的base路径,去除了seajs/x.y.z 字串,也可以指定seajs.config({base:});
模块依赖提取过程如何解析?
  1. 只提取相对标识
  2. 相对标识相对 require 所在模块的标识来解析
上线后模块标识解析规则?
  1. 顶级标识始终相对 base 基础路径解析。(顶级标识由字符串开头)
  2. 绝对路径和根路径,即普通路径,始终相对当前页面解析,跟我们平时用的其他js和css路径一样,比如当前页面是www.simple.com/user/index.html  ,路径为/js/hello.js,它解析后的地址为www.simple.com/js/hello.js。
  3. 模块定义中require 和 require.async 的相对路径相对当前模块路径来解析。

如果我们能理解其模块标识解析设计的出发点,那么就可以轻易的理解这些而不用记忆这么多:

  1. 关注度分离。书写模块的时候我们是不用指定模块id的,require的模块时候只要填入依赖模块的相对路径,于是我们只要关注代码的书写而不是依赖,打包后工具会自动帮我们处理好模块id。
  2. 尽量与浏览器的解析规则一致。上线后在浏览器中的代码,模块路径的解析规则应该于平时用的css、js这些加载路径规则一样,普通路径和相对路径的都是相对当前页面的。

 示例

目录结构如下:

www 
--app
--blog
index.html
--sea-modules
--seajs
--2.2.0
sea.js
--blog
--user
--1.0.0
main.js
--static
--user
--src
a.js
b.js
main.js
--dist
main.js
package.json
Makefile
//   /www/static/user/src/a.js
define(function(require,exports,module){
module.exports = function(){
// ..........................
};
});
//   /www/static/user/src/b.js
define(function(require,exports,module){
module.exports = function(){
// ..........................
};
});
//   /www/static/user/src/main.js
define(function(require,exports,module){
     var a = require('./a");
var b = require('./b");
// ..............
 }); 
//  /www/static/user/package.json
{
family:"blog",
name:"user",
version:"1.0.0",
spm:{
output:["main.js"]
}
}

// /www/static/user/Makefile
build:
@spm build deploy:
@rm -rf ../../sea-modules/blog/user
@mkdir ../../sea-modules/blog/user
@mkdir ../../sea-modules/blog/user/1.0.
@cp dist/*.* ../../sea-modules/blog/user/1.0.0
@echo
@echo " deploy to seajs-modules/blog/user/1.0.0"
@echo
使用spm-build构建项目:
cd /www/static/user ; spm-build --encoding gbk
会在/www/static/user/dist 下生成 main.js 和 main-debug.js,main.js大概是这样的
// /www/static/user/dist/main.js
define("blog/user/1.0.0/main",["./a","./b"],function(require){
var a = require('./a");
var b = require('./b");
});
define("blog/user/1.0.0/a",[],function(require,exports,module){
// .......................
});
define("blog/user/1.0.0/b",[],function(require,exports,module){
// .......................
});

然后运行make deploy

会将 ../dist/main 部署到 /www/sea-modules/blog/user/1.0.0/main.js

在页面中如何加载模块呢?

<!--    www.expample.com/app/blog/index.html     -->
<script src="/sea-modules/seajs/2.4.0/sea.js" id="seajson"></script>
<script>
seajs.config({charset:"gbk"});
seajs.use("blog/user/1.0.0/main");
</script>

 参考阅读:

seajs的那些坑的更多相关文章

  1. seajs之seajs-debug坑

    最近遇到两个关于seajs-debug的坑 一个与preload有关,详情见https://github.com/seajs/seajs-debug/issues/15 一个与map时间戳有关,详情见 ...

  2. 用spm2构建seajs项目的过程

    前言 Javascript模块化规范有CommonJs规范,和主要适用于浏览器环境的AMD规范,以及国内的CMD规范,它是SeaJs遵循的模块化规范.因为以前项目中用SeaJs做过前端的模块管理工具, ...

  3. seajs的那点事(很坑的事),和本白的一点事(更坑的事)

    在开始之前,偶先吐槽加逗比一下,2天前,CCAV的本白和百度的菊花成功潜入到了携程大楼 然后在没有找到他们运维的情况下,四处乱逛,企图把他们的服务器给root一下,然后再瞎逛之后到了一个很神奇的地方 ...

  4. seajs集成jquery的一个坑

    var $ = require("jquery"); 今天在用seajs集成js的时候,老是发现$获取不到,但是文件又加载进去了,后来找了半天发现是这个问题. 本质的原因在于sea ...

  5. JS模块化开发:使用SeaJs高效构建页面

    一.扯淡部分 很久很久以前,也就是刚开始接触前端的那会儿,脑袋里压根没有什么架构.重构.性能这些概念,天真地以为前端===好看的页面,甚至把js都划分到除了用来写一些美美的特效别无它用的阴暗角落里,就 ...

  6. seajs学习一天后的总结归纳

    公司项目最近需要将js文件迁移到seajs来进行模块化管理,由于我以前主要接触模块化开发是接触的AMD规范的requireJS,没有接触过CMD规范,而且在实际项目中还没有用过类似技术.于是,我非常兴 ...

  7. 新手 gulp+ seajs 小demo

    首先,不说废话,它的介绍和作者就不在多说了,网上一百度一大堆: 我在这里只是来写写我这2天抽空对seajs的了解并爬过的坑,和实现的一个小demo(纯属为了实现,高手请绕道); 一.环境工具及安装 1 ...

  8. SeaJS与RequireJS最大的区别

    SeaJS与RequireJS最大的区别 U_U 2013-06-20 16:21:12 执行模块的机制大不一样-----------------------------------由于 Requir ...

  9. 前端模块化开发之seaJs

    了解后端语言的童鞋一定听过模块化开发的概念,比如java.python等后端语言都有自己的模块化特性,然而和后端语言相比,javascript还尚未实现模块化的功能,虽然之后的更高版本可能引入模块化开 ...

随机推荐

  1. 介绍Office 365 中文用户社区 4.0

    本文于2017年3月18日首发于LinkedIn,原文链接在这里 为了给广大用户提供一个可以自由交流.切磋技术的平台,微软和其他一些国际知名的大型软件公司一样,都有创建用户社区(Community,或 ...

  2. Unity文档总结(2)-Understanding Automatic Memory Management

    当一个对象.字符串.数组被创建的时候,从中间池申请分配需要存储的内存称为堆.当该部分不在使用时,一度占用的内存被释放收回,用于别的事物.在过去,它通常由开发人员分配和释放这些堆内存块,明确相应的功能调 ...

  3. 浅谈!SQL语句中LEFT JOIN ON WHERE和LEFT JOIN ON AND的区别

    今天的工作学习之路是一个数据库的小知识,当时没有区分出所以然,特此记录分享一下子. 众所周知,数据库的表都是单独存在的,但是当我们进行联合查询(多表查询)时,我们获得数据库返回的值时就好像在一张表里一 ...

  4. 2015.07.20MapReducer源码解析(笔记)

    MapReducer源码解析(笔记)   第一步,读取数据源,将每一行内容解析成一个个键值对,每个键值对供map函数定义一次,数据源由FileInputFormat:指定的,程序就能从地址读取记录,读 ...

  5. python应用部署--flask

    首先必须吐槽一下,python应用部署简直就是有毒...太麻烦了.关键还不能成功部署. 网上很多教程都是说要用nginx和uwsgi.来来回回试了无数次都不行.于是乎,在某一个瞬间,灵感以来,发现了一 ...

  6. MYSQL数据库-修改和删除

    删除数据库: $ DROP DATABASE t_name; 重命名一张表: $ RENAME TABLE ori_name TO new_name; $ ALTER TABLE ori_name R ...

  7. Linux网络设备驱动(一) _驱动模型

    Linux素来以其强大的网络功能著名,同时, 网络设备也作为三大设备之一, 成为Linux驱动学习中必不可少的设备类型, 此外, 由于历史原因, Linux并没有强制对网络设备贯彻其"一切皆 ...

  8. 使用idea2017搭建SSM框架

    搭建个SSM框架居然花费了我好长时间!特此记录! 需要准备的环境: idea 2017.1 jdk1.8 Maven 3.3.9  请提前将idea与Maven.jdk配置好,本次项目用的都是比较新的 ...

  9. JS——操作内容、操作相关元素

    操作内容:普通元素.innerHTML = "值": 会把标记执行渲染普通元素.innerText = "值": 将值原封不动的展示出来,即使里面有标记 var ...

  10. 关于压缩jar包时提示*.*没有这个文件或目录的问题以及解决办法:

    关于压缩jar包时提示.没有这个文件或目录的问题以及解决办法: 问题描述: 我在打包jar时,CMD中进入到包的上一层目录. 在命令提示符中输入 提示如下: 从提示中可知没有找到我们想要打包的clas ...