Problem dotyczy
- jak emulowane są moduły ES6 we CommonJS
- jak importujesz moduł
ES6 do CommonJS
W chwili pisania tego tekstu żadne środowisko nie obsługuje natywnie modułów ES6. Używając ich w Node.js, musisz użyć czegoś takiego jak Babel, aby przekonwertować moduły na CommonJS. Ale jak to dokładnie się dzieje?
Wiele osób uważa module.exports = ...
za równoważne export default ...
i exports.foo ...
równoważne export const foo = ...
. To nie do końca prawda, a przynajmniej nie tak to robi Babel.
default
Eksport ES6 jest w rzeczywistości również nazywany eksportem, z tą różnicą, że default
jest to nazwa „zarezerwowana” i istnieje specjalna obsługa składni. Zobaczmy, jak Babel kompiluje nazwy i domyślny eksport:
// 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;
Tutaj widzimy, że domyślny eksport staje się właściwością exports
obiektu, podobnie jak foo
.
Zaimportuj moduł
Możemy zaimportować moduł na dwa sposoby: albo używając CommonJS, albo używając import
składni ES6 .
Twój problem: uważam, że robisz coś takiego:
var bar = require('./input');
new bar();
oczekiwanie, że bar
jest przypisana wartość domyślnego eksportu. Ale jak widać w powyższym przykładzie, domyślny eksport jest przypisany do default
właściwości!
Aby więc uzyskać dostęp do domyślnego eksportu, musimy to zrobić
var bar = require('./input').default;
Jeśli użyjemy składni modułu ES6, a mianowicie
import bar from './input';
console.log(bar);
Babel to przekształci
'use strict';
var _input = require('./input');
var _input2 = _interopRequireDefault(_input);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
console.log(_input2.default);
Możesz zobaczyć, że każdy dostęp do bar
jest konwertowany na dostęp .default
.
module.exports
,exports
imodule.exports
mają różne wartości, tak że zadanieexports.defaults
nie ma wpływu (bomodule.exports
to, co dostaje eksportowane). Innymi słowy, jest dokładnie tak samo, jakbyś to zrobiłmodule.exports = { ... }
.Musisz poprawnie skonfigurować Babel w swoim projekcie, aby używać domyślnego eksportu i eksportować const foo
następnie dodaj poniżej konfigurację w .babelrc
źródło
Felix Kling zrobił świetne porównanie tych dwóch, dla każdego, kto zastanawia się, jak zrobić domyślny eksport obok nazwanych eksportów z module.exports w nodejs
źródło
tl; dr teraz, aby to zadziałało, plik wymagający lub importujący
SlimShady
musi zostać skompilowany przy użyciu Babel z'use strict'
.Korzystam z wersji
babel-cli
6.18.0 w projekcie, w którym początkowo napotkałem ten błąd.Bez
'use strict'
jest zła wiadomość Niedźwiedzieproszę stosować „ścisłe”
źródło
import
deklaracji jest modułem, a te już są ścisłe. Rzeczywista różnica polega na wymaganiu kontra importowaniu.import
zamiastrequire
iexport default
zamiastexports.default
.