Nodejs Web端JavaScript模块化的历史是什么样子的?

Nodejs Web端JavaScript模块化的历史是什么样子的?

Web端JavaScript模块化并不是横空出世,凭空捏造的,目前的这些SeaJS,RequireJS,AMD以及CMD标准是怎么形成的呢?

8 回复

Node.js Web端JavaScript模块化的历史是什么样子的?

Web端JavaScript模块化并不是凭空捏造的。从早期的混乱到如今的规范和工具,JavaScript模块化的历程充满了挑战和创新。本文将回顾这一过程,并介绍一些重要的里程碑。

1. 早期阶段:全局变量混乱

在早期,JavaScript并没有模块化概念。所有代码都在全局作用域中执行,这导致了命名冲突和难以维护的代码。例如:

// 文件: script1.js
var message = "Hello, World!";
function sayHello() {
    console.log(message);
}

// 文件: script2.js
var message = "Goodbye, World!";
function sayGoodbye() {
    console.log(message);
}

在这段代码中,script1.jsscript2.js 都定义了一个名为 message 的变量,这会导致命名冲突。

2. 模块模式(Module Pattern)

为了减少全局变量污染,开发者开始使用模块模式来封装代码。这种模式通过立即调用函数表达式(IIFE)来创建私有作用域:

(function(global) {
    var message = "Hello, World!";
    global.sayHello = function() {
        console.log(message);
    };
})(this);

这种模式虽然解决了部分问题,但仍然缺乏模块之间的依赖管理和加载机制。

3. CommonJS 规范

随着服务器端JavaScript的发展,CommonJS规范应运而生。它定义了一套标准的模块系统,允许开发者通过 requiremodule.exports 来导入和导出模块:

// 文件: module1.js
exports.message = "Hello, World!";
exports.sayHello = function() {
    console.log(exports.message);
};

// 文件: module2.js
var module1 = require('./module1');
console.log(module1.message); // 输出 "Hello, World!"
module1.sayHello(); // 输出 "Hello, World!"

4. AMD (Asynchronous Module Definition)

AMD规范旨在解决浏览器环境中的异步加载问题。它允许模块在加载时声明依赖关系,并且支持异步加载:

// 文件: module1.js
define(['dependency'], function(dependency) {
    return {
        message: "Hello, World!",
        sayHello: function() {
            console.log(dependency.getMessage());
        }
    };
});

// 文件: dependency.js
define({
    getMessage: function() {
        return "Hello from dependency!";
    }
});

5. CMD (Common Module Definition)

CMD规范与AMD类似,但更注重于简单性和兼容性。SeaJS是一个流行的CMD实现:

// 文件: module1.js
define(function(require, exports, module) {
    var dependency = require('./dependency');
    exports.message = "Hello, World!";
    exports.sayHello = function() {
        console.log(dependency.getMessage());
    };
});

// 文件: dependency.js
define(function(require, exports, module) {
    return {
        getMessage: function() {
            return "Hello from dependency!";
        }
    };
});

总结

从全局变量混乱到模块模式,再到CommonJS、AMD和CMD规范,JavaScript的模块化经历了多个阶段。这些规范和工具为现代Web开发提供了强大的模块化能力,使得代码更加组织有序和易于维护。


感觉dojo是比较早模块化的,然后yui3也开始模块化了。标准都是晚于这些探索者,而SeaJS和RequireJS则是提供了基于某些标准的实现。标准被广泛接受之后,又影响到dojo之类的框架。 我最早接触到的模块化解决方案是国内的JSI,比以上所有这些都要更早。

确实,之前我只用extjs,后来接触dojo的时候发现他提供了require方法,dojo也是之前很早发行的,所以想想应该是比较早的

谢谢你的回复,学到了新的东西。

JSI太小众,作者比较低调,文档也比较少。如果就想要一个模块加载方案的话,那就seaJS或者requireJS吧。。。

以前用RequireJS,现在放弃不用了,文本合并压缩一下一个更好

可以模块化开发,压缩打包上线。

Node.js Web端JavaScript模块化的历程可以追溯到早期Web应用开发时面对的挑战。在Web应用中,随着功能的复杂度增加,JavaScript代码也变得越来越庞大,难以维护。因此,如何有效地组织和管理这些代码成为了一个亟待解决的问题。

模块化的发展历程

  1. 全局变量污染

    • 最初,开发者将所有JavaScript代码放在一个全局作用域中,这会导致全局变量和函数命名冲突。
    • 示例(不推荐):
      // script1.js
      var globalVar = "Hello";
      
      // script2.js
      var globalVar = "World"; // 这会覆盖script1.js中的globalVar
      
  2. CommonJS规范

    • 为了改善这一情况,CommonJS规范应运而生,它允许JavaScript文件以模块的形式进行组织。每个模块都有自己的作用域,从而避免了全局变量污染问题。
    • 示例(CommonJS):
      // module1.js
      module.exports = {
        greet: function() {
          console.log("Hello");
        }
      };
      
      // main.js
      const module1 = require('./module1');
      module1.greet(); // 输出 "Hello"
      
  3. AMD(Asynchronous Module Definition)

    • 随着浏览器端JavaScript应用的发展,CommonJS规范并不适合浏览器环境。AMD规范为浏览器环境提供了一种异步加载模块的方式,比如RequireJS库就实现了这一规范。
    • 示例(AMD):
      // module1.js
      define({
        greet: function() {
          console.log("Hello");
        }
      });
      
      // main.js
      require(['./module1'], function(module1) {
        module1.greet(); // 输出 "Hello"
      });
      
  4. CMD(Common Module Definition)

    • CMD规范则是另一种浏览器端的模块化方案,它更注重按需加载,由SeaJS实现。
    • 示例(CMD):
      // module1.js
      define(function(require, exports, module) {
        var dep = require('./dep'); // 按需加载
        exports.greet = function() {
          console.log("Hello");
        };
      });
      
      // main.js
      seajs.use('./module1', function(module1) {
        module1.greet(); // 输出 "Hello"
      });
      
  5. ES6 Modules

    • 随着ECMAScript 6(ES6)的标准化,内置的模块系统成为了标准。现在大多数现代浏览器和Node.js都支持这种模块化方式。
    • 示例(ES6 Modules):
      // module1.js
      export function greet() {
        console.log("Hello");
      }
      
      // main.js
      import { greet } from './module1';
      greet(); // 输出 "Hello"
      

总结

从最早的全局变量污染问题到CommonJS、AMD、CMD等规范的出现,再到现在的ES6 Modules标准,JavaScript模块化技术经历了一个逐步完善的过程。现在,ES6 Modules已经成为主流,其简洁性和标准性使得它在未来的Web开发中占据了主导地位。

回到顶部