谈谈前端模块化的发展

文章目录

  • 前言
  • 一、理解前端模块化
      • (一)含义
      • (二)为什么要使用模块化?
  • 二、前端模块化标准规范
      • (一)CommonJS
      • (二)AMD
      • (三)CMD
      • (四)ES module


前言

前端模块化发展了10余年左右,前前后后出现了commonJS,AMD,CMD等多种模块化标准方案,目前最新的是ES module。下面大概讲述一下这十年左右的发展历程~


一、理解前端模块化

(一)含义

最开始JS是没有模块化的,由于前端页面越来越复杂,项目越来越大,催生了模块化的概念。

前端模块化是一种开发管理规范,用分割模块的方式来管理优化代码。每个模块有它特定的功能,模块间相互隔离,但可以通过特定接口访问内部成员,也可以依赖其他模块。

(二)为什么要使用模块化?

(1)在没有模块化时:


<html>
  <head>
    <meta charset="utf-8">
  head>
  <body>
    <div id="app">div>
    <script>
    	console.log(2)
	script>
  body>
html>

我们所有的业务代码,都通过script标签内嵌到HTML中,代码质量随着业务的扩大变得无法保证。
(2)最初的模块化方案是:

<html>
  <head>
    <meta charset="utf-8">
  head>
  <body>
    <div id="app">div>
    <script src="a.js">script>
    <script src="b.js">script>
    <script src="index.js">script>
  body>
html>

将代码写在外部JS文件中,一个JS文件为一个模块,通过script src引入。这样组织代码带来了一些好处:

  1. 提高了代码复用性,通过代码可以抽离
  2. 提高代码可维护性
  3. 灵活架构,焦点分离,方便模块间组合、分解

虽然这样可以将不同的功能模块分割,但明显不是很好的解决方案,仍然存在一些弊端:

  1. 作用域:所有JS文件模块共用一个作用域-全局作用域,会有命名冲突,污染全局的问题。
  2. 加载顺序:模块若有依赖模块,必须按特定的顺序加载JS文件。被依赖的先加载。
  3. 文件数量很多

(3)为了解决作用域的问题,之后出现了闭包立即执行函数来定义一个模块:

;(function(){
     ...})()

立即执行函数的作用域是独立的,这样就避免了上面存在的污染全局的问题。但模块依赖的加载顺序问题依然存在。

因此,我们需要比较标准的模块化方案来解决这些问题。

二、前端模块化标准规范

(一)CommonJS

随着V8引擎的诞生,诞生了Node,Node 应用采用的是 CommonJS 模块规范。此规范特点:

  1. 每个文件就是一个模块,有自己的作用域。
  2. node环境使用,模块的加载是运行时同步加载的;
  3. require引入,module.exports或者exports导出(输出的是值的拷贝
  4. 缓存机制:每个模块可以多次加载但是只会在第一次加载时运行,然后会被缓存供后续加载时使用

由于此规范无法在浏览器环境中使用,所以之后又催生了一些适用浏览器环境的规范,AMD CMD。

(二)AMD

当然AMD只是一种规范,实现此规范的库是RequireJS,特点:

  1. async module definition 异步模块定义,异步加载,适应环境
  2. define(moduleName, [module], factory) 定义模块,一个文件可设置多个模块
  3. require([module], callback) 引入模块
  4. 模块依赖前置

(三)CMD

之后阿里也对模块化做了贡献,推出了符合CMD规范的SeaJS库(现已不再维护),特点:

  1. common module definition 通用模块规范,与AMD类似,同样适应浏览器环境
  2. define(function(require, exports, module){}) 定义模块
  3. seajs.use([module路径],function(moduleA,moduleB,moduleC){ }) 使用模块
  4. 遵循模块依赖就近原则,按需加载,这是与AMD(依赖前置)的本质区别。对模块化做的改进之处。

(四)ES module

CommonJS AMD CMD 都不是ES官方给出的规范,直到2015年推出了ES6版本,从语言标准层面实现模块功能,作为前后端通用的解决方案。特点:

  1. ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
  2. 浏览器、node通用
  3. ES6模块默认是严格模式
  4. 一个文件一个模块
  5. import 导入模块
  6. export 导出模块

浏览器端使用ES6模块:
对于type="module"

你可能感兴趣的:(前端,js,前端,模块化,大前端,工程化)