模块与组件

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

原文地址:https://www.cnblogs.com/yuanzhiguo/p/8318631.html