Nie można wymagać () domyślnej wartości eksportu w Babel 6.x

85

W Babel 5.x mogę napisać następujący kod:

app.js

export default function (){}

index.js

require('babel/register');
require('./app')();

Wtedy mogę działać node index.jsbez błędów. Jednak używając Babel 6.x, uruchamiasz następujący kod

index.es6.js

require('babel-core/register');
require('./app')();

powoduje błąd

require (...) nie jest funkcją

Chcę wiedzieć dlaczego?

XGHeaven
źródło
Czy masz .babelrc? Czy gdzieś określasz opcje Babel? Pytam, ponieważ Babel 6 domyślnie niczego nie transponuje i nie określasz ustawienia es2015wstępnego w opublikowanym kodzie.
Igor Raush
@IgorRaush Naprawdę mam .babelrc, pozostałe skrypty es6 działają normalnie
XGHeaven
Przeczytaj opisy tagów. babeldotyczy pytań do biblioteki Pythona o tej nazwie.
Felix Kling
Po prostu nie eksportuj funkcji z app.js, ale uruchom ją od razu
Bergi
@FelixKling przepraszam, nie znam tej samej nazwy również w Pythonie ...
XGHeaven

Odpowiedzi:

156

TL; DR

Musisz użyć

require('./app').default();

Wyjaśnienie

Babel 5 miał kiedyś hack kompatybilności export default: jeśli moduł zawierał tylko jeden eksport i był to domyślny eksport, został przypisany do module.exports. Na przykład Twój moduł app.js

export default function () {}

zostałby do tego przełożony

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = function () {};

module.exports = exports["default"];

Zrobiono to wyłącznie w celu zapewnienia zgodności z requiremodułami transpiled -ing Babel (tak jak robisz). Było to również niespójne; jeśli moduł zawierał zarówno nazwane, jak i domyślne eksporty, nie może to być require-d.

W rzeczywistości, zgodnie ze specyfikacją modułu ES6, domyślny eksport nie różni się od nazwanego eksportu z nazwą default. Jest to po prostu cukier syntaktyczny, który można rozwiązać statycznie w czasie kompilacji, więc to

import something from './app';

jest taki sam jak ten

import { default as something } from './app';

To powiedziawszy, wygląda na to, że Babel 6 zdecydował się porzucić hack interoperacyjności podczas transpilacji modułów. Teraz twój moduł app.js jest transponowany jako

'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

exports.default = function () {};

Jak widzisz, nie ma więcej przydziału do module.exports. Do requiretego modułu musisz zrobić

require('./app').default();
Igor Raush
źródło
19
U mnie require('./app').default;działało. default()powróciłundefined
thinklinux
14
@thinklinux, require(...).defaultzawiera odniesienie do wyeksportowanej funkcji. default()nazywa to. Jeśli twoja funkcja nic nie zwraca (lub jest pusta), to oczywiście wynik będzie undefined.
Igor Raush
10
require('path').default()nie działa, require('path').defaultdziała dla mnie
soulmachine
2
Powinieneś użyć require('./app').default;Jeśli eksportujesz obiekt zamiast funkcji.
Tokenyet
7

Po prostu kontynuuj z poprawną odpowiedzią powyżej.

Jeśli chcesz użyć domyślnego zachowania eksportu programu babel@5, możesz wypróbować wtyczkę babel-plugin-add-module-export .

U mnie działa całkiem nieźle.

haotang
źródło
2

Jeśli to nie zadziała

require('./app').default()

posługiwać się

require('./app').default

Bez wywołania funkcji na końcu.

Ska
źródło
Jak Igor mówi w powyższym komentarzu ( stackoverflow.com/questions/33704714/ ), pierwszy z twoich przykładów wywoła funkcję, a drugi poda odniesienie
Stefano