# JS的模块化进程
//最早我们这么写代码
function a(){}
function b(){}
//Global被污染,很容易命名冲突
//简单封装: Namespace模式
var myModule = {
a: function(){},
b: function(){}
}
myModule.a();
//减少了全局命名,但是能操作对象,一点都不安全
//IIFE 匿名闭包模式
var Module = (function(){
var _private = "safe now";
function a(){
console.log("_private");
}
return {
a: a
}
})()
Module.a();
Module._private; //读不到,undefined
//相对安全
//再增强一点:引入依赖
//这里依赖了jQuery
var Module = (function($){
var _body = $("body");
var a = function(){
console.log(_body);
}
return {
a: a
}
})(jQuery);
//但这样在页面引入script也是要按顺序,且请求量非常多
# 为什么要模块化
- 降低复杂度、解耦合、降低请求
- 避免命名冲突、按需加载、高复用、可维护
# 模块化规范
# CommonJS规范
说明
- 每个文件都可当做一个模块
- 在服务器端:模块加载是运行时同步加载的
- 在浏览器端:模块需要提前编译打包处理
语法
- module.exports = value;
- exports.xxx = value;
- require(相对路径/包名);
- (暴露的本质都是exports对象与require所得一样,exports.xxx是里面一个属性)
利用browserify编译
sudo npm install browserify -g
npm install browserify --save -dev
//编译打包命令
browserify index.js -o dist/bundle.js
# AMD规范
说明
- 用requireJS库
- 专门用于浏览器端,模块的加载是异步的
语法
//定义没有依赖模块
define(functon(){
return 模块;
})
//定义有依赖模块
define(['module1','module2'],functon(m1,m2){
return 模块;
})
//requireJS的配置文件
requirejs.config({
//设置根路径
baseUrl:"",
paths:{
module1:'相对路径',
module2:'相对路径'
}
});
require(['module1','module2'],functon(m1,m2){
return 模块;
});
//在html中引入
//<script data-main="主模块的相对路径" src="requireJS库路径"></script>
# ES6
说明
依赖模块需要打包处理,使用Babel将ES6编译为ES5代码,使用Browserify编译打包js 语法
export导出
import导入
export default导出单个对象
编译打包过程(此方法是使用插件预设babel-perset-es2015完成的)
- npm安装好需要件(browserify babel-cli)
- 定义.babelrc配置文件(当前文档上已经有新的方法创建)
- {"presets":["es2015"]}
- babel编译(build) 使ES6语法转换为ES5语法 和 browserify打包(dist) 使JS能被浏览器识别
//babel module -d build
//browserify build -o dist/bundles.js
4.html引入bundles.js运行