preface

In the interview before, the interviewer asked about the import and export parsing strategy of Webpack in esModule and CommonJS, and unsurprisingly, I was confused. So I did some simple experiments, and then MAYBE I’ll go into the source code level to do an analysis of these phenomena.

1.ES6 import and export modes

// module.js
export let a = 1 // Named export
let b = 2
export default b // Export by default
// index.js
import b, { a } from './module'
console.log(a + b)
Copy the code

Let’s export the module in its entirety

import * as module from './module'
console.log(module);
/* {a: 1
default: 2
Symbol(Symbol.toStringTag): "Module"
__esModule: true
}*/
Copy the code

As you can see, this namespace import will import the entire module. If there is a default export in the module, it will appear as default, which is set to the keyword to prevent naming conflicts.

By the way, the Symbol(symbol.toStringTag) property

This is a built-in symbol that is usually used as the attribute key of an object. The corresponding attribute value should be a string that represents the object’s custom type label. Usually only built-in Object. The prototype. The toString () method to read the label and put it in his own return values

class ValidatorClass {[Symbol.toStringTag] = 'Validator'
  get [Symbol.toStringTag]() {
    return "Validator"; }}console.log(Object.prototype.toString.call(new ValidatorClass())); // [object Validator]
Copy the code

There’s something new to brag about when the interviewer asks you to get the type of person you’re interviewing.

2.CommonJS

Require using CommonJS returns a JS object

// module.js
exports.someValue = 42;
// index.js
const module = require('./module')
console.log(module);
/*{someValue: 42}*/
Copy the code

exports (CommonJS)

This variable defaults to module.exports (that is, an object). Exports will no longer be exported if module.exports is overwritten.

3. Mix es and CommonJS syntax

Es introduces the Common export

// module.js
module.exports = {
  someValue: 42
};
// index.js
import * as module from './module'
// Import module from './module' with the same result
console.log(module);
/*{someValue: 42}*/
Copy the code

As you can see, if the export is module.export, no matter how it is imported, it is a normal JS object.

If you use a named import like the following, the default value is additionally initialized as this object. That is, when an export is exported, both ES imports are applied to the named import when it is resolved.

// module.js
exports.someValue = 42;
// index.js
import * as module from './module'
console.log(module);
/* {default: {someValue: 42}
someValue: (...)
Symbol(Symbol.toStringTag): "Module"
__esModule: true
}*/
Copy the code

Common introduces the ES export

In this case, const… = require(…) Can be equivalent to import * as… from ‘… ‘, which is introduced as a named name.

// module.js
export let someValue = 42;
// index.js
const module = require('./module')
console.log(module);
/* {someValue: 42
Symbol(Symbol.toStringTag): "Module"
__esModule: true
}*/
Copy the code