Es6 模块 与 CommonJS 模块的区别

1,304 阅读3分钟

模块的作用

为什么需要模块

JavaScript在没有模块化之前,所有的变量在全局都是共享的,特别容易被篡改,出现一些莫名其妙的 bug。所以很多时候为了解决这个问题都用闭包的形式来解决这类问题。例如: JQ

(function( global, factory ) {
  ...
})(global, factory);

作用

每一个模块都是独立的,都有自己的作用域互不影响、便于管理与阅读。

Es6 模块

在浏览器中使用我们必须指定 script 标签的类型,<script type="module" src="./index.js"></script>

在模块里面默认启用严格模式 this 指向 undefined

模块可以多次加载,但是只会在第一次加载时运行一次

import 引入

import 是静态执行,所以不能使用表达式和变量,也不能在条件语句中使用
import 语句会提升到文件的头部并优先执行(编译期执行)
// 解构引入
import { xx } from './module.js'

// 重命名引入
import { xx as xxx } from './module.js'

// 引入默认导出
import xx from './module.js'

// 解构与默认引入的结合
import xx, { xx } from './module.js'

// 引入模块
import 'xx'

// 不能条件引入
if (true) {
  import xx from './module.js'
}

export、export default 导出

// 导出 必须是声明语句
export const x = 1

// 默认导出, 一个模块只能有一个
export default { a: 1 }

引入与导出的混合

// 导出 module 模块的所有
export * from './module.js'

// 将 module 模块的所有收集到一个对象并导出
export * as xx from './module.js'

// 引入并导出一个默认模块
import module from './module.js'
export { module }

动态加载

返回的是一个 Promise

import('./modlue.js').then(_ => {})

循环引用

引用多次,执行一次

CommonJS 模块

所有代码都运行在模块作用域,不会污染全局作用域。

模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。

模块加载的顺序,按照其在代码中出现的顺序。

require 引入

// 解构引入
const { xx } = require('./module.js')

// 整体引入
const xx = require('./module.js')

exports、module.exports 导出

exports.xx = 12

module.exports.xx = 12

循环引用

引用多次,执行一次

修改引入位置

区别

  • 执行方式不一样

    Es6 编译期执行

    CommonJS 运行期执行

  • 值的输出形式不通

    Es6 值的引用 CommonJS 值的拷贝

博文推荐

【笔记不易,如对您有帮助,请点赞,谢谢】