模块化开发 - Zikzin/Angular.js-study GitHub Wiki
- 1、将软件产品看作为一系列功能模块的组合。
- 2、通过特定的方式实现软件所需模块的划分、管理、加载。
- 1、便于协同:你不是一个人在战斗。
- 2、代码复用
- 3、解决问题:(可以解决痛点的东西才是好东西,比如ng.js可以解决复杂的dom操作。)
- (1)https://github.com/seajs/seajs/issues/547(seajs官方解释)
- (2)大量的文件引入
- (3)命名冲突
- (4)文件依赖 a、存在 b、顺序 c、类似问题:使用bootstrap时,需要使用jquery。
-
1、案例:02-evolution文件夹
- 早期开发过程中就是将重复的代码封装到函数中,再将一系列的函数放到一个文件中,称之为模块。
- 这只是约定的形式定义的模块,存在命名冲突,可维护性也不高。
- 仅仅从代码角度来说:没有任何模块的概念。
-
2、分页实现
- 案例插件:http://esimakin.github.io/twbs-pagination/
- 可以用实际数据帮助理清逻辑
- innerHTML 比 appendChild() 效率高:innerHTML是一次dom操作,appendChild()是多次dom操作,会导致dom上多次重复。
- classList对象用于给dom元素新增或删除它的类名的那个属性。
- 学习时候,可以参考其他语言的逻辑,然后用js实现。
- 从代码层面就已经有了模块的感觉。
- 缺点:还是污染全局(不是问题)。
- 传统编程语言中的命名空间的概念(math.calculator.add();)。
- 高内聚,低耦合:模块内部相关性强,模块之间没有过多相互牵连。
- 但这样还是不够好:因为没有私有空间。
- 函数包装一个独立的作用域(自执行函数)
- 私有的转换逻辑
- 返回值的方式得到模块的公共成员(return{ add:add,})
- 比如注册方法中可能会记录日志
- 优势在于:可以有选择的对外暴露自身成员
- 私有成员的作用:1、将一个成员私有化。 2、抽象公共方法(其他成员中都会用到的)。
- 给自执行函数传参数。
- 便于庞大模块的子模块划分。
- 开闭原则,对新增开放,对修改关闭。
- 对于模块的依赖通过自执行函数传参数。
- 依赖抽象。
- 比如jQuery换zepto。
- 原则:高内聚,低耦合。
- 业务复杂。
- 重用逻辑非常多。
- 扩展性要求较高。
-(本身没API,或者使用,你实现我定义的标准,就可以说是实现了这个规范。)
- 服务端js模块化编码规范
- require
- exports
(3)CommonJS官方网站
(5)AMD官方文档
(4)CMD官方文档
- (1)引包
- (2)定义一个模块如main.js(通过define方式并将模块exports暴露出去):在Seajs中模块的引入需要相对路径完整写法,或者使用网站根目录(启用网站服务器时候)
- (3)引用模块(页面的行内脚本中通过seajs.use('path',fn)的方式使用模块):方便我们模块化,解决了命名冲突(因为文件名不会重复),文件依赖的问题。
- (4)回调函数的参数传过来的就是模块中导出的成员对象。
- define
define(function(require, exports, module) {
exports.add = function(a, b) {
return a + b;
};
});
-
1、seajs.use
- 一般用于入口模块
- 一般只会使用一次(入口是单一的。)
-
2、require
- 模块与模块之间
- (1)module.exports(导出一个成员、一个对象的时候,是一个整体)(module指的是模块信息,不只是exports)
- (2)exports.xxx (导出部分成员,工具类、方法)
- (3)return
- 三种方式的优先级 return > module.exports > exports (一般很少用return)
- 默认require的效果是同步的,会阻塞代码的执行,造成界面卡顿
- require.async();
require.async('path',function(module) {
});
- 由于CMD是国产货,jquery默认不支持(jQuery支持了AMD,从源码可看出)
- 改造(直接在jQuery.js中)
// 适配CMD
if (typeof define === "function" && !define.amd) {
// 当前有define函数,并且不是AMD的情况
// jquery在新版本中如果使用AMD或CMD方式,不会去往全局挂载jquery对象(noConflict(true))
define(function() {
return jQuery.noConflict(true);
});
}
- js中引入模块时,可能模块的层级会陷得比较深,为提高开发效率和可维护性。对变化点进行封装。
- 如:
<script> seajs.config({ alias: { // 变化点封装 calc: './modules/calc.js', } }); seajs.use('calc'); </script>
- 配置
- 变化点封装
- seajs.config
- base
- alias 别名设置(对象)
- Tab标签页