webentwicklung-frage-antwort-db.com.de

Standardmäßig wird in Node.js und ES6 zwischen module.exports und export unterschieden

Was ist der Unterschied zwischen dem module.exports des Knotens und dem export default des ES6? Ich versuche herauszufinden, warum ich den Fehler "__ ist kein Konstruktor" erhalte, wenn ich versuche, export default in Node.js 6.2.2 auszuführen.

Was funktioniert

'use strict'
class SlimShady {
  constructor(options) {
    this._options = options
  }

  sayName() {
    return 'My name is Slim Shady.'
  }
}

// This works
module.exports = SlimShady

Was nicht funktioniert

'use strict'
class SlimShady {
  constructor(options) {
    this._options = options
  }

  sayName() {
    return 'My name is Slim Shady.'
  }
}

// This will cause the "SlimShady is not a constructor" error
// if in another file I try `let marshall = new SlimShady()`
export default SlimShady
223
Marty Chang

Das Problem ist mit

  • wie ES6-Module in CommonJS emuliert werden
  • wie Sie das Modul importieren

ES6 zu CommonJS

Zum jetzigen Zeitpunkt unterstützt keine Umgebung ES6-Module nativ. Wenn Sie sie in Node.js verwenden, müssen Sie Babel verwenden, um die Module in CommonJS zu konvertieren. Aber wie genau passiert das?

Viele Leute betrachten module.exports = ... als äquivalent zu export default ... und exports.foo ... als äquivalent zu export const foo = .... Das ist allerdings nicht ganz richtig, oder zumindest nicht, wie Babel das macht.

ES6 default -Exporte sind eigentlich auch benannte Exporte, mit der Ausnahme, dass default ein "reservierter" Name ist und spezielle Syntaxunterstützung besteht dafür. Schauen wir uns an, wie Babel benannte und Standardexporte kompiliert:

// input
export const foo = 42;
export default 21;

// output
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = exports.foo = 42;
exports.default = 21; 

Hier können wir sehen, dass der Standardexport eine Eigenschaft für das Objekt exports wird, genau wie foo.

Importieren Sie das Modul

Wir können das Modul auf zwei Arten importieren: Entweder mit CommonJS oder mit der import -Syntax von ES6.

Ihr Problem: Ich glaube, Sie machen so etwas wie:

var bar = require('./input');
new bar();

in der Erwartung, dass bar den Wert des Standardexports zugewiesen bekommt. Wie wir im obigen Beispiel sehen können, wird der Standardexport der Eigenschaft default zugewiesen!

Um auf den Standardexport zuzugreifen, müssen wir also tatsächlich etwas tun

var bar = require('./input').default;

Wenn wir ES6-Modulsyntax verwenden, nämlich

import bar from './input';
console.log(bar);

Babel wird es in verwandeln

'use strict';

var _input = require('./input');

var _input2 = _interopRequireDefault(_input);

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

console.log(_input2.default);

Sie können sehen, dass jeder Zugriff auf bar in den Zugriff auf .default konvertiert wird.

310
Felix Kling