commonJS规范、AMD规范、CMD规范、ES6模块化

本文介绍了JavaScript中的模块化规范,包括CommonJS、AMD、CMD和ES6模块化。分别阐述了它们的作用域独立、文件模块化及应用场景。通过实例展示了如何使用这些规范实现模块化,帮助开发者理解并选择合适的模块化方案。
摘要由CSDN通过智能技术生成

这三个规范有什么用:

这三个规范可以帮助你加载各个模块,完成各个模块的作用域独立

那么模块是什么,作用域又是什么?

1、作用域:

作用域指在一个区域内有效的区域。

熟悉javascript的应该知道,javascript是函数级作用域,在函数内可以访问到函数外的变量,而函数外不能访问到函数内的变量,这个就是函数的作用域。

在函数外的变量会变成全局变量。一个比较大的项目需要很多变量命名,很容易就会造成命名冲突。那么该怎么解决呢,我们知道函数内的变量是不被外部访问的,自然也不会造成对命名冲突。那么该怎么使用函数去进行避免命名冲突呢?下面引入我们的模块:

2、模块:

模块具有对外可见,外部不可修改,作用域独立的效果。那么什么是模块呢?

个人理解为一个立即执行的函数,可以是一个匿名函数,并且立即执行。

(function(){
    var name = "张三";
    console.log(name)    // 张三
})()

console.log(name)    // undefined

这样可以成为一个模块,函数内部可以访问到变量,外部则访问不到。不过一般一个标准的模块应该这么用:

var user = (function(){
    var name = "张三";

    // 获取名字
    function getName(){
        return name;
    }
    // 修改名字的方法
    function setName(name){
        name = name;
    }
    // 向外提供的方法
    return {
        getName:getName,
        setName:setName,
    }
})()

console.log(user.getName())    // 张三
user.setName("李四")
console.log(user.getName())    // 李四

这样是不是就可以做到作用域独立,对外提供我想要提供的方法。实现了获取名字,修改的名字的功能。并且不会造成环境的变量污染。

 

commonJs规范:

下面看一个小例子:

创建一个index.js文件:

// index.js

var name = "张旭伟"

在创建一个 index2.js文件:

// index2.js

console.log(name)

创建一个html文件将他们一起引入:

<script type="text/javascript" src="index.js"></script>
<script type="text/javascript" src="index2.js"></script>

执行html文件将会打印出 index.js中定义的变量name。

可以知道在一个html文件中一起引入的 js文件之间是可以互相访问到全局变量的,这显然不符合我们的作用域互相独立的规则。

我们可以使用模块的方式,对各自js文件进行隔离。

// index.js
(function(){
    var name = "张旭伟"
})()
// index2.js

(function(){
    console.log(name)
})()

这样就已经做到了文件之间互相隔离。

commonJS的规范就是每一个文件为一个模块,作用域独立,互相不受影响。

commonJs认为每一个文件为一个模块,通过module.exports输出模块内容,每个模块当前对象都是module,导出的对象为module下的属性exports。通过require命令引入。

下面实践,创建项目结构如下:

module1.js 、module2.js为模块,app.js为入口文件(执行入口)

module1.js

// module1.js

module.exports = function () {
    var name = "这是module1模块";
    console.log("我是module1模块");
    function getName() {
        return name;
    }
    return {
        getName:getName,
    };
}

module2.js

// module2.js

module.exports = function () {
    var name = "这是module2模块";
    console.log("我是module2模块");
    function getName() {
        return name;
    }
    return {
        getName:getName,
    };
}

app.js

// app.js

var module1 = require("./modules/module1.js")
var module2 = require("./modules/module2.js")
console.log(module1().getName())
console.log(module2().getName())

运行app.js

node app.js

得到输出结果,没有问题,这就是commonJs规范。

 

但是这只适合在服务器上使用。

因此,有了下面的AMD规范。

 

AMD规范

AMD规范是为浏览器上运行而推出的,同样也是为了使文件模块化。

AMD规范需要借助require.js去实现

require.js可以帮助我们实现AMD规范,并且将多个文件作为一个在html中共同引入。

1、下载require.js

2、新建一个主文件main.js,并进行如下配置:

// 配置文件
requirejs.config({
    
    baseURI:'js/',  // 加载模块的根路径
    paths:{     // 模块映射,映射需要使用的模块
        "index1":"js/index",    
        "index2":"js/index2"
    }
})

requirejs(["index1","index2"],function (index, index2) {

})

3、define定义模块:

index.js:

define(function () {
    var str = "这是index.js的数据"
    return "这是index.js模块"
})

index2.js:

define(['./module1.js'],function (module1) {    // 此处加载依赖文件
    var str = "这是index2.js的数据"
    return "这是index2.js模块"
})

可以给定义模块返回值。

4、html中引入require.js:

<script data-main="main.js" src="require.js"></script>

data-main: 属性为require.js的配置文件路径,用于找打配置文件。

src: 引入require.js文件。

5、执行html文件,可以看到已经把index.js,index.js也都引入了。并且作用域互补影响。

 

有时候我们还会需要引入第三方插件、库,也可以当做一个模块进行引入。但是有的插件、库没有模块化呢?怎么办。

可以使用require.js中的shim模块,配置如下:

// 配置文件
requirejs.config({

    baseURI:'js/',  // 加载模块的根路径
    paths:{     // 模块映射
        "index1":"js/index",
        "index2":"js/index2"
    },
    shim:{
        "index2":{      // 需要模块化的文件
            deps:[],    // 该插件需要依赖的文件
            exports:"index2"    // 输出名称
        }
    }
})

requirejs(["index1","index2"],function (index, index2) {
    console.log(index)
    console.log(index2)
})

 

CMD规范

CMD规范是commonJS和AMD规范的合体,取自两者的一半,进行修改,成为CMD规范。

CMD规范需要借助sea.js实现。

下面为项目结构。

1、下载sea.js

2、定义模块(文件模块化)

module1.js

// module1.js

define(function (require, exports, module) {
    console.log("我是module1模块");
    module.exports = '这是module1模块';
});

module2.js

define(function (require, exports, module) {
    // let module1 = require("./module1.modules");       // 同步加载依赖文件
    require.async("./module1.modules",function (module1) {       // 异步加载文件
        // 加载完后执行回调
        console.log(module1)    // 打印module1的输出内容
    });
    console.log("我是module2模块");
    module.exports = "这是module2模块";     // 输出自己
});

3、入口文件(执行入口):app.js

define(function (require, exports, module) {
    var module2 = require("./modules/module2.js")
    console.log(module2)
});

4、HTML中引入

引入sea.js

<script type="text/javascript" src="lib/sea.js"></script>

加载入口文件:

<script>
    seajs.use("./app.js")
</script>

5、执行html文件:

 

browserify 

commonJS规范初衷是为服务器端的文件进行模块化。其实commonJs的规范也可以在浏览器上运行,不过需要使用browserify工具去编译。

1、安装 browserify

全局安装

npm install -g browserify

局部安装

npm install --save-dev browserify

2、编译

使用browserify编译main.js文件(入口文件)

browserify main.js -o build.js

这个操作是将main.js配置里面引入的模块一起打包为一个文件,并且命名为build.js

3、html中使用

html中引入build.js,执行html可以得到服务器上运行同样的效果

 

ES6模块化:

javascript吸收了第三方模块化规范的精神,es6开始加入模块化,无需使用第三方规范即可使用模块化。

1、es6暴露模块方式:

第一种:多个对象单独暴露

export function show() {
    console.log('这是module1模块')
}
export function show2() {
    console.log('这是module1模块')
}

第二种:默认暴露(多个对象统一暴露)

function show() {
    console.log('这是module1模块')
}
function show2() {
    console.log('这是module1模块')
}

export default{
    show,
    show2
}

2、引入模块:

第一种:按变量方式引入(解构赋值方式),针对单独暴露

import {show,show2} from "module"

第二种:按模块方式引入,针对统一暴露

import module from "module"

3、浏览器上使用

需要先对模块进行编译

编译可使用browserify工具编译(对入口文件编译即可),browswerify的使用前面有讲到。

在使用browserify编译之前呢,有一个问题,它不认的es6语法,需要对编译的文件进行转换为es5语法,然后再进行编译。

编译完成后即可引入浏览器使用。

了解es6转换为es5可移步:使用 babel 将 ES6 转换为 ES5

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值