js模块化历程
无模块时代
if(xx){
//.......
}
else{
//xxxxxxxxxxx
}
for(var i=0; i<10; i++){
//........
}
element.onclick = function(){
//.......
}
模块萌芽时代
<script type="text/javascript" src="a.js"></script>
<script type="text/javascript" src="b.js"></script>
modA = function(){
var a,b; //变量a、b外部不可见
return {
add : function(c){
a + b + c;
},
format: function(){
//......
}
}
}()
app.util.modA = xxx;
app.tools.modA = xxx;
app.tools.modA.format = xxx;
app.tools.modA.format();
(function(window){
//代码
window.jQuery = window.$ = jQuery;//通过给window添加属性而暴漏到全局
})(window);
模块化面临什么问题
源自nodejs的规范CommonJs
1. 模块的标识应遵循的规则(书写规范)2. 定义全局函数require,通过传入模块标识来引入其他模块,执行的结果即为别的模块暴漏出来的API3. 如果被require函数引入的模块中也包含依赖,那么依次加载这些依赖4. 如果引入模块失败,那么require函数应该报一个异常5. 模块通过变量exports来向往暴漏API,exports只能是一个对象,暴漏的API须作为此对象的属性。
//math.js
exports.add = function() {
var sum = 0, i = 0, args = arguments, l = args.length;
while (i < l) {
sum += args[i++];
}
return sum;
};
//increment.js
var add = require('math').add;
exports.increment = function(val) {
return add(val, 1);
};
//program.js
var inc = require('increment').increment;
var a = 1;
inc(a); //
服务端向前端进军
1. 全局有一个module变量,用来定义模块2. 通过module.declare方法来定义一个模块3. module.declare方法只接收一个参数,那就是模块的factory,次factory可以是函数也可以是对象,如果是对象,那么模块输出就是此对象。4. 模块的factory函数传入三个参数:require,exports,module,用来引入其他依赖和导出本模块API5. 如果factory函数最后明确写有return数据(js函数中不写return默认返回undefined),那么return的内容即为模块的输出。
//可以使用exprots来对外暴漏API
module.declare(function(require, exports, module)
{
exports.foo = "bar";
});
//也可以直接return来对外暴漏数据
module.declare(function(require)
{
return { foo: "bar" };
});
AMD/RequireJs的崛起与妥协
1. 用全局函数define来定义模块,用法为:define(id?, dependencies?, factory);2. id为模块标识,遵从CommonJS Module Identifiers规范3. dependencies为依赖的模块数组,在factory中需传入形参与之一一对应4. 如果dependencies的值中有"require"、"exports"或"module",则与commonjs中的实现保持一致5. 如果dependencies省略不写,则默认为["require", "exports", "module"],factory中也会默认传入require,exports,module6. 如果factory为函数,模块对外暴漏API的方法有三种:return任意类型的数据、exports.xxx=xxx、module.exports=xxx7. 如果factory为对象,则该对象即为模块的返回值
//a.js
define(function(){
console.log('a.js执行');
return {
hello: function(){
console.log('hello, a.js');
}
}
});
//b.js
define(function(){
console.log('b.js执行');
return {
hello: function(){
console.log('hello, b.js');
}
}
});
//main.js
require(['a', 'b'], function(a, b){
console.log('main.js执行');
a.hello();
$('#b').click(function(){
b.hello();
});
})
b.js执行
main.js执行
hello, a.js
define(['a', 'b', 'c', 'd', 'e', 'f', 'g'], function(a, b, c, d, e, f, g){ ..... })
define(function(){
console.log('main2.js执行');
require(['a'], function(a){
a.hello();
});
$('#b').click(function(){
require(['b'], function(b){
b.hello();
});
});
});
a.js执行
hello, a.js
var a = require('a');
a.hello();
$('#b').click(function(){
var b = require('b');
b.hello();
});
//d.js
define(function(require, exports, module){
console.log('d.js执行');
return {
helloA: function(){
var a = require('a');
a.hello();
},
run: function(){
$('#b').click(function(){
var b = require('b');
b.hello();
});
}
}
});
require(['d'], function(d){
});
b.js执行
d.js执行
兼容并包的CMD/seajs
//a.js
define(function(require, exports, module){
console.log('a.js执行');
return {
hello: function(){
console.log('hello, a.js');
}
}
});
//b.js
define(function(require, exports, module){
console.log('b.js执行');
return {
hello: function(){
console.log('hello, b.js');
}
}
});
//main.js
define(function(require, exports, module){
console.log('main.js执行'); var a = require('a');
a.hello(); $('#b').click(function(){
var b = require('b');
b.hello();
}); });
a.js执行
hello, a.js
hello, b.js
var b = require.async('b');
b.hello();
面向未来的ES6模块标准
//方式一, a.js
export var a = 1;
export var obj = {name: 'abc', age: 20};
export function run(){....}
//方式二, b.js
var a = 1;
var obj = {name: 'abc', age: 20};
function run(){....}
export {a, obj, run}
import {run as go} from 'a'
run()
module foo from 'a'
console.log(foo.obj);
a.run();
js模块化历程的更多相关文章
- js 模块化历程
作者:吕大豹 网址:http://www.cnblogs.com/lvdabao/p/js-modules-develop.html 这是一篇关于js模块化历程的长长的流水账,记录js模块化思想的诞生 ...
- JavaScript 模块化历程
这是一篇关于js模块化历程的长长的流水账,记录js模块化思想的诞生与变迁,展望ES6模块化标准的未来.经历过这段历史的人或许会感到沧桑,没经历过的人也应该知道这段历史. 无模块时代 在ajax还未提出 ...
- 面试指南」JS 模块化、组件化、工程化相关的 15 道面试题
JS 模块化.组件化.工程化相关的 15 道面试题 1.什么是模块化? 2.简述模块化的发展历程? 3.AMD.CMD.CommonJS 与 ES6 模块化的区别? 4.它们是如何使用的? 5.exp ...
- JS模块化开发:使用SeaJs高效构建页面
一.扯淡部分 很久很久以前,也就是刚开始接触前端的那会儿,脑袋里压根没有什么架构.重构.性能这些概念,天真地以为前端===好看的页面,甚至把js都划分到除了用来写一些美美的特效别无它用的阴暗角落里,就 ...
- 从273二手车的M站点初探js模块化编程
前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...
- ReactJS webpack实现JS模块化使用的坑
从一个原生HTML/CSS/JS模式的网页改造到ReactJS模块化的结构,需要以下步骤: (1)引用ReactJS框架 ->(2)使用webpack 工具 -> (3)配置webpack ...
- JS 模块化和打包方案收集
1.这里想讨论的是拆分规则,不是在问哪个工具怎么使用.2.这里没有在想找正确答案,因为感觉这个问题要结合具体业务场景. 随着项目开发越来越大,一开始代码全打包到一个文件的方式,让文件越来越大,接下来要 ...
- 闲聊——浅谈前端js模块化演变
function时代 前端这几年发展太快了,我学习的速度都跟不上演变的速度了(门派太多了,后台都是大牛公司支撑类似于facebook的react.google的angular,angular的1.0还 ...
- js 模块化的一些理解和es6模块化学习
模块化 1 IIFE 2 commonjs 3 浏览器中js的模块化 4 简单理解模块加载器的原理 5 es6 之前在参加百度前端技术学院做的小题目的时候,自己写模块的时候 都是写成立即调用表达式( ...
随机推荐
- Nginx - Windows下作为服务启动
Nginx官方没有提供作为服务启动nginx的方案.以服务启动nginx依赖于winsw,当前最新版是1.19. 参考:https://segmentfault.com/a/1190000006807 ...
- [转]在Eclipse中使用JUnit4进行单元测试(初级篇)
首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的快感! 首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除 ...
- sping注解
1.@Autowired(已不推荐使用) 按类型装配,如果匹配不到或者匹配到多个则抛BeanCreationException异常.如果是多个时可以用@Qualifier指定来解决 eg. @Auto ...
- git 开发merge rebase 记录
git status git lg git add src/ git commit -m "restful api and portal" //先commit到自己的本地branc ...
- C++-Qt【1】-退出程序&静态调试
目前还没有发现很好的调试qt代码的方法,权且记录一下: #include "mainwindow.h" #include "ui_mainwindow.h" # ...
- 20161023 NOIP 模拟赛 T1 解题报告
Task 1.纸盒子 (box.pas/box.c/box.cpp) [题目描述] Mcx是一个有轻度洁癖的小朋友.有一天,当他沉溺于数学卷子难以自拔的时候,恍惚间想起在自己当初学习概率的时候准备的一 ...
- Junit测试框架 Tips
关于Junit测试框架使用的几点总结: 1.Junit中的测试注解: @Test →每个测试方法前都需要添加该注解,这样才能使你的测试方法交给Junit去执行. @Before →在每个测试方法执行前 ...
- Vim 插入递增列
<C-a> ++1 <C-x> --1 安装Plugin 'terryma/vim-multiple-cursors'后 <C-v> 选所有数字 <C ...
- 第三周作业(一):安装VS以及创建单元测试
安装的时候找的是最新版本的VS2015,因为不想花钱也不想用破解版,所以用社区版本. 下了一个IOS文件,社区版VS2015,个人免费版,强行表示不用盗版来表现自己高尚的情操:D 放入虚拟光驱软件后, ...
- block 从B界面向A界面传值
最近在改公司外包项目的代码,发现了一种block传值的用法很有意思,记录一下 A.B两个页面 在B界面.h中定义 @property (nonatomic,strong) void(^block)(N ...