preface

You can import moment from ‘moment’; , the operation is normal.

However, in typescript with nodeJS, it is sometimes reported that the default export is not available. Instead, use import * as moment from ‘moment’; .

In this case, check the esModuleInterop option of tsconfig.json. Enabling this option will affect the actual compilation and resolve this issue (see Babel below for details). Also take esModuleInterop allowSyntheticDefaultImports default value, this option only affects typescript hint, does not affect the compilation.

Because the front-end Webpack can handle CommonJS modules, the following are compiled to CommonJS, ES5, and the esModuleInterop option is not enabled in typescript

typescript

Typescript handles ES6 export

index.ts:

export default 1;
export const a =2;
Copy the code

Compiled into:

"use strict";
exports.__esModule = true;
exports["default"] = 1;
exports.a = 2;
Copy the code

Compile to the CommonJS specification and hang properties directly to exports

Exports. __esModule is required by the general specification

Typescript handles ES6 imports

index2.ts:

import example, { a } from "./index";
console.log(example, a);
Copy the code

Compiled into

"use strict";
exports.__esModule = true;
var index_1 = require("./index");
console.log(index_1["default"], index_1.a);
Copy the code

The object index_1 is loaded back from the CommonJS specification, and this is the exports object in the index.js file.

The example and a variables we used in indexx2.ts console.log are replaced by index_1[“default”] and index_1.a after compilation

babel

Babel handles ES6 export

index.js:

export default 1;
Copy the code

Compiled into:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;
var _default = 1;
exports["default"] = _default;
Copy the code

The code is different from TS, but it follows the same formula.

Babel handles ES6 imports

index2.js:

import example from "./index";
console.log(example)
Copy the code

Compiled into:

"use strict";

var _index = _interopRequireDefault(require("./index"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

console.log(_index["default"]);
Copy the code

The example variable in index2.js console.log becomes _index[“default”].

Babel will have a “dark magic”, if the file loaded is the esModule specification (from the __esModule attribute), then no processing is required, and the _index variable is the object that require gets. Otherwise, the _index is {“default”: require(“./index”)}, which means that Babel packages the exported object and puts it in the default property of the new object.

conclusion

  1. The basic principle of import is import ‘XXX’ === require(‘ XXX ‘).default

  2. When Babel imports commonJS modules such as moment.js, it wraps them in the default property of the new object. This special operation is not performed when the esModuleInterop option is not enabled for TS.