Kāda ir atšķirība starp Node's module.exports
un ES6's export default
? Es mēģinu noskaidrot, kāpēc man parādās "__ is not a constructor" kļūda, kad es mēģinu export default
Node.js 6.2.2. programmā.
'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
Problēma ir saistīta ar
Šā raksta rakstīšanas laikā neviena vide neatbalsta ES6 moduļus dabiski. Ja tos izmantojat Node.js, jums ir jāizmanto kaut kas tāds kā Babel, lai konvertētu moduļus uz CommonJS. Bet kā tieši tas notiek?
Daudzi uzskata, ka module.exports = ...
ir ekvivalents export default ...
un exports.foo ...
ir ekvivalents export const foo = ...
. Tomēr tā nav gluži taisnība, vai vismaz ne tā, kā to dara Babel.
ES6 default
eksports patiesībā ir arī nosaukuma eksports, tikai default
ir "rezervēts" nosaukums, un tam ir īpašs sintakses atbalsts. Aplūkosim, kā Babel kompilē nosauktos un noklusējuma eksportus:
// 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;
Šeit mēs redzam, ka noklusējuma eksports kļūst par exports
objekta īpašību, tāpat kā foo
.
Moduli varam importēt divos veidos: Izmantojot CommonJS vai ES6 import
sintaksi.
Jūsu problēma: Es domāju, ka jūs darāt kaut ko līdzīgu:
var bar = require('./input');
new bar();
sagaidot, ka bar
tiek piešķirta noklusējuma eksporta vērtība. Bet, kā redzams piemērā iepriekš, noklusējuma eksports ir piešķirts īpašībai default
!
Tātad, lai piekļūtu noklusējuma eksportam, mums patiesībā ir jāveic šādi uzdevumi
var bar = require('./input').default;
Ja mēs izmantojam ES6 moduļu sintaksi, proti
import bar from './input';
console.log(bar);
Babel to pārveidos uz
'use strict';
var _input = require('./input');
var _input2 = _interopRequireDefault(_input);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
console.log(_input2.default);
Var redzēt, ka katra piekļuve bar
tiek pārveidota uz piekļuvi .default
.
tl;dr tagad, lai tas darbotos, fails, kas pieprasa vai importē SlimShady
, ir jāapkopo, izmantojot Babel ar 'use strict'
.
Projektā, kurā sākotnēji sastapos ar šo kļūdu, es izmantoju babel-cli
6.18.0.
'use strict'
ir sliktas ziņas lāčiemvar SlimShady = require('./slim-shady');
var marshall = new SlimShady(); // uh, oh...
'use strict'
import SlimShady from './slim-shady'
var marshall = new SlimShady() // all good in the hood