【记录】前端工程化 - 模块化规范

模块化

  • 将一个复杂的程序根据一定的规则封装成几个块,并组合在一起。块的内部数据/实现是私有的,只是向外部暴露一些借口与外部其他模块进行通信。

模块化的进化史

//全局函数模式:将不同的功能封装成不同的全局函数。
//Global被污染,容易命名冲突。
function foo(){
	...
}
function bar(){
	...
}


	
//Namespace模式:简单对象封装。
//减少Global上的变量数目;本质是对象,仍可以操作修改它,不安全。
let MYAPP = {
	foo: function(){
		...
	},
	bar: function(){
		...
	}
};

MYAPP.foo();
		
		
		
//IIFE模式:匿名函数自调用(闭包)。
(function(window){
	let msg = 'module';
	function foo(){
		...
	}
	window.module = {
		foo
	};
})(window);

module.foo();
		
				

//IIFE模式增强:引入依赖。
(function(window, $){
	var _private = "a";
	var foo = function(){
		console.log(_private);
	};
	window.Module = {
		foo
	};
})(window, jQuery);
		
Module.foo();//"a"
Module._private;// undefined

模块化的好处

  • 避免命名冲突(减少命名空间污染)。
  • 更好的分离,按需加载。
  • 高复用性。
  • 高可维护性。

CommonJS

模块

  • 核心模块:由node引擎提供的模块。
    核心模块的标识就是模块的名字。例如:var fs = require(‘fs’);

  • 文件模块:由用户自己创建的模块。
    文件模块的标识就是文件的路径。

//服务器端
//一个模块就是一个js文件。当执行模块中的代码时,会在代码包裹在函数里,同时传递进5个参数。
/*
	expots:该对象用来将变量或函数暴露到外部。是module的属性。
	require:用来引入外部模块的函数。
	module:当前模块本身。
	__filename:当前模块的完整路径。
	__dirname:当前模块所在文件夹的完整路径。

*/
function (exports, require, module, __filename, __dirname){
	...
}



//暴露模块
//1、分别暴露:将需要暴露的变量或方法设置为exports的变量或方法。
exports.x = 10;
//等同于(因为exports是module的属性)
module.exports.x = 10;
	
//2、统一暴露
//不能写成以下(因为exports指向module.exports,如果写成下面则把exports指向另外一个对象了)
exports = {
	...
}
//正确写法
module.exports = {
	...
};


//引入模块
//require(filePath):使用相对路径,必须使用./或者../开头,.js可以省略。返回一个对象。
//app.js
var module = require('./module');
module.x // 10
module.foo();

包规范

  • 允许我们将一组相关的模块组合在一起,形成一组完整的工具。
  • 由包结构和包描述文件两个部分组成。
    包结构:用于组织包中的各种文件。
    包描述文件:描述包的相关信息,以供外部读取分析。
//服务器端
|- package.json 描述文件(必须;放在根目录下;json文件里不能写注释)
|- bin 可执行二进制文件
|- lib js代码
|- doc 文档
|- test 单元测试
//浏览器端
|- js
	|- dist(build) 打包生成文件的目录
	|- src 源码所在的目录
		|- module1.js
		|- module2.js
		|- module3.js
		|- app.js 应用主源文件
|- index.html
|- package.json


//Browserify:编译工具,通过它可以在浏览器环境下像nodejs一样使用遵守commonjs规范的模块化编程。
browserify js/src/app.js -o js/dist/bundle.js
//index.html
<script type="text/javascript" src="./js/dist/bundle"></script>

AMD

Asynchronous Module Definition异步模块定义

  • 模块的加载是异步的。
//浏览器端
//下载require.js,放入项目目录中
|- js
	|- libs
		|- require.js
	|- modules
		|- module1.js
		|- module2.js
	|- main.js
|- index.html


//暴露模块
//1、暴露没有依赖的模块
//module1.js
define(function(){
	let name = 'a';
	function foo(){
		...
	}
	return {foo};
})
//2、暴露有依赖的模块
//module2.js
define(['module1'], function(module1){
	let msg = 'b';
	function showmsg(){
		...
	}
	return {showmsg}});

//引入模块
//main.js
(function(){
	requirejs.config({
		baseUrl: 'js/'
		paths:{
			//默认不加.js
			module1: './modules/module1',
			module2: './modules/module2',
			jquery: './libs/jquery'
		}
	});
	
	requirejs(['module2'], function(module2){
		module2.showmsg();
	});
})();
	
//index.html
<script data-main="js/main.js" src="js/libs/require.js"></script> 

CMD

Common Module Definition通用模块定义

  • 模块的加载是异步的。
//浏览器端
//下载sea.js,放入项目目录中
|- js
	|- libs
		|- sea.js
	|- modules
		|- module1.js
		|- module2.js
		|- main.js
|- index.html


//暴露模块
//1、暴露没有依赖的模块
define(function(require, exports, module){
	//分别暴露
	exports.x = 10;
	//统一暴露
	module.exports = {
		...
	}
});
//2、暴露有依赖的模块
define(function(require, exports, module){
	//引入依赖模块(同步)
	var module2 = require('./module2');
	//引入依赖模块(异步)
	require.async('./module3',function(m3){
		...
	})
	
	//分别暴露
	exports.x = 10;
	//统一暴露
	module.exports = {
		...
	}
});
	


//引入模块
//main.js
define(function(require){
	var m1 = require('./module1');
	m1.show();
});
//index.html
<script type="text/javascript" src="js/libs/sea.js"></script>
<script type="text/javascript">
	seajs.use('./js/modules/main.js');	
</script>

ES6

//浏览器端- js
	|- build
	|- src
		|- main.js
		|- module1.js
		|- module2.js
|- index.html
|- .babelrc
|- package.json
|- package-lock.json

//定义package.json
//安装babel-cli(-g),babel-preset(--save-dev)
//设置.babelrc
//使用babel将ES6转换为ES5(转换后包含commonjs语法):babel js/src -d js/build
//再用Browserfy打包:browserify js/build/main.js -o js/dist/bundle.js
//index.html
<script type="text/javascript" src="./js/dist/bundle"></script>

//export命令:规定模块的对外接口。
//1、分别暴露:直接在要暴露的变量前面加export。
//m1.js
export let s = 's';
export function f(){
	...
}
//2、统一暴露
//m2.js
let s = 's';
function f(){
	...
}
export {s, f};
//3、默认暴露
export default{
	s: 's',
	f: function(){
		...
	}
}


//import命令:输入其他模块提供的功能。
//1、在文件里直接引入
<script type="module">
	//1、通用导入
	import * as m1 from './src/js/m1.js';
	console.log(m1.s);
	import * as m2 from './src/js/m2.js';
	console.log(m2.s);
	import * as m3 from './src/js/m3.js';
	console.log(m3.default.s);
	//2、解构赋值
	import {s, f} from './src/js/m1.js';
	consoel.log(s);
	import {s as s_plus, f as f_plus} from './src/js/m2.js';
	console.log(s_plus);
	import {default as m3} from './src/js/m3.js';
	console.log(m3.s);
	//3、简便:针对默认暴露
	import m3 from "./src/js/m3.js";
	console.log(m3.s);
</script>
//2、利用标签引入:用的ES6,兼容性不佳。
<script src="./src/js/app.js" type="module"></script>
//app.js
	import * as m1 from './src/js/m1.js';
	console.log(m1.s);
	import * as m2 from './src/js/m2.js';
	console.log(m2.s);
	import * as m3 from './src/js/m3.js';
	console.log(m3.default.s);
	//导入npm包语法
	import $ from 'jquery';
//3、babel
<script src="dist/bundle.js"></script>
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值