学习前端模块化方案的一些总结
2016-02-22 21:50
543 查看
今天看了一天的前端的模块化的解决方案,发现如果是初学者会有很多的疑问,网上看了很多文章渐渐才有了头绪。
首先模块化的方案其实一直都用,从我们最基本的函数来说可以说就是一个模块化的过程,可是这个模块化的过程会有很多的弊端,首先就是变量冲突的问题,命名冲突的问题,全局作用域的污染,一旦项目构建的越来越大,会导致我们越来越痛苦,所以出现了很多的解决方案,模块化就是目前比较流行的一种方法,es6出来完全就实现了模块化的工程,可以说模块化是一个优秀的前端人员必须学习的。
模块化的话首先要讲commonJS它是服务器端的node最先采用的一种模块化的规范,学习node的人肯定都明白,我没有深入学习过,所以在这就不多说了。模块话固然是非常好的,但是在浏览器端实现起来确困难重重,首先是因为浏览器的环境中依赖的资源都是通过网络请求过来的,没有服务端的那么稳定,我们在请求资源时,资源可能对应在不同的服务器端配置,所以会出现各种的问题,但是后面出现了一些改进的方案,先不急,先了解以下AMD规范和CMD规范。
在了解之前先来看一张图
看了这幅图之后,相信你会有一个大概的印象,AMD是异步加载模块的缩写,他产生了requireJS这样的定义,CMD他有了seaJS这样的模块加载框架,有一段代码很好的讲了他们两的区别:
requireJS需要在定义之前就要预加载所有需要的模块,而reaJS需要在什么时候使用,什么时候再进行加载,用语言来类比就是一个是静态加载,一个是运行时加载,当然这个比喻不是很恰当,但是有些类似,下面说说在requireJS下定义模块的方式:
AMD其实也就只定义了一个define函数,
这个函数就是定义模块的函数,参数说明:id就是这个模块的名字,也就是模块加载器要进行加载的指定的名字,在另外一个地方看到说也就是这个文件的路径名,第二个参数是当前模块已定义的依赖模块的数组字面量,依赖参数是可选的,如果忽略此参数,默认是
然而如果工厂方法的长度属性小于三,加载器会以函数的长度属性指定的参数属性调用工厂方法。
工厂方法factory是模块初始化要执行的函数或对象,如果为函数,他应该只被执行一次,如果为对象,他应该为模块的输出值,定义模块用define定义用exports导入,下面来看一个例子:
这就是定义一个模块的方法,我们常见的jquery就已经实现自动模块化了,
seaJS是懒加载,那么它是怎么使用的,下面看个例子:
就这样可以使用响应的模块了,当然对于这些规范有一些很深的思考,比如怎么设计一个AMD模块,怎么实现,这些我暂时没有实践过,暂时不说了。
首先模块化的方案其实一直都用,从我们最基本的函数来说可以说就是一个模块化的过程,可是这个模块化的过程会有很多的弊端,首先就是变量冲突的问题,命名冲突的问题,全局作用域的污染,一旦项目构建的越来越大,会导致我们越来越痛苦,所以出现了很多的解决方案,模块化就是目前比较流行的一种方法,es6出来完全就实现了模块化的工程,可以说模块化是一个优秀的前端人员必须学习的。
模块化的话首先要讲commonJS它是服务器端的node最先采用的一种模块化的规范,学习node的人肯定都明白,我没有深入学习过,所以在这就不多说了。模块话固然是非常好的,但是在浏览器端实现起来确困难重重,首先是因为浏览器的环境中依赖的资源都是通过网络请求过来的,没有服务端的那么稳定,我们在请求资源时,资源可能对应在不同的服务器端配置,所以会出现各种的问题,但是后面出现了一些改进的方案,先不急,先了解以下AMD规范和CMD规范。
在了解之前先来看一张图
看了这幅图之后,相信你会有一个大概的印象,AMD是异步加载模块的缩写,他产生了requireJS这样的定义,CMD他有了seaJS这样的模块加载框架,有一段代码很好的讲了他们两的区别:
// CMD define(function(require, exports, module) { var a = require('./a') a.doSomething() // 此处略去 100 行 var b = require('./b') // 依赖可以就近书写 b.doSomething() // ... }) // AMD 默认推荐的是 define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.doSomething() // 此处略去 100 行 b.doSomething() ... })
requireJS需要在定义之前就要预加载所有需要的模块,而reaJS需要在什么时候使用,什么时候再进行加载,用语言来类比就是一个是静态加载,一个是运行时加载,当然这个比喻不是很恰当,但是有些类似,下面说说在requireJS下定义模块的方式:
AMD其实也就只定义了一个define函数,
define(id?, dependencies?, factory);
这个函数就是定义模块的函数,参数说明:id就是这个模块的名字,也就是模块加载器要进行加载的指定的名字,在另外一个地方看到说也就是这个文件的路径名,第二个参数是当前模块已定义的依赖模块的数组字面量,依赖参数是可选的,如果忽略此参数,默认是
["require", "exports", "module"]
然而如果工厂方法的长度属性小于三,加载器会以函数的长度属性指定的参数属性调用工厂方法。
工厂方法factory是模块初始化要执行的函数或对象,如果为函数,他应该只被执行一次,如果为对象,他应该为模块的输出值,定义模块用define定义用exports导入,下面来看一个例子:
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) { exports.verb = function() { return beta.verb(); //Or: return require("beta").verb(); } });
这就是定义一个模块的方法,我们常见的jquery就已经实现自动模块化了,
seajs.config({ 'base':'/', 'alias':{ 'jquery':'jquery.js'//定义jQuery文件 } }); define(function(require, exports, module{ //先要载入jQuery的模块 var $ = require('jquery'); //然后将jQuery对象传给插件模块 require('./cookie')($); //开始使用 $.cookie方法 });
seaJS是懒加载,那么它是怎么使用的,下面看个例子:
- 引入sea.js的库 - 如何变成模块? - define - 3.如何调用模块? -exports -sea.js.use - 4.如何依赖模块? -require <script type="text/javascript"> define(function (require,exports,module) { //exports : 对外的接口 //requires : 依赖的接口 require('./test.js');//如果地址是一个模块的话,那么require的返回值就是模块中的exports }) </script>
就这样可以使用响应的模块了,当然对于这些规范有一些很深的思考,比如怎么设计一个AMD模块,怎么实现,这些我暂时没有实践过,暂时不说了。
相关文章推荐
- 异步流程控制:7 行代码学会 co 模块
- [译] React 入门
- 如何优雅处理前端异常?
- 深入探寻seajs的模块化与加载方式
- 深入探讨前端框架react
- Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(一)
- 自己动手写的javascript前端等待控件
- 前端必备神器 Snap.svg 弹动效果
- JavaScript模块化开发之SeaJS
- JavaScript的模块化:封装(闭包),继承(原型) 介绍
- 一张Web前端的思维导图分享
- 一道常被人轻视的web前端常见面试题(JS)
- 浅谈AngularJS--基础
- 浅谈AngularJS--域变量(scope)
- AngularJS' Internals In Depth(深入理解 AngularJS)
- 3ff8 javascript 获取Flash下载进度兼容IE, FireFox,Chrome浏览器
- CSS清除浮动常用方法小结
- window.external 的用法(收藏夹功能)