0

0

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

不言

不言

发布时间:2018-10-26 15:20:29

|

2739人浏览过

|

来源于segmentfault

转载

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

为什么需要模块化

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

// file a.js
var name = 'aaa';
var sayName = function() {
    console.log(name);
};



上面的代码中,我们两次调用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';
};






// 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该参数可以省略,表示该模块的名字,一般作用不大

    千博企业网站管理系统标准版2013 Build0206
    千博企业网站管理系统标准版2013 Build0206

    系统简介 千博企业建站系统是根据企业客户实际应用需求而提供的一套完整的中小企业网站应用解决方案,协助企业对公司产品进行更深层次的展示、推广。 千博企业建站系统主要面向企业进行产品展示、推广、企业形象展示而设计研发,系统界面简洁大方,管理操作非常简易,可高效构建企业、行业、律师、医院、政府信息门户网站、内部知识网站、信息门户等平台,并内置了专业的内容管理功能模块,可为浏览网站的顾客提供全方位的导购服

    下载
  • ['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的变量或函数。

相关专题

更多
Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

公务员递补名单公布时间 公务员递补要求
公务员递补名单公布时间 公务员递补要求

公务员递补名单公布时间不固定,通常在面试前,由招录单位(如国家知识产权局、海关等)发布,依据是原入围考生放弃资格,会按笔试成绩从高到低递补,递补考生需按公告要求限时确认并提交材料,及时参加面试/体检等后续环节。要求核心是按招录单位公告及时响应、提交材料(确认书、资格复审材料)并准时参加面试。

44

2026.01.15

公务员调剂条件 2026调剂公告时间
公务员调剂条件 2026调剂公告时间

(一)符合拟调剂职位所要求的资格条件。 (二)公共科目笔试成绩同时达到拟调剂职位和原报考职位的合格分数线,且考试类别相同。 拟调剂职位设置了专业科目笔试条件的,专业科目笔试成绩还须同时达到合格分数线,且考试类别相同。 (三)未进入原报考职位面试人员名单。

58

2026.01.15

国考成绩查询入口 国考分数公布时间2026
国考成绩查询入口 国考分数公布时间2026

笔试成绩查询入口已开通,考生可登录国家公务员局中央机关及其直属机构2026年度考试录用公务员专题网站http://bm.scs.gov.cn/pp/gkweb/core/web/ui/business/examResult/written_result.html,查询笔试成绩和合格分数线,点击“笔试成绩查询”按钮,凭借身份证及准考证进行查询。

11

2026.01.15

Java 桌面应用开发(JavaFX 实战)
Java 桌面应用开发(JavaFX 实战)

本专题系统讲解 Java 在桌面应用开发领域的实战应用,重点围绕 JavaFX 框架,涵盖界面布局、控件使用、事件处理、FXML、样式美化(CSS)、多线程与UI响应优化,以及桌面应用的打包与发布。通过完整示例项目,帮助学习者掌握 使用 Java 构建现代化、跨平台桌面应用程序的核心能力。

65

2026.01.14

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

36

2026.01.13

PHP 高性能
PHP 高性能

本专题整合了PHP高性能相关教程大全,阅读专题下面的文章了解更多详细内容。

75

2026.01.13

MySQL数据库报错常见问题及解决方法大全
MySQL数据库报错常见问题及解决方法大全

本专题整合了MySQL数据库报错常见问题及解决方法,阅读专题下面的文章了解更多详细内容。

21

2026.01.13

PHP 文件上传
PHP 文件上传

本专题整合了PHP实现文件上传相关教程,阅读专题下面的文章了解更多详细内容。

35

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
ECMAScript6 / ES6---十天技能课堂
ECMAScript6 / ES6---十天技能课堂

共25课时 | 1.9万人学习

HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 6.7万人学习

HTML+CSS基础与实战
HTML+CSS基础与实战

共132课时 | 9.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号