Skip to content

Latest commit

 

History

History
221 lines (168 loc) · 3.75 KB

2017-12-21__commonjs-es6modules-diff.md

File metadata and controls

221 lines (168 loc) · 3.75 KB

笔记

commonjs和es6模块的差异

commonjs是动态加载 es6是静态解析

if (true) {
  // 可以这样写 因为commonjs是动态的
  exports.a = 1
} else {
  // 错误
  export const a = 1
}
在webpack打包时,设置如下的babel配置进行实验的结果
{
  "presets": [
    ["env", {
      "modules": false
    }],
    "stage-2"
  ],
  "plugins": ["transform-runtime"],
}

当一个模块中采用es6抛出时,就不能再使用commonjs抛出了

采用es抛出
// a.js
export let a = 1
let b = 2
setInterval(() => {
  a++
  b++
}, 1000)
export default b

// 不存在exports
// module.exports为只读
exports.c = 3
module.exports = {
  c: 3
}
// b.js
let { a } = require('./a.js')
// => 1 1 1 1 1 1

let b = require('./a.js')
// => {default: 2, __esModule: true} 不变
// => 如果上面没有抛出default的话 会变成 {__esModule: true}
// c.js
import b, { a } from './a.js'
// a => 1 2 3 4 5 6
// b => 2 2 2 2 2 2
采用commonjs抛出
// d.js
exports.b = 1

setInterval(() => {
  exports.b++
}, 1000)
// e.js
let { b } = require('./d.js')
// => 1 1 1 1 1 1

let b = require('./a.js')
// => {b: 1} {b: 2} {b: 3} {b: 4}
// f.js
import { b } from './d.js'
// => 1 2 3 4 5 6

import b from './d.js'
// => {b: 1} {b: 2} {b: 3} {b: 4}
commonjs处理es6模块(删除modules: false)
// h.js
export let a = 1

let b = 2

exports.c = 2

setInterval(() => {
  a++
  b++
  exports.c++
}, 1000)

export default b
i.js
let a = require('./h.js')
// => {a: 1, c: 2, default: 2, __esModule: true} {a: 2, c: 3, default: 2, __esModule: true} {a: 3, c: 4, default: 2, __esModule: true}

let {a} = require('./h.js')
// => 1
并不是抛出的default不会被改变 而是在打包的时候 上面的代码会变为如下:
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var a = exports.a = 1;

var b = 2;

exports.c = 2;

setInterval(function () {
  exports.a = a += 1;
  b++;
  exports.c++;
}, 1000);

exports.default = b;

并没有实时修改exports.default的值,所以default没有改变,但是可以用一下写法让他改变

export default function c () {
  console.log('c')
}

setTimeout(() => {
  /* eslint-disable */
  c = 2
}, 1000)

这样再引入的时候 1s后会变成2,因为打包后的代码如下,会实时修改exports.default的值

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

function c() {
  console.log('c');
}

setTimeout(function () {
  /* eslint-disable */
  exports.default = c = 2;
}, 1000);
UMD模块

umd 模块是动态导出,所以不能采用es6方式导入(并不是指不能import,而是指设置"modules": false),只能使用 commonjs 方式导入

各种在es6模块下不能正常引入,但是在commonjs中可以的例子
  1. umd
(function (root, factory) {
  console.log(typeof module);
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(factory);
  } else if (typeof module === 'object' && module.exports) {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.Popper = factory();
  }
}(this, function () {
  // return
})

上面是典型的umd格式,动态导出,由于es6是静态解析,所以不能采用es6进行处理

  1. module.exportsexportsimportexport 共存的时候
// 两者共存只能采用commonjs打包,因为这样不存在exports对象
export const a = 1;

exports.b = 1;