MG,Module Generation,模块时代。以Sea.js为基础,构建遵循CMD规范的模块。
解决两个问题:
- 解决模板中对脚本随意引用而引起的复和杂问题,实现解耦;
- 将脚本依赖从模板中迁移到脚本中,更接近使用的地方,实现内聚。
客户端延迟请求
页面中,大多数脚本处于等待使用的状态,这部分脚本完全可以按需加载,将依赖分析后移到浏览器端业务执行时,基于Sea.js实现客户端延迟请求解决方案。
页面加载完成之后,基于HTTP 1.1协议中的Connection: keep-alive
和浏览器的并发加载,是否真的会比全部合并加载快。
HTTP 2.0协议普及之后,combo的过程都可以省略,文件的加载将不是问题。
基础
$header
(HeaderLite
类的全局单例)和$footer
(FooterLite
类的全局单例)中的importJavascript
和importCss
两个静态资源引用方法会自动合并并更新资源的版本号(?ver=最新版本号
),用这两个方法引用的静态资源不用关心CDN缓存的问题。
Header中的关键代码
Footer中的关键代码
JS模块代码进行Transport处理时,会自动为模块中依赖的JS脚本添加hash版本号解决CND缓存的问题。
页面中以模块为基本逻辑和代码组织单位,在单独的模块中引用对应的seajs_config.js入口配置文件,一个页面中可以多次引用,Sea.js会自动合并配置。
目的:提升使用的快感,解决无法编译的问题。
页面中需要引入的JS文件
在页面的头部中共需要引入如下6个JS文件,前5个是Sea.js的基本文件。config.js是全局配置文件。
全局配置文件config.js详细
全局配置文件的作用共4个:
- 基于版本号统一管理Lib库中引用的第三方资源,当第三方资源更新时,只需要更新配置文件中的版本号,重新编译Lib库和config.js配置文件并上线即可在业务代码中生效;
- 设置统一的debug开关,当URL中出现dev参数时,即可调用debug版本的js;
- 设置模板后缀名映射;
- combo合并请求配置参数设置。
第三方资源Lib管理
Lib目录结构设计
Lib库编译
Lib库中引用的第三方JS共有两类,一是Sea.js相关文件,只进行Uglify压缩处理;二是jQuery、Hogan等第三方库,引入源码文件并手工修改为CMD格式,随后按如下流程处理。
主要处理流程如下:
- SeaJs文件Uglify压缩;
- 第三方库CSS文件压缩;
- 第三方库JS文件Transport;
- 第三方库JS文件拷贝Debug版本;
- 第三方库JS文件Uglify压缩。
针对项目CSS编译
每个页面只引用1个CSS文件,CSS的依赖通过Less的@import
解决。
主要处理流程如下:
- Less文件预处理;
- CSSLint;
- ICON图片合并;
- 图片文件Hash化;
- 图片路径转换(符合静态资源部署规则);
- CSS文件压缩。
针对项目JS编译
JS目录的组织,每个业务或功能模块分别建立单独的文件夹,文件夹中以main.js为其入口文件,并以该文件夹名为启动入口名。
主要处理流程如下:
- 代码质量检查(JsLint,出现错误立刻中止);
- JS文件Transport;
- JS文件拷贝Debug版本;
- JS文件Uglify压缩;
- 生成模块入口配置文件(
seajs_config.js
)。
生成的seajs_config.js文件示例
该文件的作用是避免模块入口启动文件的CND缓存问题。
目前存在的问题
- 文件编译的性能问题;
- 入口文件名标识容易冲突的问题;
- 可以增加以单个JS文件为粒度的客户端持久化缓存;
- Sea.js的CMD不符合国际事实,Require.js的AMD更友好,或者找到更好的方案;
- gulp的流模式比Grunt的配置在工程化上更有优势;
- 将开发开发构建和生产环境构建分离;
- JS、CSS和图片等静态资源和HTTP/2的兼容;
- 图片的优化处理(gulp方案中存在);
- NPM管理第三方库资源;
- 按正宗的CommonJS方案去写代码;
- Babel和ES6的使用;
- 肯定还有很多其他问题,需要大家一起携手搞定。