模块化开发

模块化开发

将一个复杂的程序按照一定的规则(规范)分成几个块,并组合在一起。

块的内部数据/实现是私有的,只是向外暴露一些接口(方法)与外部其他模块进行通信

模块化开发的历史

一开始我们使用的是几个函数作为一个模块,但是这种方法容易造成全局变量污染,并且模块之间没有联系。

后来提出对象的方法,就函数作为一个对象的方法来实现,这样就解决了函数作为模块的一些缺点,但是这种方法会暴露所有的模块成员,并且外部成员可以修改内部属性。

现在最常用的是立即执行函数的写法,通过利用闭包的私有作用域的建立,并且不会造成全局变量的污染

(function(win){

​ function aFn(){

​ }

​ function bFn(){

​ }

​ win.myMethod={aFn,bFn};

})(window)

IIFE模式增强版:引入依赖

这里是现代模块实现的基石

(function(window,&){

​ let msg=‘module4’;

​ function foo(){

​ console.log(‘foo()’,msg);

​ }

​ window.module4=foo;

​ $(‘body’).css(‘background’,‘red’);

})(window,jQuery)

模块化的好处

减少全局变量的污染,更好的分离,按需加载,高复用性,高可维护性。

但是现实是 页面引入过来的script会造成 请求过多 依赖模糊 难以维护

Commentjs

暴露模块 module.exports=value exports.xxx=value

引入模块 require(xxx)

服务器端实现

Nodejs

module1.js
/**
 * 使用module.exports = value向外暴露一个对象
 */
"use strict"
module.exports = {
  foo() {
    console.log('moudle1 foo()')
  }
}

module2.js
/**
 * 使用module.exports = value向外暴露一个函数
 */
"use strict"
module.exports = function () {
  console.log('module2()')
}

module3.js
/**
 * 使用exports.xxx = value向外暴露一个对象
 */
"use strict"
exports.foo = function () {
  console.log('module3 foo()')
}

exports.bar = function () {
  console.log('module3 bar()')
}

app.js
/**
  1. 定义暴露模块:
    module.exports = value;
    exports.xxx = value;
  2. 引入模块:
    var module = require(模块名或模块路径);
 */
"use strict"
//引用模块
let module1 = require('./modules/module1')
let module2 = require('./modules/module2')
let module3 = require('./modules/module3')

客户端实现

Browserify 也称为Commonjs的浏览器端的打包工具

代码和服务器端一样 我们需要打包处理
browserify js/src/app.js -o js/dist/bundle.js //output

区分Node与Browserify Node.js运行时动态加载模块(同步) Browserify是在转译(编译)时就会加载打包(合并)require的模块

AMD

专门用于浏览器端,模块的加载是异步的

//dataService.js
define(function(){
	let name='dataService.js';
	function getName(){
		return name;
	}
	//暴露接口
	return {getName};
})

//alerter 定义有依赖的参数
define(['dataService','jquery'],function(dataService,$){
	let msg='alerter.js';
	function showMsg(){
		console.log(msg,dataService.getName());
	}
    $('body').css('background','deeppink');
    //暴露模块
    return {showMsg};
})

// main.js 入口文件
(function(){
    requirejs.config({
        baseUrl:'js/',//基本的路径 出发点在根目录下
        paths:{
            dataService:'./modules/dataService',
            alerter:'./modules/alerter', // 不可以添加js 因为默认添加了
            jquery:'./libs/jquery-1.10.1', // 因为它支持AMD
            angular:'./libs/angular'
        }
        shim:{
        	angular:{
        		exports:'angular'
    		}
    	}
    });
    
    requirejs(['alerter','angular'],function(alerter,angular){
        alerter.showMsg();
        console.log(angular);
    })
})

CMD

module1.js

//定义没有依赖的模块
define(function(require,exports,module){
	let msg='module1';
	function foo(){
		return msg;
	}
	// 暴露模块
	module.exports={foo};
});

module2.js

//定义没有依赖的模块
define(function(require,exports,module){
	let msg='module2';
	function bar(){
		console.log(msg);
	}
	// 暴露模块
	module.exports=bar;
});

module3.js

define(function(require,exports,module){
	let data='module3';
	function fun(){
		console.log(data);
	}
	exports.module3={fun};
});

module4.js

define(function(require,exports,module){
	let msg='module4';
	// 同步引入
	let module2=require('./module2');
	module2();
	// 异步引入
	require.async('./module3',function(module3){
		module3.module3.fun();
	});
	function fun2(){
		console.log(msg);
	}
	exports.fun2=fun2;
})

main.js

define(function(require){
	let module1=require('./module1');
	console.log(module1.foo());
	let module4=require('./module4');
	module4.fun2();
})

index.html

<script type='text/javascript' src='js/libs/sea.js'><scirpt>
<script type='text/javascript'>
	seajs.use('./js/modules/main.js');
</script>
// module1 module2 module4 module3

ES6

依赖模块需要编译打包处理

module1.js

// 暴露模块 分别暴露
export function foo(){
	console.log('foo() module1');
}
export function bar(){
	console.log('bar() module1');
}
export let arr = [1,2,3,4,5];

module2.js

// 统一暴露
function fun(){
   	console.log('fun() module2');
}
function fun2(){
    console.log('fun2() module2');
}
export {fun,fun2};

module3.js

// 默认暴露 可以暴露0任意数据类型,暴露什么数据接收到的就是什么数据
export default{
	mag:"默认暴露",
	foo(){
		console.log('我是默认暴露的箭头函数');
	}
}

main.js

// 引入其他的模块
// 语法 import xxx from '路径';
import {foo,bar} from './module1'; // import 只是开了一下门 你需要选择你需要的方法
import {fun,fun1} from './module2';
import module3 from './module3';
import $ from 'jquery'
foo();
far();
fun();
fun1();
module3.foo();

使用Babel将es6编译为ES5代码(但包含CommJS语法):babel js/scr -d js/lib

使用Browserify编译成js:browserify js/lib/app.js -o js/lib/bundle.js

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值