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

前端模块化开发

作者头像
用户1394570
发布2018-08-08 10:11:37
1.2K0
发布2018-08-08 10:11:37
举报
文章被收录于专栏:carvencarven

其实对前端模块化开发的接触时间并不多,很多见解都是别人的,或者是偏的, 还是乐意记录下来,谁让我一天一个念头 说到前端模块化开发,其实是说 javascript 模块化开发。 目前,大众讲到的 javascript模块化规范 有3种,CommonJSAMD(异步模块定义)、CMD(通用模块定义)

CommonJS

CommonJS在 node 端模块采用的规范。 根据CommonJS规范,每一个文件都是一个模块,每一个模块都有一个独立的作用域,文件内的变量都是私有的,其他文件不可使用(除非 赋值到 global上) 每个文件对外的接口是 module.exports 对象。其他文件通过使用这个对象的属性和方法,实现对本文件的使用。

require用于引用其他模块,实际获得的是其他模块的module.exports对象。

例子

example.js

代码语言:javascript
复制
var x = 5;
var addX = function(value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

index.js

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

console.log(example.x); // 5
console.log(example.addX(1)); // 6
CommonJS模块的特点:

所有代码都运行在模块作用域,不会污染全局作用域。 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。 模块加载的顺序,按照其在代码中出现的顺序。

require内部处理流程

require 实际是 指向当前模块的 module.require, module.require 又调用Node的 Module._load(此Module非彼module)

代码语言:javascript
复制
Module._load = function(request, parent, isMain) {
  // 1. 检查 Module._cache,是否缓存之中有指定模块
  // 2. 如果缓存之中没有,就创建一个新的Module实例
  // 3. 将它保存到缓存
  // 4. 使用 module.load() 加载指定的模块文件,
  //    读取文件内容之后,使用 module.compile() 执行文件代码
  // 5. 如果加载/解析过程报错,就从缓存删除该模块
  // 6. 返回该模块的 module.exports
};

其中 module.compile()执行如下:

代码语言:javascript
复制
Module.prototype._compile = function(content, filename) {
  // 1. 生成一个require函数,指向module.require
  // 2. 加载其他辅助方法到require
  // 3. 将文件内容放到一个函数之中,该函数可调用 require
  // 4. 执行该函数
};

这是大概的CommonJS 流程 详见CommonJS规范

AMD(异步模块定义)

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。

CommonJS 采用的是同步加载机制,如果用于 客户端,必定受到网络的限制。所以,CommonJS不 适用于客户端。 而 AMD 采用的是 模块异步加载 方式,在需要执行到模块文件的时候,实现异步加载,回调执行。 看例子:

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

当执行到这一段代码的时候, 浏览器会先 加载 math 模块,在math模块加载成功后, 再执行后面的回调函数 math.add(2,3)

require.js

说道AMD 就不得不提 require.js了。 因为目前要实现 AMD , 不要按照require要求的写法。 首先下载最新require.js ,然后在 html 底部写上如下代码:

代码语言:javascript
复制
<script src="js/require.js" data-main="js/main"></script>

data-main用于指定网页程序的主模块

main.js

代码语言:javascript
复制
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
    // some code here
  });

要加载的模块也必须使用特定的写法,使用define() moduleA.js

代码语言:javascript
复制
define(['moduleD'],function (){
    var add = function (x,y){
      return x+y;
    };
    return {
      add: add
    };
  });

CMD(通用模块定义)

CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。

CMDAMD 在使用方面非常相似。(其实我没用过)

知呼上的比较

对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码: 作者:玉伯 链接:https://www.zhihu.com/question/20351507/answer/14859415 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

代码语言:javascript
复制
// 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()
...
})

就是说, 模块加载完成后, AMD 是立刻执行的,而 CMD是在需要用到的时候才执行的 针对这些不同, 在体现上: AMD 速度会相对快, 但是会浪费资源 CMD 节省资源, 性能会差一点(反应时间)

webpack

react.jswebpack 流行起来。(至少我是通过 react.js 认识到 webpack 的) react.js 可以说是前端(浏览器)项目,可是在编程风格上,确实不折不扣的 CommonJS 风格。 webpack 兼容了 CommonJSAMD

webpack 是一个模块管理工具。 对于 CommonJS 的模块, 对将其 最终打包在一个js文件里面, 对于不写不需要立刻执行的文件,也可以拆分出来,在运行时异步加载。

当然, 这里并不打算 说明怎么使用 webpack , google上有很多丰富的教程。


巨人的肩膀上,加自己的一点感悟

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • CommonJS
    • 例子
      • CommonJS模块的特点:
        • require内部处理流程
        • AMD(异步模块定义)
          • require.js
          • CMD(通用模块定义)
          • webpack
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档