JS 模块化规范

来源:互联网 发布:形状与抗弯曲能力数据 编辑:程序博客网 时间:2024/06/06 09:16

在我们最初写代码的时候,引入JS文件用script标签来引入,并且在引入多个JS文件时,当前文件所依赖的JS文件必须放在前面。也就存在一个顺序的问题,而且这是由开发者去判断和把控的。而现在前端项目越来越复杂,难免会出现很多很多script标签引入JS,这无论对于开发和维护都有着一定的缺点。所以出现了模块化的概念。

模块化的形式有很多中,比如把某个特定功能封装成一个函数,但是存在着一个问题,很有可能会出现命名冲突等问题。针对这种问题,又有了对象的方式来模块化,这种不会出现命名冲突,但是外界却可以改变对象内的成员。又有了下面这种方式:

var obj = (function(){    var name = 'liu';    var job = 'Web developer';    function sayName() {        console.log(name + ' is a ' + job);    }    return {        sayName: sayName    }})()

这样外界就不会修改没有暴露出来的对象内的变量。
上面这些是前端模块化的基础。目前通用的模块化规范主要有COMMONJSAMDCMD等等。

COMMONJS

COMMONJS主要是用于服务端的模块化规范,可以说NodeJS是它的最佳实践。看下面一个例子:

//导入一个文件系统模块,返回的是一个对象;var fs = require('fs');//调用对象的readFile方法,读文件。fs.readFile('test.txt', function(data){    console.log(data);});

上面是一个读文件的操作,主要引入文件系统模块,这个是一个同步的过程。

当然,也可以自定义一个模块实现特定的功能。比如要实现一个Multi模块,可以这样来实现:

//multi.jsfunction multi(a ,b) {    return a*b;}module.exports = {    multi: multi}
//moduleTest.jsvar obj = require('./multi.js');var res = obj.multi(3, 4);console.log(res);

结果如下:
这里写图片描述

AMD

上面的COMMONJS规范不适合浏览器端的模块化开发,因为COMMONJS去请求模块是一个同步的过程,如果浏览器用这种规范去开发很可能会出现阻塞情况/假死情况。因此AMD规范就是为解决这种情况而出现的。
由于不是原生JS所支持的,所以AMD规范需要用到RequireJS库。
AMD的用法如下:
定义模块: define([依赖的模块], function(){ //自定义模块 });
引入模块:require([依赖的模块], function(){ //回调 })

在这里,需要说明的一点是:RequireJS是依赖前置,先去执行依赖的模块,然后再执行当前模块。

CMD

CMD典型的就是SeaJSSeaJSRequireJS实现上是差不多的,但是还是有一些区别,主要是在定义方式上和模块的执行时机上。
定义模块: define(function( require, exports, module ){ })
可以看到,SeaJS在定义模块的时候,并不会像RequireJS那样依赖前置,而是就近依赖的原则,需要的时候再去requireSeaJS主要是对模块先加载不执行,等到遇到require的时候才会去执行模块。
对于RequireJSSeaJS的差异可以看下面这个例子:

//c.jsdefine(function(require, exports, module){    console.log('c Module');    require('./b.js');    console.log('c module finished');})
//b.jsdefine(function(require, exports, module){    console.log('b Module');    require('./a.js');    console.log('b module finished');})
//a.jsdefine(function(require, exports, module){    console.log('a Module');})
//html文件//requirejs文件部分代码<script src="require.min.js" data-main="c.js"></script>  //SeaJs文件部分代码<script src="Sea.js"></script><script>seajs.use('./c');  </script>  

大家可以猜猜两种执行结果有什么不同,这里就不做验证了。

上面这些就是JS模块化的通用方法总结,当然,ES6中已经有了Module模块化的概念,后面还会再对这个进行整理。

原创粉丝点击