【JS】模块:CommonJS与ES6

106 阅读1分钟

CommonJS

CommonJS主要以服务端为目标环境,同步的一次性把所有模块加载到内存,但是也可以用于定义浏览器中使用的模块依赖(浏览器中无法直接使用)。

var moduleB = require("./moduleB")

module.exports = {
  stuff: moduleB.doStuff()
}

特性

  • 无论一个模块在require()被引用多少次,模块永远是单例。也就是说无论请求多少次只会加载一次,加载之后会被缓存,后续得到缓存的模块。
  • 模块的加载是同步的。

用法

  • require()引入,可以是绝对,相对路径,也可以是node_modules中模块的标识符
  • module.exports 默认是空对象,在此对象上定义模块暴露的公共接口
  • 如果想导出实体,可以直接给module.exports赋值,比如变量,函数...

ES6模块

浏览器会从顶级模块加载整个依赖图,并且是异步完成的。

特性

  • 模块只加载一次
  • 引入的模块是单例 (eg: vue cli项目中多个js引入vue单例)
  • 严格模式默认
  • 有自己的命名空间
  • 顶级的this是undefined
  • 异步加载

用法

  • export 关键字声明一个值 为 命名导出

  • 导出语句必须在模块顶级,不能嵌套在一个块中,比如if

  • 命名导出与行内命名导出

    // 命名导出
    function funA() {
      console.log('funA');
    }
    function funB() {
      console.log('funB');
    }
    
    export {funA, funB}
    
    // 等价于 行内命名导出写法
    
    export function funA() {
      console.log('funA');
    }
    export function funB() {
      console.log('funB');
    }
    
  • 默认导出

    const foo = 'foo'
    export default foo
    
    // 等价于命名导出
    export {foo as default}
    
  • 命名导出与默认导出两种导出方法并不冲突,可以在同一个模块并存

  • 命名导出可以使用 * 批量获取并复制给别名变

    import * as mod from './module.js'
    mod.funA()
    mod.funB()