目录
CommonJS
基本写法
规范
AMD
基本用法
其他
CDM
UMD
ES6 module
export命令
import命令
export default命令
首页 web前端 js教程 为什么需要模块化?js中常用模块化方案介绍

为什么需要模块化?js中常用模块化方案介绍

Oct 26, 2018 pm 03:20 PM
es6 javascript 模块化

本篇文章给大家带来的内容是关于为什么需要模块化?js中常用模块化方案介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

为什么需要模块化

在ES6出现之前,JS语言本身并没有提供模块化能力,这为开发带来了一些问题,其中最重要的两个问题应当是全局污染和依赖管理混乱。

// file a.js
var name = 'aaa';
var sayName = function() {
    console.log(name);
};
登录后复制
<!-- file index.html -->
<script src=&#39;xxx/xxx/a.js&#39;></script>

<script>
    sayName(); // 'aaa'
    
    // code...
    
    var name = 'bbb';
    
    sayName(); // 'bbb'
</script>
登录后复制

上面的代码中,我们两次调用a.js所提供的sayName函数输出了不同结果,很明显这是因为两个文件都对变量name进行了赋值,因此相互之间造成了影响。当然我们可以在编写代码时注意不要定义已存在的变量名,但是当一个页面引用了10几个几百行的文件时,记住所有已经定义过的变量显然不太现实。

// file a.js
var name = getName();
var sayName = function() {
    console.log(name)
};
登录后复制
// file b.js
var getName = function() {
    return 'timo';
};
登录后复制
<script src=&#39;xxx/xxx/b.js&#39;></script>
<script src=&#39;xxx/xxx/a.js&#39;></script>

<script>
    sayName(); // 'timo'
</script>
登录后复制
<script src=&#39;xxx/xxx/a.js&#39;></script>
<script src=&#39;xxx/xxx/b.js&#39;></script>

// Uncaught ReferenceError: getName is not defined
登录后复制

上面的代码说明,多个文件有依赖关系时,我们需要确保其引入的顺序,从而保证运行某个文件时,其依赖已经提前加载,可以想象,面对越大型的项目,我们需要处理的依赖关系也就越多,这既麻烦又容易出错。

而为了解决这些,社区中出现了许多为JS语言提供模块化能力的规范,借助这些规范,能让我们的开发更加方便安全。

常见模块化方案

CommonJS

CommonJS是由社区提出的模块化方案中的一种,Node.js遵循了这套方案。

基本写法

// file a.js
var obj = {
    sayHi: function() {
        console.log('I am timo');
    };
};

module.exports obj;
登录后复制
// file b.js
var Obj = require('xxx/xxx/a.js');

Obj.sayHi(); // 'I am timo'
登录后复制

上面的代码中,文件a.js是模块的提供方,文件b.js是模块调用方。

规范

  1. 每个文件都是一个模块;

  2. 在模块内提供module对象,表示当前模块;

  3. 模块使用exports对外暴露自身的函数/对象/变量等;

  4. 模块内通过require()方法导入其他模块;

CommonJS的规范,简单来说就是上面4条,可以对照基本写法中的例子理解一下,在实际实现中,Node.js虽然遵循CommonJS规范,但是仍然对其进行了一些调整。

AMD

AMD是模块化规范中的一种,RequireJS遵循了这套规范。

基本用法

 // file a.js
 define('module', ['m', './xxx/n.js'], function() {
    // code...
 })
登录后复制

上面的代码中,文件a.js向外导出了模块;

规范

AMD中,暴露模块使用define函数

define(moduleName, [], callback);
登录后复制

如上面代码,define函数共有三个参数

  • moduleName该参数可以省略,表示该模块的名字,一般作用不大

  • ['name1', 'name2'],第二个参数是一个数组,表示当前模块依赖的其他模块,如果没有依赖模块,该参数可以省略

  • callback,第三个参数是必传参数,是一个回调函数,内部是当前模块的相关代码

其他

ADM的特点是依赖前置,这是ADM规范与接下来要介绍的CMD规范最大的不同,依赖前置是指:在运行当前加载模块回调前,会首先将所有依赖包加载完毕,也是就是define函数的第二个参数中指定的依赖包。

CDM

基本写法

 define(function(require, exports, module) {   
    var a = require('./a')  
    a.doSomething();
    // code... 
    var b = require('./b') 
    // code...
})
登录后复制

上面代码是CMD规范导出模块的基本写法;

规范

从写法可以看出,CMD的写法和AMD非常像,其主要区别是对于依赖加载时机的不同,上面已经说过,AMD是依赖前置,而CMD规范推崇就近原则,简单说就是在模块运行前并不加载依赖,模块运行过程中,当需要某个依赖时,再去进行加载。

UMD

CommonJS、AMD、CMD并行的状态下,就需要一种方案能够兼容他们,这样我们在开发时,就不需要再去考虑依赖模块所遵循的规范了,而UMD的出现就是为了解决这个问题。

基本写法

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        //AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        //Node, CommonJS之类的
        module.exports = factory(require('jquery'));
    } else {
        //浏览器全局变量(root 即 window)
        root.returnExports = factory(root.jQuery);
    }
}(this, function ($) {
    //方法
    function myFunc(){};
    //暴露公共方法
    return myFunc;
}));
登录后复制

上面的代码是UMD的基本写法,从代码就可以看出,其能够同时支持CommonJS规范和AMD规范。

ES6 module

上面分别介绍了CommonJS、AMD、CMD和UMD,他们都是社区对于JS实现模块化的贡献,这个规范其产生的根本原因,都是JS语言自身没有模块化能力,而目前,在JS最新的语言规范ES6中,已经为JS增加了模块化能力,而JS自身的模块化方案,完全能够替代目前社区提出的各类规范,且能够做到浏览器端和Node端通用。

ES6中的模块化能力由两个命令构成:exportimportexport命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

export命令

ES6中一个文件就是一个模块,模块内部的变量/函数等外部是无法访问的,如果希望将内部的函数/变量等对外暴露,供其他模块进行使用,就需要通过export命令进行导出

// file a.js
export let a = 1;
export let b = 2;
export let c = 3;
登录后复制
// file b.js
let a = 1;
let b = 2;
let c = 3;

export {a, b, c}
登录后复制
// file c.js
export let add = (a, b) => {
    return a + b;
};
登录后复制

上面三个文件的代码,都是通过export命令导出模块内容的示例,其中a.js文件和b.js文件都是导出模块中的变量,作用完全一致但写法不同,一般我们更推荐b.js文件中的写法,原因是这种写法能够在文件最底部清楚地知道当前模块都导出了哪些变量。

import命令

模块通过export命令导出变量/函数等,是为了让其他模块能够导入去使用,在ES6中,文件导入其他模块是通过import命令进行的

// file d.js
import {a, b, c} from './a.js';
登录后复制

上面的代码中,我们引入了a.js文件中的变量a、b、c,import在引入其他模块内的函数/变量时,必须与原模块所暴露出来的函数名/变量名一一对应。
同时,import命令引入的值是只读的,如果尝试对其进行修改,则会报错

import {a} d from './a.js';
a = 2; // Syntax Error : 'a' is read-only;
登录后复制

export default命令

从上面import的介绍可以看到,当需要引入其他模块时,需要知道此模块暴露出的变量名/函数名才可以,这显然有些麻烦,因此ES6还提供了一个import default命令

// file a.js

let add = (a, b) => {
    return a+b
};
export default add;
登录后复制
// file b.js
import Add from './a.js';

Add(1, 2); // 3
登录后复制

上面的代码中,a.js通过export default命令导出了add函数,在b.js文件中引入时,可以随意指定其名称

export default命令是默认导出的意思,既然是默认导出,显然只能有一个,因此每个模块只能执行一次export default命令,其本质是导出了一个名为default的变量或函数。

以上是为什么需要模块化?js中常用模块化方案介绍的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

如何使用WebSocket和JavaScript实现在线语音识别系统 如何使用WebSocket和JavaScript实现在线语音识别系统 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript实现在线语音识别系统引言:随着科技的不断发展,语音识别技术已经成为了人工智能领域的重要组成部分。而基于WebSocket和JavaScript实现的在线语音识别系统,具备了低延迟、实时性和跨平台的特点,成为了一种被广泛应用的解决方案。本文将介绍如何使用WebSocket和JavaScript来实现在线语音识别系

WebSocket与JavaScript:实现实时监控系统的关键技术 WebSocket与JavaScript:实现实时监控系统的关键技术 Dec 17, 2023 pm 05:30 PM

WebSocket与JavaScript:实现实时监控系统的关键技术引言:随着互联网技术的快速发展,实时监控系统在各个领域中得到了广泛的应用。而实现实时监控的关键技术之一就是WebSocket与JavaScript的结合使用。本文将介绍WebSocket与JavaScript在实时监控系统中的应用,并给出代码示例,详细解释其实现原理。一、WebSocket技

如何利用JavaScript和WebSocket实现实时在线点餐系统 如何利用JavaScript和WebSocket实现实时在线点餐系统 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket实现实时在线点餐系统介绍:随着互联网的普及和技术的进步,越来越多的餐厅开始提供在线点餐服务。为了实现实时在线点餐系统,我们可以利用JavaScript和WebSocket技术。WebSocket是一种基于TCP协议的全双工通信协议,可以实现客户端与服务器的实时双向通信。在实时在线点餐系统中,当用户选择菜品并下单

如何使用WebSocket和JavaScript实现在线预约系统 如何使用WebSocket和JavaScript实现在线预约系统 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript实现在线预约系统在当今数字化的时代,越来越多的业务和服务都需要提供在线预约功能。而实现一个高效、实时的在线预约系统是至关重要的。本文将介绍如何使用WebSocket和JavaScript来实现一个在线预约系统,并提供具体的代码示例。一、什么是WebSocketWebSocket是一种在单个TCP连接上进行全双工

JavaScript和WebSocket:打造高效的实时天气预报系统 JavaScript和WebSocket:打造高效的实时天气预报系统 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的实时天气预报系统引言:如今,天气预报的准确性对于日常生活以及决策制定具有重要意义。随着技术的发展,我们可以通过实时获取天气数据来提供更准确可靠的天气预报。在本文中,我们将学习如何使用JavaScript和WebSocket技术,来构建一个高效的实时天气预报系统。本文将通过具体的代码示例来展示实现的过程。We

简易JavaScript教程:获取HTTP状态码的方法 简易JavaScript教程:获取HTTP状态码的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教程:如何获取HTTP状态码,需要具体代码示例前言:在Web开发中,经常会涉及到与服务器进行数据交互的场景。在与服务器进行通信时,我们经常需要获取返回的HTTP状态码来判断操作是否成功,根据不同的状态码来进行相应的处理。本篇文章将教你如何使用JavaScript获取HTTP状态码,并提供一些实用的代码示例。使用XMLHttpRequest

javascript中如何使用insertBefore javascript中如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用于在DOM树中插入一个新的节点。这个方法需要两个参数:要插入的新节点和参考节点(即新节点将要被插入的位置的节点)。

JavaScript和WebSocket:打造高效的实时图像处理系统 JavaScript和WebSocket:打造高效的实时图像处理系统 Dec 17, 2023 am 08:41 AM

JavaScript是一种广泛应用于Web开发的编程语言,而WebSocket则是一种用于实时通信的网络协议。结合二者的强大功能,我们可以打造一个高效的实时图像处理系统。本文将介绍如何利用JavaScript和WebSocket来实现这个系统,并提供具体的代码示例。首先,我们需要明确实时图像处理系统的需求和目标。假设我们有一个摄像头设备,可以采集实时的图像数

See all articles