前端模块化的发展

63 阅读3分钟

背景

前端经历了一系列的发展,各种标准和工具百花齐放,自从2009年的Node.js诞生,前端先后出现了CommonJSAMDCMDUMDES Module等模块规范,底层规范的发展催生出了一系列工具链的创新,比如AMD规范提出时社区诞生了模块加载工具requireJS,基于CommonJS规范的模块打包工具browserify,还有能让用户提前用上ES Module语法的JS编译器Babel、兼容各种模块规范的重量级打包工具webpack以及基于浏览器原生ES Module支持而实现的no-bundle构建工具Vite等等。

模块化的起点:直接引入脚本

最早的前端开发依赖简单的 <script> 标签来引入 JavaScript 文件

CommonJS规范

CommonJS是业界最早正式提出的JavaScript模块规范,主要用于服务端,随着Node.js越来越普及,这个规范也被业界广泛应用,对于模块规范而言,一般会包含两个方面的内容:

  • 统一的模块化代码规范
  • 实现自动加载模块的加载器(也称之为loader

代码中使用了require来导入一个模块,用module.exports来导入一个模块。对于ConnonJS而言,一方面它定义了一套完整的模块化代码规范,另一方面Node.js为之实现了自动加载模块的loader,看上去是一个不错的模块规范,但是也存在一些问题:模块加载器由Node.js提供,依赖了Node.js本身的功能实现,比如文件系统,如果CommonJS模块直接放到浏览器中是无法执行的

AMD规范

AMD全称为Asynchronous Module Definition,即异步模块定义规范,模块根据这个规范,在浏览器环境中被异步加载,而不会像CommonJS规范进行同步加载,也就不会产生同步请求导致的浏览器解析过程阻塞的问题了

CMD规范

同期出现的规范当中也有CMD规范,这个规范是由淘宝出品的SeaJS实现的,解决的问题和AMD一样,不过随着社区的不断发展,SeaJS已经被requireJS兼容了。

UMD:统一模块定义

UMD(Universal Module Definition) 兼容 CommonJS 和 AMD,为模块在多种环境下的运行提供支持

ES6 Module

ES6 Module也被称作ES Module或者ESM,是由ECMAScript官方提出的模块化规范,作为一个官方提出的规范,ES Module已经得到了现代浏览器的内置支持,在现代浏览器中,如果在HTML中加入含有type='module'属性的script标签,name浏览器会按照ESModule规范来进行依赖加载和模块解析,这也是vite在开发阶段实现no-bundle的原因,由于模块加载的任务交给了浏览器,即使不打包也可以顺序运行模块代码。

工具链的发展

随着模块规范的演进,各种工具不断创新,推动前端开发的工程化:

  • RequireJS:基于 AMD,用于模块加载。
  • Browserify:基于 CommonJS,将 Node.js 模块打包到浏览器中。
  • Webpack:支持多种模块规范,提供强大的打包能力,成为行业标准。
  • Babel:允许开发者提前使用 ES Module 语法,将其转为兼容的代码。
  • Vite:基于浏览器原生 ES Module 支持,优化开发体验,无需预打包。

总结

前端模块化经历了从混乱到规范化的过程,推动了前端生态的繁荣发展。从最初的 CommonJS 和 AMD 到官方的 ES Module,每一代规范都解决了特定场景下的问题。如今,ES Module 已成为行业标准,而工具链如 Webpack 和 Vite 进一步提升了开发效率。模块化的发展不仅提高了代码可维护性,也为复杂前端项目的实现奠定了基础。