More important difference is: export default
exports value, while export const
/export var
/export let
exports reference(or been called live binding). Try below code in nodejs(using version 13 or above to enable es module by default):
// a.mjs
export let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
export default x;
// index.mjs
import y, { x } from './1.mjs';
setInterval(() => {
console.log(y, x);
}, 1000);
# install node 13 or above
node ./index.mjs
And we should get below output:
6 5
7 5
8 5
...
...
Why we need this difference
Most probably, export default
is used for compatibility of commonjs module.exports
.
How to achieve this with bundler(rollup, webpack)
For above code, we use rollup to bundle.
rollup ./index.mjs --dir build
And the build output:
// build/index.js
let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
var y = x;
setInterval(() => {
console.log(y, x);
}, 1000);
Please pay attention to var y = x
statement, which is the default
.
webpack has similar build output. When large scale of modules are added to build, concatenateing text is not sustainable, and bundlers will use Object.defineProperty
to achieve binding(or called harmony exports in webpack). Please find detail in below code:
main.js
...
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
...
// 1.js
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],[
/* 0 */,
/* 1 */
/***/ (function(__webpack_module__, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "x", function() { return x; });
let x = 5;
// or
// let x = 5;
// export { x }
setInterval(() => {
x++;
}, 1000);
/* harmony default export */ __webpack_exports__["default"] = (x);
/***/ })
]]);
Please find the difference behavior between /* harmony export (binding) */
and /* harmony default export */
.
ES Module native implementation
es-modules-a-cartoon-deep-dive by Mozilla told why, what and how about es module.
const
will make the identifier read-only. So in the case of primitive values, you can consider that to be immutable. Note that the value itself is not immutable, so objects, arrays, etc can be changed — just not reassigned. – spmurrayzzzconst
. – Felix Kling