前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈前端模块化

浅谈前端模块化

作者头像
IMWeb前端团队
发布2019-12-03 18:05:39
5200
发布2019-12-03 18:05:39
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队

本文作者:IMWeb coverguo 原文出处:IMWeb社区 未经同意,禁止转载

  • 模块化编程
  • CommonJS
  • AMD(Asynchronous Module Definition)规范
  • requireJS与seaJS
  • requireJs 以及 seaJs 的区别

模块化编程:

@为了更好的开展话题,首先需了解什么是前端模块化

模块的由来:

其实模块化的诞生不难理解,我们知道因为随着网站逐渐的发展,嵌入网页的Javascript代码越来越庞大,而网页越来越像桌面程序,需要一个团队去分工协作,进行管理和测试等等,为了更好的管理网页的业务逻辑,产生了模块化编程的理念。

模块的定义:

模块就是实现特定功能的相互独立的一组方法。

模块的意义:

因为有了模块,我们能更好的管理网页的业务逻辑,以及按照自己的需求去使用各种模块,并且可以让每个开发者都能设计自己想要的模块以及去使用别人的模块代码。 @有了模块的概念,但为了让大家能方便的加载各种模块,因此需要一套编写模块的规范,而目前通行的Javascript的模板规范共有两种:CommonJS 和 AMD

CommonJS

CommonJS的历史渊源: nodejs项目的诞生,将javascript语言用于服务器编程。由于服务器端开发十分复杂,需要与OS以及其他应用程序互动,模块化的理念对服务器端开发是必需的。而nodejs的模块系统,就是参照CommonJS规范实现的

@因此我理解CommonJS即为服务器端模块的规范。 CommonJS的规范: 根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。下面就是一个简单的模块文件example.js

代码语言:javascript
复制
console.log("example.js");
exports.message = "hi";
exports.say = function (){
    console.log("hello");
};

使用require方法,加载example.js. 这时变量example就对应模块中的exports对象

代码语言:javascript
复制
var example = require('./example.js');

AMD规范

AMD的历史渊源:

CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。

@因此我理解AMD即为能在客户端环境,并且能兼容服务器端模块的一种模块规范。

AMD的模块定义:

AMD规范使用define方法定义模块,下面是一个例子:

代码语言:javascript
复制
define(['package/lib'], function(lib){
    function foo(){
        lib.log('hello world');
    }
    return{
        foo: foo
    };
});

Define第一个参数表达依赖的模块数组,第二个为加载完依赖的模块数组后,模块执行的函数

AMD的模块加载定义:跟CommonJS 一样,AMD也采用require()语句来加载模块,但是与CommonJS不同的是,它要求有两个参数:

require(module, callback);

第一个参数module,是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。AMD形式,就是下面这样:

代码语言:javascript
复制
require(['package/moduleA'], function(moduleA){
    moduleA.add(2, 3);
});

modleA.add()与moduleA模块加载不是同步的,十分适合浏览器的环境

AMD优缺:

AMD 运行时核心思想是「Early Executing」,也就是提前执行依赖 AMD 的这个特性有好有坏:   首先,尽早执行依赖可以尽早发现错误。上面的代码中,假如 a 模块中抛异常,那么 main.js 在调用 factory 方法之前一定会收到错误,factory 不会执行;如果按需执行依赖,结果是:   1、没有进入使用 a 模块的分支时,不会发生错误;   2、出错时,main.js 的 factory 方法很可能执行了一半。      另外,尽早执行依赖通常可以带来更好的用户体验,也容易产生浪费。例如模块 a 依赖了另外一个需要异步加载数据的模块 b,尽早执行 b 可以让等待时间更短,同时如果 b 最后没被用到,带宽和内存开销就浪费了;这种场景下,按需执行依赖可以避免浪费,但是带来更长的等待时间。    引用AMD的Javscript库: 目前,主要有两个Javascript库实现了AMD规范:require.js和curl.js

RequireJS与SeaJS

@根据诞生的时间,先有了Requirejs,然后再诞生了SeaJS。但其实requirejs 和 seajs其实都是模块加载器,只是遵循的模块规范不同,加载机制有所不同。

@在讲解之前,我先说明下模块加载器出现之前存在的两个问题:

  • 最早的时候,所有Javascript代码都写在一个文件里面,只要加载这一个文件就够了。后来,由于代码越来越多,一个文件很难管理并进行维护,必须分成多个文件,依次加载。而一次加载多个js文件有很大的弊端---加载的时候,浏览器会停止网页的渲染,加载文件越多,而网页失去响应的时间就会越长。
  • 由于出现了模块的定义,许多js文件之间存在着依赖关系,因此必须严格保证加载的顺序(即依赖性最大的一定要放到最后加载)

由此可以看出模块加载器的作用,主要是为了解决两个问题: 实现js文件的异步加载,避免网页失去响应 管理模块之间的依赖性,便于代码的编写和维护

RequireJS 与 SeaJS 的异同:

@异同摘录知乎大神的讲法,感觉比较具体和准确 相同之处:   RequireJS 和 SeaJS 都是模块加载器,倡导的是一种模块化开发理念,核心价值是让 JavaScript的模块化开发变得更简单自然。 不同之处:

  • 定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。SeaJS 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 服务器端。
  • 遵循的规范不同。RequireJS 遵循的是 AMD(异步模块定义)规范,SeaJS 遵循的是 CMD (通用模块定义)规范。规范的不同,导致了两者 API 的不同。SeaJS 更简洁优雅,更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
  • 社区理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。SeaJS 不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
  • 代码质量有差异。RequireJS 是没有明显的 bug,SeaJS 是明显没有 bug。
  • 对调试等的支持有差异。SeaJS 通过插件,可以实现 Fiddler 中自动映射的功能,还可以实现自动 combo 等功能,非常方便。RequireJS 无这方面的支持。

总结:

前端模块化的诞生,大大促进我们前端的发展。前端模块化是web前端需掌握的基础知识之一。

参考:

http://www.douban.com/note/283566440/

http://wiki.commonjs.org/wiki/Modules/1.1

http://seajs.org/docs/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2015-07-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模块化编程:
    • 模块的由来:
      • 模块的定义:
        • 模块的意义:
        • CommonJS
        • AMD规范
          • AMD的历史渊源:
            • AMD的模块定义:
              • AMD优缺:
              • RequireJS与SeaJS
              • RequireJS 与 SeaJS 的异同:
              • 总结:
              • 参考:
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档