前端模块化输出
前端模块化输出
技术学习|2024-1-29|最后更新: 2024-6-3
type
status
date
slug
summary
tags
category
icon
password
Blocking
Blocked by
top
URL
Sub-item
Parent item
模块化主要是用来抽离公共代码,隔离作用域,避免变量冲突等。
无模块化
CommonJS规范
AMD规范
CMD规范
ES6模块化
适用
服务端
浏览器端
浏览器端
浏览器端
加载方式
同步加载
异步加载、模块开始加载所有依赖
按需加载
异步加载
实现库
requireJs
seajs
来源
前端社区
前端社区
前端社区
官方
是否需要bebal编译

无模块化

将所有JS文件都放在一块,代码执行顺序就按照文件的顺序执行。

缺点

  • 污染全局作用域。 因为每一个模块都是暴露在全局的,简单的使用,会导致全局变量命名冲突,当然,我们也可以使用命名空间的方式来解决。
  • 对于大型项目,各种js很多,开发人员必须手动解决模块和代码库的依赖关系,后期维护成本较高。
  • 依赖关系不明显,不利于维护。 比如main.js需要使用jquery,但是,从上面的文件中,我们是看不出来的,如果jquery忘记了,那么就会报错。

CommonJS

核心思想

  • 通过 require 方法来同步加载所要依赖的其他模块,
  • 通过 module.exports 来导出需要暴露的接口

特点

  1. 同步加载
      • CommonJS模块通常是同步加载的,这意味着模块在被require时会立即加载和执行。这在服务器端是可行的,因为文件通常都是本地的,但在浏览器中可能会导致性能问题。
  1. 模块导出
      • 每个CommonJS模块都有一个module对象,该对象有一个exports属性。模块可以通过添加属性到exports对象或者直接将module.exports赋值为一个值(如函数、对象或类)来导出内容。
  1. 模块导入
      • 使用require函数来导入其他模块。require函数接受一个模块标识符(通常是文件路径)作为参数,并返回该模块导出的内容。
  1. 模块作用域
      • CommonJS模块中的变量、函数等默认都是私有的,除非它们被明确地导出。

缺点

  • CommonJS 是同步加载模块的,只有加载完成,才能执行后面的操作。
  • 由于 CommonJS 是同步加载模块的,在服务器端,文件都是保存在硬盘上,所以同步加载没有问题,但是对于浏览器端,需要将文件从服务器端请求过来,那么同步加载就不适用了,所以,CommonJS是不适用于浏览器端的。

例子

整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。

ES Module

  1. 静态结构
      • ESM的导入和导出语句是静态的,正常情况下它们必须出现在模块的顶层作用域,并且不能被条件语句或函数包围。
  1. 导出和导入语法
      • ESM使用export关键字来导出模块的公共接口,使用import关键字来导入其他模块的导出。
  1. 异步和按需加载
      • ESM支持异步模块加载,允许按需动态导入模块。
  1. 模块解析
      • ESM的模块解析遵循URL的规则,可以使用相对路径、绝对路径或URL
  1. 浏览器和Node.js支持
      • ESM在现代浏览器中得到了原生支持,无需编译或打包。
      • Node.js从版本12开始提供了对ESM的实验性支持,并在后续版本中逐步完善。

common.js 和 es6 中模块引入的区别?

CommonJS 是一种模块规范,最初被应用于 Nodejs,成为 Nodejs 的模块规范。 在 ES6 出来之前,前端也实现了一套相同的模块规范 (例如: AMD),用来对前端模块进行管理。自 ES6 起,引入了一套新的 ES6 Module 规范,在语言标准的层面上实现了模块功能,有望成为浏览器和服务器通用的模块解决方案。但目前浏览器对 ES6 Module 兼容还不太好,我们平时在 Webpack 中使用的 export 和 import,会经过 Babel 转换为 CommonJS 规范。
  • CommonJS 是运行时加载,ES6 模块是静态加载。所以前者支持动态导入。后者可以做静态分析,做tree-sharking。
  • CommonJs 是同步加载模块,因为用于服务端,文件都在本地。而后者是异步导入,因为用于浏览器。同步加载:所谓同步加载就是加载资源或者模块的过程会阻塞后续代码的执行;异步加载:不会阻塞后续代码的执行;
  • CommonJS 是值拷贝(深拷贝),就算导出的值变了,原本的值也不会改变,如果想要更新,必须重新导入一次。ES6 采用值引用(浅拷贝),导入导出的值都指向同一个内存地址,所以导入值会跟随导出值变化。
  • CommonJs 是动态语法可以写在判断里,ES6 Module 静态语法只能写在顶层
  • CommonJs 的 this 是当前模块,ES6 Module的 this 是 undefined

参考

前端模块化详解(完整版)
Updated Aug 13, 2021
`What is 全面ESM` 🤩
Updated Dec 30, 2023
 
组件库支持按需加载四种 Observers 总结
Loading...