基于Seajs的项目构建 
CDC miyukizhang
使用SEA.JS做模块化开发的项目 
的构建过程
不包括: 
• 为什么使用模块化开发 
• Sea.js和其他同类项目的优劣对比 
• 各种规范的优劣对比
提纲 
• Sea.js模块标识 
• Sea.js模块加载规则 
• 项目结构 
• 构建过程 
• 项目实践
提纲 
• Sea.js模块标识 
• Sea.js模块加载规则 
• 项目结构 
• 构建过程 
• 项目实践
Sea.js的模块标识 
• 模块标识:字符串,标识模块 
– seajs.use("my-module"); 
– require("my-module"); 
• 3种模块标识: 
– 顶级标识 
– 相对标识 
– 普通路径
顶级标识 
• 不以../ , ./ , / 开头的标识 
• 相对于Sea.js base路径来解析
Sea.js base 
如果sea.js 的URL是: 
http://example.com/sea_modules/sea.js 
则base 为: 
http://example.com/sea_modules/ 
如果sea.js 的URL是: 
http://example.com/sea_modules/Sea.js/1.0.0/sea.js 
则base 为: 
http://example.com/sea_modules/
Sea.js base 
注意:这里设置的../dist,是相对于当前html页面所在路径来说的,而 
不是相对于sea.js所在路径
顶级标识 
假设Sea.js base: http://example.com/sea_modules/ 
http://example.com/sea_modules/gallery/jquery/1.10.1/jquery.js
相对标识 
• 以./ 或者../ 打头的 
• 相对于当前模块的路径来解析
相对标识 
path/to/b.js,path/c.js
普通路径 
• 三种形式: 
– http,file等开头的绝对路径 
– 以/ 开头的根路径 
– 传递给seajs.use()函数的相对路径 
• 将会根据当前html页面的位置来解析
提纲 
• Sea.js模块标识 
• Sea.js模块加载规则 
• 项目结构 
• 构建过程 
• 项目实践
模块加载规则 
假设Sea.js base: http://example.com/sea_modules/ 
文件路径:http://example.com/sea_modules/app/hello/1.1.0/hello.js
模块加载规则 
• 定义模块 
• 模块分类: 
– 具名模块 
– 匿名模块
I am not ID 
具名模块 
• 具名模块:定义了ID的模块I am ID
具名模块 
• 具名模块:定义了ID的模块 
• ID ∈ 模块标识,模块标识≠ ID 
• 当一个文件里有多个define时,ID用来判断主模块
具名模块 
• ID 和路径匹配原则 
文件路径: http://example.com/sea_modules/app/hello/1.1.0/hello.js
具名模块 
• ID 和路径匹配原则
匿名模块 
• 匿名模块:没定义ID的模块 
– 无需匹配 
– 文件中只能有一个define 块
为什么需要具名函数 
当seajs.use 这个文件时,应该返回哪个模块?
为什么需要具名函数 
和文件路径匹配的ID 的模块就是这个文件的主模块
提纲 
• Sea.js模块标识 
• Sea.js模块加载规则 
• 项目结构 
• 构建过程 
• 项目实践
Grunt 
Q:Grunt为何物? 
A:一个专为JavaScript提供的构建工具。 
Q:啥是构建工具? 
A:解决源文件压缩、合并、拷贝和提取业务 
代码依赖模块等复杂工作的自动化工具
项目结构
准备Grunt插件
Html
js文件 
main.js 
hello.js 
world.js
js文件
js文件
js文件
基于Seajs的项目构建
提纲 
• Sea.js模块标识 
• Sea.js模块加载规则 
• 项目结构 
• 构建过程 
• 项目实践
构建过程 
• 为什么要构建 
– 生产环境需要文件合并和压缩 
– 代码合并需要遵循“ID 和路径匹配原则”
构建过程 
• 提取操作:用来提取模块的标识id 和依 
赖dependencies 
• 压缩操作:包括文件合并和文件压缩
transport Grunt-cmd-transport
transport
transport 
提取后hello.js:
transport 
提取后main.js:
concat Grunt-cmd-concat
concat
concat seajs_hello/sea_modules/app/hello/1.0.0/hello.js
concat seajs_hello/sea_modules/app/hello/1.0.0/main.js
uglify和clean 
grunt-contrib-uglify,grunt-contrib-clean
构建之后的目录结构
源码 
click me
提纲 
• Sea.js模块标识 
• Sea.js模块加载规则 
• 项目结构 
• 构建过程 
• 项目实践
项目实践tracker.oa.com
目录结构及说明 
tracker_proj 
trunk release tags branches 
trunk: 项目源码 
release:部署代码,构建后代码
目录结构及说明 
statistics -- 项目页 
overview.html -- 概览 
product.html -- 产品详情 
css -- 样式文件 
img -- 图片文件 
sea_modules 
application -- 特定项目特定页面的业务层js都在这里 
jquery -- base模块,spm提供的已经以CMD格式封装好的通用库都在这里 
seajs -- seajs 
node_modules -- grunt及其所需插件。注1 
grunt -- grunt 
grunt-cmd-concat -- 依赖合并 
grunt-cmd-transport -- 提取依赖并设置模块ID 
grunt-contrib-clean -- 删除临时文件 
grunt-contrib-uglify -- 压缩 
Gruntfile.js -- grunt配置文件 
package.json -- 项目配置文件,该文件内容可以在grunt中引用 
rootConfig.js -- 开发环境下使用的seajs配置文件
目录结构及说明 
overview.js 
user_charts.js 
charts.js
模块application/statistics/1.1.0/charts.js
模块application/statistics/1.1.0/user_charts.js
模块application/statistics/1.1.0/overview.js
模块rootConfig.js
模块statistics/overview.html
构建 
1. package.json 
2. Gruntfile.js 
1. transport任务 
2. concat任务 
3. uglify任务 
4. clean任务
感受 
• 文件职责明确 
• 代码清晰 
• 减少重复开发 
• 自动化部署节省开发时间
End 
Thanks

More Related Content

PDF
July.2011.w3ctech
PPTX
open stack glance
PPTX
React js
PPTX
2016年逢甲大學資訊系:ASP.NET MVC 4 教育訓練2
PPTX
Redux+react js
PPTX
2016年逢甲大學資訊系:ASP.NET MVC 4 教育訓練1(20160222)
PPTX
PPTX
Getting started with test automation
July.2011.w3ctech
open stack glance
React js
2016年逢甲大學資訊系:ASP.NET MVC 4 教育訓練2
Redux+react js
2016年逢甲大學資訊系:ASP.NET MVC 4 教育訓練1(20160222)
Getting started with test automation

What's hot (20)

PDF
美团前端架构简介
PPTX
Full stack-development with node js
PDF
Angular js twmvc#17
PDF
Ch13 整合Spring MVC
PPT
课题二:Node.js那些事儿
PPT
Vuebms 前端技術架構
PPTX
Blazor 與 Radzen 同行
PPTX
深入淺出Node.JS
PPTX
NODEjs Lesson1
PPTX
ASP.Net MVC Framework
PDF
使用Bigpipe提升浏览速度
PPTX
微服務架構 導入經驗分享 吳剛志 - Community Open Camp
PDF
kissy modularization part2
PPTX
DDD系統分析
PPTX
使用kslite支持第三方内容开发
PPTX
2016年逢甲大學資訊系:ASP.NET MVC 4 教育訓練4
PDF
Ch02 撰寫與設定Servlet
PPTX
前端性能测试
PDF
Blazor Component 開發實戰
PPTX
Asp.net core v1.0
美团前端架构简介
Full stack-development with node js
Angular js twmvc#17
Ch13 整合Spring MVC
课题二:Node.js那些事儿
Vuebms 前端技術架構
Blazor 與 Radzen 同行
深入淺出Node.JS
NODEjs Lesson1
ASP.Net MVC Framework
使用Bigpipe提升浏览速度
微服務架構 導入經驗分享 吳剛志 - Community Open Camp
kissy modularization part2
DDD系統分析
使用kslite支持第三方内容开发
2016年逢甲大學資訊系:ASP.NET MVC 4 教育訓練4
Ch02 撰寫與設定Servlet
前端性能测试
Blazor Component 開發實戰
Asp.net core v1.0
Ad

Viewers also liked (20)

PPT
Plant tissues
PPTX
Presentatie Astorium IT
PPT
Respiratory system
PDF
Presentasjon1om barnehage2
PPT
The pancreas
PPT
Excretory system
PPT
Reproductive system day1
PPTX
Endocrine system
PPT
Quiz DDS
PPT
Hinku project 16112011
PPSX
Common heart problems
PPTX
8/10 Spinal cord
PPT
Pulmonary & systemic circulation
PPT
Nosql七种武器之长生剑 mongodb的使用介绍
PPT
Enzymes
PDF
2014WebRebuild年会分享
PPT
Pulmonary & systemic circulation
PPT
Elasticsearch
PDF
Customer satisfaction on retailers' services
PPTX
只需要懂Jquery也能學react js
Plant tissues
Presentatie Astorium IT
Respiratory system
Presentasjon1om barnehage2
The pancreas
Excretory system
Reproductive system day1
Endocrine system
Quiz DDS
Hinku project 16112011
Common heart problems
8/10 Spinal cord
Pulmonary & systemic circulation
Nosql七种武器之长生剑 mongodb的使用介绍
Enzymes
2014WebRebuild年会分享
Pulmonary & systemic circulation
Elasticsearch
Customer satisfaction on retailers' services
只需要懂Jquery也能學react js
Ad

Similar to 基于Seajs的项目构建 (20)

PDF
2011新版首页总结 技术篇
PPTX
浅析浏览器解析和渲染
PPTX
使用 TypeScript 駕馭 Web 世界的脫韁野馬:以 Angular 2 開發框架為例
PDF
合久必分,分久必合
PDF
建立前端开发团队 (Front-end Development Environment)
PDF
.NET Conf Taiwan 2022 - Tauri - 前端人員也能打造小巧快速的 Windows 應用程式
PDF
從軟體開發角度
談 Docker 的應用
PDF
淘宝前端开发关键词
PDF
前端编译平台
PDF
李成银:前端编译平台
PPTX
Postoffer前端架构设计
PDF
4. Go 工程化实践-0124-v2.pdf
PPTX
我們與Azure DevOps的距離
PDF
SeaJS 那些事儿
PPTX
Js高级技巧
PPTX
改善 Angular 開發流程:你所不知道的 Schematics 程式碼產生器
PDF
Vue ithome
PDF
模块加载策略 - 2012 SDCC, 北京
PPTX
How to ASP.NET MVC4
PPTX
ASP.NET MVC 6 新功能探索
2011新版首页总结 技术篇
浅析浏览器解析和渲染
使用 TypeScript 駕馭 Web 世界的脫韁野馬:以 Angular 2 開發框架為例
合久必分,分久必合
建立前端开发团队 (Front-end Development Environment)
.NET Conf Taiwan 2022 - Tauri - 前端人員也能打造小巧快速的 Windows 應用程式
從軟體開發角度
談 Docker 的應用
淘宝前端开发关键词
前端编译平台
李成银:前端编译平台
Postoffer前端架构设计
4. Go 工程化实践-0124-v2.pdf
我們與Azure DevOps的距離
SeaJS 那些事儿
Js高级技巧
改善 Angular 開發流程:你所不知道的 Schematics 程式碼產生器
Vue ithome
模块加载策略 - 2012 SDCC, 北京
How to ASP.NET MVC4
ASP.NET MVC 6 新功能探索

基于Seajs的项目构建

Editor's Notes

  • #3: 今天我从一个小的例子helloworld开始给大家介绍一下基于Sea.js做模块化开发项目完整的构建过程。然后会结合自身的项目实践说一下我自己的感受。 整个构建过程覆盖的面会比较多,我不可能全部介绍。所以我选出我认为最重要或者坑比较多的几点来说,另求把这几个点都给大家说明白。
  • #4: Grunt和Sea.js想必大家都并不陌生,有意或无意也听到过它们的介绍和价值,可能也有使用过它们。所以这里我不会花时间介绍这些。
  • #5: 我会按照下面的提纲介绍今天的内容
  • #7: 模块标识是一个字符串,用来标识模块。在seajs.use, require等加载函数中,第一个参数都是模块标识。 Sea.js中有三种模块标识方式
  • #8: 我们先来看一个例子 那么像这种不以../,./,/开头的标识,就是顶级标识,它将相对于seajs base路径来解析 那么seajs base又是什么?
  • #9: Sea.js base是sea.js文件本身加载的路径 当项目较大,多人合作的时候,一个js文件往往有多个版本,这个时候,我们需要用版本号管理文件。 当 sea.js 的访问路径中含有版本号时, base 不会包含 Sea.js/x.y.z 字串。 当 sea.js 有多个版本时,这样尤其会很方便。
  • #10: 当然,也可以手工配置 base 路径:
  • #11: 回到刚才的例子,我们需要加载jquery的这个模块,那么这个模块的文件地址到底在哪里咧? 假设…,那么我们得到这个模块对应的文件路径为…
  • #12: 刚才我们介绍模块有三种标识: 顶级标识 相对标识 普通路径 现在来看看相对标识,同样先看一个例子,相对的概念大家都应该很清楚,引用文件时经常用到相对路径,这里的相对标识其实也差不多。 以./或者../打头的是相对标识,这种标识是相对于当前模块的路径来解析的
  • #13: 比如上面的例子,解析得到的路径分别是 实际上,相对标识是很方便的,在项目中推荐使用相对标识来相互引用模块
  • #14: 第三种模块标识就是普通路径 除了相对和顶级标识之外的标识都是普通路径。例子中展示了它的三种形式: 普通路径的解析规则,和 HTML 代码中的 <script src="..."></script> 一样,会相对当前页面解析。 实际上,我感觉普通路径里唯一有点作用的只有seajs.use(),而且作用也不是特别大,因为可以用顶级标识代替。 绝对路径和根路径用得就更少了。 所以,不太需要关注普通路径。一般顶级标识和相对标识就已经够用了
  • #16: 我们了解了模块标识,下面大家讲一下模块加载过程 使用 seajs.use 或 require 进行模块的加载,举例加载 app/hello/1.1.0/hello这个模块,这是个顶级标识,所以我们根据Sea.js的base路径来解析, 假设Sea.js base为… 则该模块对应的文件为…
  • #17: 现在我们根据路径解析规则,知道这个模块就在这个文件中,在这个文件中我们需要做些什么咧? 首先是定义模块,而模块又分为两种:具名和匿名,
  • #18: 我们用define函数来定义模块 具名模块(即定义了 ID 的模块)。 我们用define函数来定义模块,第一个参数即模块ID,即定义了第一个参数的就是具名模块。 刚才在加载模块的时候我们见到了类似的模块标识,但是这个参数被规定为文件路径(而不是 ID),这样的设计减轻了记忆模块 ID 的负担,无论是匿名模块还是具名模块,开发者只需要知道文件放在哪儿就行了。
  • #20: 具名函数中有个非常重要的概念,ID和路径匹配原则,使用 seajs.use 或 require 进行文件引用时,如果是具名模块,会把 ID 和 use或 require 的路径名进行匹配,如果一致,则正确执行模块返回结果 只有在这种情况下,我们才能正常地执行模块
  • #21: 具名模块中,如果ID和路径不匹配,则返回 null。
  • #22: 和具名函数相对的,没有定义… 在 CMD 的书写规范中,一个文件对应一个模块,所有的模块都是匿名模块。那么当 seajs.use 某模块时,这个模块对应的文件里的唯一的 define 方法理所当然的是这个模块的执行代码。
  • #23: 在生产环境下,静态文件不可避免地需要进行合并打包,以优化请求数提高页面性能。这时,一个 js 文件可能有很多 define() 方法。
  • #24: 所以我们这个时候我们需要具名模块 我们定义好每个模块的 id ,在 Sea.js 里,那个和文件路径匹配的 ID 的模块就是这个文件的主模块。 这个原则保证了我们能够自由合并模块来优化性能。
  • #25: 下面提供一个使用Grunt构建Sea.js项目的完整例子 先看看项目结构
  • #26: 在项目部署上线前,通常要将源文件压缩,合并,并拷贝到bch或trunk中。 在将js模块化后,又多了一个分析,提取业务代码中所依赖模块的工作。 解决这一系列繁重工作的自动化工具,称之为构建工具。 就好像一个万能工厂(grunt),只负责执行任务(Task),不关心每个任务到底都干了什么
  • #27: app下放的是html文件 sea_modules 是所有的最终的js文件 其中 app 是项目特定页面的业务层js,是构建后的js最终文件 gallery spm提供的已经以CMD格式封装好的通用库都在这里 seajs 放seajs和其插件 static 项目特定页面的业务层js源码文件
  • #28: 将需要的Grunt插件写在package.json里,用npm install命令下载,装在node_modules里。注意,node_modules不需要上传到Svn或GitHub,只需要上传package.json就可以了
  • #29: 这个html作为入口,引入了sea.js,后面的id=“seajsnode",加上 seajsnode 值,可以让 sea.js 直接获取到自身路径,而不需要通过其他机制去自动获取。这对性能和稳定性会有一定提升,推荐默认都加上。 之后设置了base,因为默认的是seajs_hello/seajs_modules/seajs,不方便用top-level来引用其他模块,所以改成../sea_modules,注意这里的路径相对于html页面所在路径来说的 最后因为开发态和部署态,引的js文件不一样,开发环境下,加载src下的main.js作为入口,生产环境下加载app…作为入口(使用的是顶级标识)
  • #30: 该项目共三个js文件,依赖关系为
  • #31: 我们从最基本的模块world开始 开发阶段,一般每个文件对应一个模块,并使用匿名的方式定义模块 world这个模块主要是对外提供 add 方法
  • #32: 在hello.js中首先用require函数来获取指定world模块的接口:add,这里加载模块使用的是相对标识 然后通过exports对外提供increment函数
  • #33: 最后就是main.js就是获取hello模块的接口,并使用它
  • #34: 现在,已经可以正常运行了
  • #35: 下面开始一步步介绍构建的详细过程
  • #36: 虽然现在项目已经能够正常运行了。但是生产环境一般都需要合并和压缩js文件来提高性能,而直接压缩的话,一个js文件会有多个define模块,Sea.js无法识别用户到底想加载哪个模块,所以需要先提取module_id,变成具名模块。 而且由于前面说过的Sea.js的“ID和路径一致性”的要求,传给require()的模块标识,不仅要能找到对应的js文件,而且模块ID还要相同才可以。 因此,需要用配套的构建工具来构建,压缩后的js才能被Sea.js正常解析和加载
  • #37: CMD 模块在构建时,有两个基本操作: 经过上面的提取操作后,构建工具就可以调用任何 JS 压缩工具来进行压缩了 具体情况,后面的例子会想详细给出
  • #38: 这是构建的第一步,用的是Grunt-cmd-transport插件,Gruntfile.js这部分内容如下: idleading参数,这决定了提取出来的module_id,要和我们最终的目录结构保持一致!
  • #39: 执行Grunt transport以后,会把提取之后的文件放在临时目录.build里
  • #40: 看下hello.js提取后的样子: 通过transport,我们提取出了模块的标识id和依赖。将匿名模块转化为了具名模块
  • #41: main.js同理,main.js依赖hello和world
  • #42: 前面提取之后,接下来的动作是合并,把hello.js和world.js合并成hello.js,用到的插件是Grunt-cmd-concat。这里务必注意,合并后的名字不能改,还必须是hello.js,这也是因为前面提到的“ID与路径匹配原则”。 include参数是合并哪些依赖,可选值有self,relative,all。self只会合并自身,relative的含义是合并采用相对路径依赖的模块,all则是会合并依赖的依赖。self是默认值
  • #43: 执行grunt-cmd-concat后
  • #45: 我们可以发现,多个文件合并成一个之后,对外就只能暴露一个模块了(这里是hello,world只能内部引用)
  • #46: 容易出错的部分已经结束了,剩下的就是压缩和清理临时目录,没什么特别可说的,用的是Grunt-contrib-uglify和Grunt-contrib-clean
  • #50: 一个以js为主的项目
  • #53: 首先,示例非常简单,就是展示数据分析的图表。由于这个项目中图表特别多,由于很多除了数据,都是可以重复使用的,那么我将各类图表封装成一个模块
  • #57: 现在需要一个开发阶段seajs的配置文件rootConfig.js,并将其引入到页面中:
  • #58: 接下来我们来编写展示的页面overview.html: 这时候运行刚刚完成的index.html,一切顺利的话,应该已经可以看到图表的效果了。
  • #59: 这里我不详细介绍了,和前面helloworld的构建过程一样,我们回忆一下