1、模块化中的模块是指Javascript 模块,比如一个用来格式化时间的模块。比如在node.js中的http 模块、fs模块等,并且可以自己建立模块,模块化大致有两种类型“:
源自nodejs的规范CommonJs
CommonJs最开始示威服务端所写的,所以不是异步加载,举一个简单的例子,假如有一个math模块
var math = require(‘math‘); math.add(2,3); // 5
很明显由于js是单线程,并且是依次加载执行的,在math没有加载完成的时候,就会卡在这块出现假死现象,那为什么服务端可以这么写?服务端所有模块都是放在本地硬盘,加载速度非常快。
AMD,异步加载所需的模块,然后在回调函数中执行主逻辑。这正是我们在浏览器端开发所习惯了的方式,其作者亲自实现了符合AMD规范的requirejs,AMD/RequireJs迅速被广大开发者所接受。
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
在RequireJs中同样采用的是require来加载模块,不同的是它具有了回调,实现了异步加载,
require([module], callback);
第一个参数数组是需要加载的模块,后面是它们的回调。
也是上面的例子,在RequireJs中的写法如下图
require([‘math‘], function (math) { math.add(2, 3); });
这就避免了假死现象的发生,那么具体怎么用呢
首先我们下载RequireJs,在网页底部引入RequireJs
<script src="js/require.js" defer async="true" ></script>
加入defer、 async都是为了让其异步加载。
然后就是加载我们自己的代码
<script src="js/require.js" data-main="js/main"></script>
其中data-main="js/main"就是加载main.js,因为是存在于script标签中所以我们简写为main,main.js就是我们主模块,是整个模块加载的一个窗口。
在main.js中我们可以这样写,假定我们加载了jquery、zepto、backbone这三个模块
require([‘jquery‘, ‘zepto‘, ‘backbone‘], function ($,zepto, Backbone){
// some code here
});
这样写明显没有路径,这是因为默认和main.js是在同一级的,如果不在同一级我们可以这样写
require.config({ paths: { "jquery": "js2/jquery.min", "zepto": "lib/zepto.min",
"backbone": "js2/backbone.min"
}
});
这个配置放在main.js的最上面,前面的query这些是可以自定义的,就相当于他们的名字。加载device时候直接加载就可以了。如果所需要的模块都在同一个文件中,我们可以设置baseUrl。如下
require.config({ baseUrl: "js/lib", paths: { "jquery": "jquery.min", "zepto": "zepto.min", "backbone": "backbone.min" } });
接下来就是如何编写模块——基于AMD规范的模块,模块必须采用特定的define()函数来定义。如果一个模块不依赖其他模块,那么可以直接定义在define()函数之中
define(function () { var add=function (x,y) { return x+y; } return{ add:add } })
如果定义的模块依赖于其他模块我们要在其中引入。
define([‘jquery‘],function ($) { var add=function () { return $.test(); } return{ add:add } })
这样在加载该模块的时候就会先加载jquery。
2、组件,组件则包含了 template、style 和 script,而它的 Script 可以由各种模块组成。比如一个显示时间的组件会调用上面的那个格式化时间的模块。比较常见的比如公共的头部,这就是一个组件,我们在使用的时候直接引用就可以了,webpack中vue页面就是组件。
下面是知乎上的一个介绍
组件化和模块化的价值都在于分治,web应用系统的复杂度不断提升,兼顾开发效率和产品实际运行效率,会在开发阶段运用组件化和模块化的手段分离关注点,结合构建工具合理打包。组件化更多关注的是UI部分,你看到的一个管理界面的弹出框,头部,内容区,确认按钮和页脚都可以是个组件,这些组件可以组成一个弹出框组件,跟其他组件组合又是一个新的组件。模块化侧重于功能或者数据的封装,一组相关的组件可以定义成一个模块,一个暴露了通用验证方法的对象可以定义成一个模块,一个全局的json配置文件也可以定义成一个模块。封装隔离来后,更重要的是解决模块间的依赖关系。babel作为现在最火的es6转换器,用babelify或者webpack的babel loader再或者基于task的构建系统插件都可以很方便用起来es6 modules