ejs和cjs

1,868 阅读1分钟

我们先来看下ejs和cjs的区别在哪

//cjs写法  a.js

var a = 1;

var b = 2;

setTimeout(function(){

    a = 3;

    b = 4;

}, 2000)

module.exports = {

    a: a,

    b: b

}

var a = require('a.js');

console.log(a.a) // 1

console.log(a.b) // 2

setTimeout(function(){

    console.log(a.a) // 1

    console.log(a.b) // 2

}, 5000)

//esmx写法 a.js

var a = 1;

var b = 2;

setTimeout(function(){

    a = 3;

    b = 4;

}, 2000)

export defalut {

    a: a,

    b: b

}

import a from 'a.js';

console.log(a.a) // 1

console.log(a.b) // 2

setTimeout(function(){

    console.log(a.a) // 3

    console.log(a.b) // 4

}, 5000)

可以看出ejs和cjs写法产生了不同效果。

cjs是执行到require语句才会导入模块,它导入的是模块的拷贝,导入一次之后就会被缓存,后面再导入是缓存的版本

esm 模块在编译阶段就可以分析出导出的结果(导入会先于正常的执行流执行),导出的结果是值得引用,所以对原模块的更改会影响导出值

可以看个例子:

    // a.js

    console.log('a')

    // b.js

    console.log('b')

    var a = require('a.js') // b a

    // c.js

    console.log('c')

    import 'a.js' // a c



怎么在ems中使用cjs呢?

esm中 export 导出的是一个模块 export default a 实际导出的是{default: a}

import a, {b, c}from 'b.js' 其实a导入的是 b模块导出来的default属性

babel处理esm中使用cjs

// a.js

'use strict';

Object.defineProperty(exports, '__esModule', {

    value: true

})

exports.defalut = exports.a = exports.b = void 0;

var a = 1;

exports.a = a

var b = 2;

exports.b = b;

var _default = 3l

exports.defalut = _default;

// b.js

import {a, b} from 'a.js'

console.log(a)

console.log(b)

babel处理后:

var _lib = require('lib');

console.log(_lib.a)

console.log(_lib.b)

// c.js

import lib from 'a.js'

使用整体导入的,babel处理后:

'use strict';

var _lib = _interopRequireDefault(require('a.js'));

function _interopRequireDefault(obj) {

    return obj && obj.__esModule ? obj : {defalut: obj}

}

可以看出如果export上挂载了__esModule属性,所有在导入时,如果是es module直接返回,如果不是则当做cjs处理,整体挂载在一个对象的default属性上,统一。