在前端开发中,在使用 webpack
等构建工具开发中我们经常使用 import * from
或者是require
来引入我们需要的模块,那么下面来聊聊前端模块化几种规范。
为什么需要模块化
在早期我们写 js 代码通常是这样子:
var a=1;
var b=1;
function a(){}
function b(){}
这样子会造成命名冲突和全局污染。
同时当我们在同一个页面请求过多的 js 文件时会造成页面阻塞和 http 请求过多。
模块化规范
由于上面的种种缺点,这时候模块化显得非常重要,前期的模块化通过闭包来达到变量私有化和模块化。
var module=(function(){
var a = 1;
var b = function(){}
return {b:b}
})()
但是这样子还是不能解决加载问题。这时 js 模块加载器诞生了,并逐渐形成几种模块化规范。
CommonJS 规范
CommonJS 简介
CommonJS
规范是在 node 的模块系统基础上提出来的,也就是 CommonJS
在服务器中使用,不能在浏览器环境中使用。
CommonJS
规范规定,每个模块内部,module
变量代表当前模块(一个 js 文件就是一个模块)。这个变量是一个对象,它的 exports
属性(即 module.exports
)是对外的接口。加载某个模块,其实是加载该模块的module.exports
属性。
CommonJS 代码书写
var a = 1;
var b = function (){}
module.exports.a = a;
module.exports.b = b;
上面代码通过 module.exports
输出变量 a
和函数b
。
require 方法引入
var main = require('./main')
main.a
main.b
其实这些代码在我们使用 webpack 配置的时候经常用到,webpack 是运行在 node 环境中的,他使用的是 CommonJS 规范。
CommonJS 规范特点
- 所有模块都是运行在模块作用域,不会污染全局
- 模块多次运行,只执行一次,然后缓存起来,要让模块重新执行只能清缓存
- 他是按照引入的顺序执行的,也是就是同步执行
ADM
ADM 简介
上面说了 CommonJS 的执行是同步进行的,而且浏览器环境中没有 CommonJS 模块中的必要的字段,所以他不适合浏览器环境,这时候 requirejs
应势而生,它的诞生逐渐形成了 ADM
规范。
ADM 规范中规定所有模块和依懒项异步加载,这样子 js 文件就不是一次性引入了。
ADM 模块代码书写
我们说 ADM
规范主要使用requirejs
。
//a.js
define([jquery.js],function($){
var aa = 1
return{a:aa}
})
//b.js
define([jquery.js],function($){
var bb = 2;
return {b:bb}
})
上面文件 a.js
和b.js
通过 define
方法定义各自的模块。
通过 require
方法引入:
require([a.js,b.js],function(a,b){console.log(a.aa) //1
console.log(b.bb)//2
})
ADM 规范模块特点
- 按需加载,也就是说你引入模块才加载,不会在页面上一次性加载
- 异步加载,所有加载都是异步,不会阻塞页面
CDM
CDM 介绍
在 seajs
出现后又形成了 CDM
规范,CDM 规范和 ADM 类似,都是为了适应浏览器,但是 CDM 推崇就近依赖,ADM 推崇依赖前置。
CDM 模块代码书写
define(function(require,exports,module){var $ = require(jquery.js)
exports.sayHello = function() {$('#hello').toggle('slow');
};
})
CDM 规范中模块代码书写和 CommonJS 相似,其实 ADM 规范中也可以这样子引用模块。具体可以看 seajs 使用文档和 requirejs 使用文档
CDM 和 ADM 规范
CDM 规范和 ADM 规范是类似的,都是异步按需引入。
但是他们执行的时机不同。
CDM 是加载模块后立刻执行,也就是提前执行,
而 ADM 是加载模块后遇到 require 方法才执行模块,也就是延迟执行,可以参考这篇文章中的几个列子。
ES6 模块化规范
在前面几个模块化规范发展中,逐渐形成了 ES6 规范,也是我们在项目中用的最多的了,也是我们最熟悉的模块化规范了,这里就不展开说了。
参考:
https://blog.csdn.net/weixin_40969472/article/details/78646003
http://www.360doc.com/content/19/0519/15/13328254_836725029.shtml
http://www.ruanyifeng.com/blog/2015/05/commonjs-in-browser.html
http://huangxuan.me/js-module-7day/#/15
https://github.com/seajs/seajs/issues/547