1.为什么模块化
1.前端逻辑越来越复杂和庞大
2.按逻辑划分模块和文件,最终有很多小文件
3.小文件之间有依赖关系,需要手动解决
4.发布的时候,需要打包成一个文件,加速下载性能。
需要一个模块化系统
当前的开发现状:
通过定义一个立即执行函数:
(function(){})
来封装模块。
有一个名字叫:module pattern(模块模式)
2.当前的模块化系统
其他语言的模块方案。
c include
java import
css @import
js的模块方案。
开始的时候,js比较简单(很多几十几百行的小文件)没有考虑模块系统。
1.Commonjs
后来commonjs小组制定了一个commonjs规范。
node 就是遵循的这个规范。
这个规范,通过 require来加载依赖。通过 exports来导出模块。
缺点:
cjs运行在node里面,很好。但是前端天生异步,cjs不能很好的运行在前端浏览器。
如果想运行,需要一些处理。后端的或前端的。
例如前端:ajax请求cjs模块,然后,正则匹配模块依赖,解决依赖。增加了前端程序员的工作量。
2.AMD
xhr
ajax获取脚本内容,然后正则查找依赖,然后eval执行脚本。
缺点:
ajax不能跨域
eval尽量少用
可以利用worker 提升性能。
document.write
优点:
可以跨域
缺点:
不能再文档加载完成的时候,调用:这个时候一调用会把文档清空。
另外他会阻塞页面渲染。
head.appendChild
var script = document.createElement('script');
script.src = '地址';
document.head.appendChild(script)
这种方式需要配合函数包装来实现。
define(moduleName,[依赖列表],function(dep){
//参数是依赖列表的值,
//返回的是模块的定义。
return {}
})
AMD的用法
一种是
define(moduleName,[dep1,dep2],function(dep1,dep2){
//参数是依赖列表的值,
//返回的是模块的定义。
return {}
})
这种方式当依赖特别多的时候,参数和依赖的关系很难对应。
另外一种:
define(function(){
var dep1 = require('dep1')
var dep2 = require('dep2')
//返回的是模块的定义。
return {}
})
他有一个名字叫 simpled commonjs(简化的cjs)。
这种方式的依赖搜集是通过 Function.prototype.toString.toString 把函数的定义返回来,然后正则匹配。
3.技术细节点
eval
eval对scope的影响。
非直接调用会影响全局变量。(global.eval,或者是 e = eval,e())
document.write
当文档关闭的时候,
调用 write相当于调用 document.open().document.write();
Function.prototype.toString
可以通过他拿到函数的定义。
4.模块化的方案
commonjs
用在node环境
amd
用在浏览器环境
es6 module
以后的标准。
网友评论