没有规矩,不成方圆,今天我们就来聊聊模块化规范
模块:对一些复杂的代码功能进行分离、按照某个规范进行封装成单个或者多个文件,同时暴露一些属性或者方法给外界调用。
为什么要模块化?
1.避免变量污染或者冲突
2.便于代码封装,提高复用性
3.代码便于维护,逻辑分离
温馨提示:文章结构如下,阅读完可能需要花费3分钟
一、模块化的进化过程
二、模块化规范之-CommonJS规范
三、模块化规范之-AMD规范
四、模块化规范之-CMD规范
五、模块化规范之-ES6规范
进入正文
一、模块化的进化过程
1.全局function模式 : 将不同的功能封装成不同的全局函数
优点:把单一功能封装在函数中,增加复用性
缺点:命名空间被污染,数据不安全,容易命名冲突
使用案例:
function funcA() {
console.log('函数A')
}
function funcB() {
console.log('函数B')
}
2.namespace模式: 命名空间,封装成对象
优点:减少全局变量
缺点: 数据不安全,可以直接修改内部变量
使用案例:
const module = {
message: "我是一个message",
run(){
console.log('开始运行', this.message);
},
};
module.message = "test";
module.run();
3.IIFE模式: 立即执行函数
优点:私有数据,外部只能访问暴露的方法或者属性
缺点:模块依赖其他模块比较麻烦
使用案例:
(function (window) {
const url = "www.baidu.com";
function run(){
console.log('开始运行', this.url);
};
window.myModule = {run, url};
})(window);
myModule.run();
二、模块化规范之-CommonJS规范
同步加载,服务端文件一般存在本地,所以使用同步加载比较快,这个规范服务端常用
CommonJS说明
1.1.每个文件就是一个模块,有自己的作用域;
1.2 每个文件里面定义的变量、函数、类,都是私有的;
1.3.服务端-模块的加载是运行时同步加载;
1.4.浏览器端-模块需要提前编译打包处理,才可以被运行
1.5 运行时确定依赖关系
1.6 CommonJS 模块输出的是一个值的拷贝基本语法
导出方式一 : module.exports.xxxx = value
const url = "www.zb.com";
function funcA() {
console.log('commonjs-导出-模块A',url);
}
//暴露属性
module.exports.test = url;
// 暴露方法
module.exports.funcB = funcA;
导出方式二 : module.exports = {}
module.exports = {
count: 4,
addCount(){
this.count++;
},
printB(){
console.log('打印模块B');
}
}
导入引用: require('路径引入或者第三方模块')
浏览器不能直接使用require,需要使用webpack 或者browserify 编译之后的文件浏览器才能识别
本质:加载某个模块,其实是加载该模块的module.exports属性
const moduleA = require('./moduleA.js');
const moduleB = require('./moduleB.js');
console.log('打印模块A的属性',moduleA.test);
moduleA.funcB();
moduleB.printB();
console.log('模块计算前的值',moduleB.count);
moduleB.addCount();
console.log('模块计算后的值',moduleB.count);
3.使用工具
browserify 或者 weback
三、模块化规范之-AMD规范
非同步加载,主要用于浏览器端
AMD规范说明
1.1 主要用于浏览器端,模块加载是异步的
1.2 依赖于require.js-
基本语法
导出方式一 : 无依赖直接导出模块define(function () { const moduleA = { getMessage: function () { return "我是模块A的message"; } } return moduleA; });
导出方式二 :有依赖导出
define(['moduleA'], function (moduleA) {
const moduleB = {
getReuslt: function () {
return moduleA.getMessage() + "我是模块B";
},
};
return moduleB;
});
引用模块
require(['moduleA','moduleB'], function (moduleA , moduleB) {
moduleB.getReuslt();
})
- AMD + requirejs 使用
第一步: 下载require.js
下载方式 : 官网下载 或者 npm install requirejs --save-dev
第二步: 创建自定义模块, 目录如下moduleA, moduleB
第三步: 创建main.js 作为自定义模块的入口并配置
// main.js
(function () {
require.config({
baseUrl: "./05-模块化规范/053-AMD规范",
paths:{
//映射: 模块标识名: 路径 不能加js
moduleA: './moduleA',
moduleB: './moduleB'
}
});
require('moduleB', function (moduleB) {
moduleB.getReuslt();
})
})();
第四步:html中引用main.js 与requirejs
<script src="../node_modules/requirejs/require.js" defer async="true"data-main="./053-AMD规范/main.js"></script>
defer async 表示异步 兼容写法
src: 引用requirejs
data-main: 模块入口
三、模块化规范之-CMD规范
CMD规范说明
1.1 commonjs + AMD 组合版
1.2 主要用于浏览器
1.3 模块的加载是异步的
1.4 依赖于sea.js基本语法
导出方式一:导出没有依赖的模块
define(function (require, exports, module) {
const moduleAA = {
message: "我是模块AA",
};
module.exports = moduleAA;
});
导出方式二:导出有依赖的模块
define(function (require, exports, module) {
const moduleAA = require('./moduleAA');
const moduleBB = {
printMessage:function () {
console.log("我是模块BB" + moduleAA.message);
},
};
module.exports = moduleBB;
});
引入导入方式:define(function (require) {})
define(function (require) {
const moduleBB = require('./moduleBB');
const moduleAA = require('./moduleAA');
// console.log('main文件打印---',moduleAA.message);
console.log('main文件打印---',moduleBB.printMessage());
});
- CMD+sea.js
第一步:下载或安装seajs npm install seajs --save-dev
第二步:新建自定义模块, 目录结构如下
第三步:新增main.js作为模块入口
// main.js
define(function (require) {
const moduleBB = require('./moduleBB');
const moduleAA = require('./moduleAA');
// console.log('main文件打印---',moduleAA.message);
console.log('main文件打印---',moduleBB.printMessage());
});
第四步:html 使用模块
<script src="../node_modules/seajs/dist/sea.js"></script>
<script type="text/javascript">
seajs.use('./054-CMD规范/main');
</script>
五、模块化规范之- ES6规范- 常用
ES6规范说明
1.1 编译时确定依赖关系
1.2 ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块
1.3 ES6 模块输出的是值的引用值基本语法
导出
export default xxx 或者 export {}
导入
import
- 语法编译工具
A. 使用Babel将ES6编译为ES5代码;
B. 使用Browserify编译打包js