Quelle est la différence entre module.exports
de Node et export default
de ES6? J'essaie de comprendre pourquoi l'erreur "__ n'est pas un constructeur" apparaît lorsque j'essaie de export default
dans Node.js 6.2.2.
'use strict'
class SlimShady {
constructor(options) {
this._options = options
}
sayName() {
return 'My name is Slim Shady.'
}
}
// This works
module.exports = SlimShady
'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
Le problème est avec
Au moment de la rédaction de cet article, aucun environnement ne prend en charge les modules ES6 de manière native. Lorsque vous les utilisez dans Node.js, vous devez utiliser quelque chose comme Babel pour convertir les modules en CommonJS. Mais comment ça se passe exactement?
Beaucoup de gens considèrent que module.exports = ...
est équivalent à export default ...
et exports.foo ...
est équivalent à export const foo = ...
. Ce n'est pas tout à fait vrai cependant, ou du moins pas comment Babel le fait.
Les exportations ES6 default
sont en fait également nommées , sauf que default
est un nom "réservé" et que sa syntaxe est prise en charge pour ça. Voyons comment Babel compile les exportations nommées et par défaut:
// 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;
Nous pouvons voir ici que l'exportation par défaut devient une propriété de l'objet exports
, tout comme foo
.
Nous pouvons importer le module de deux manières: en utilisant CommonJS ou en utilisant la syntaxe ES6 import
.
Votre problème: Je pense que vous faites quelque chose comme:
var bar = require('./input');
new bar();
s’attendant à ce que bar
se voit attribuer la valeur de l’export par défaut. Mais comme nous pouvons le voir dans l'exemple ci-dessus, l'exportation par défaut est affectée à la propriété default
!
Donc, afin d'accéder à l'exportation par défaut, nous devons réellement faire
var bar = require('./input').default;
Si nous utilisons la syntaxe de module ES6, à savoir
import bar from './input';
console.log(bar);
Babel le transformera en
'use strict';
var _input = require('./input');
var _input2 = _interopRequireDefault(_input);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
console.log(_input2.default);
Vous pouvez voir que chaque accès à bar
est converti en accès à .default
.