Не может требовать () значение экспорта по умолчанию в Babel 6.x

88

В Babel 5.x я могу написать следующий код:

app.js

export default function (){}

index.js

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

Тогда я могу работать node index.jsбез ошибок. Однако при использовании Babel 6.x выполняется следующий код

index.es6.js

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

приводит к ошибке

require (...) не является функцией

Я хочу знать почему?

XGHeaven
источник
У тебя есть .babelrc? Вы где-то указываете параметры Babel? Я спрашиваю, потому что Babel 6 ничего не переносит по умолчанию, и вы не указываете es2015предустановку в опубликованном вами коде.
Игорь Рауш
@IgorRaush У меня действительно есть .babelrcскрипт es6, остальные работают нормально
XGHeaven
Пожалуйста, прочтите описания тегов. babelпредназначен для вопросов к библиотеке Python с указанным именем.
Феликс Клинг
Просто не экспортируйте функцию из app.js, а запускайте ее сразу
Берги
@FelixKling, извините, я не знаю того же имени и в
питоне

Ответы:

157

TL; DR

Вы должны использовать

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

Объяснение

В Babel 5 использовался способ совместимости export default: если модуль содержал только один экспорт, и это был экспорт по умолчанию, он был назначен module.exports. Так, например, ваш модуль app.js

export default function () {}

будет перенесено на это

"use strict";

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

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

module.exports = exports["default"];

Это было сделано исключительно для совместимости с requireмодулями -ing Babel-transpiled (как вы это делаете). Это также было непоследовательно; если модуль содержал как именованный экспорт, так и экспорт по умолчанию, он не мог быть require-d.

На самом деле, согласно спецификации модуля ES6, экспорт по умолчанию ничем не отличается от именованного экспорта с именем default. Это просто синтаксический сахар, который можно статически разрешить во время компиляции, так что это

import something from './app';

такое же, как это

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

При этом, похоже, Babel 6 решил отказаться от взлома совместимости при транспиляции модулей. Теперь ваш модуль app.js передается как

'use strict';

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

exports.default = function () {};

Как видите, никаких назначений на module.exports. Для requireэтого модуля вам нужно сделать

require('./app').default();
Игорь Рауш
источник
19
У меня require('./app').default;сработало. default()вернулсяundefined
thinklinux
14
@thinklinux, require(...).defaultдает ссылку на экспортируемую функцию. default()называет это. Если ваша функция ничего не возвращает (или пуста), то, конечно, результат будет undefined.
Игорь Рауш
10
require('path').default()не работает, require('path').defaultу меня работает
soulmachine 03
2
Вы должны использовать require('./app').default;Если вы экспортируете объект вместо функции.
Tokenyet
7

Просто чтобы ответить на правильный ответ выше.

Если вы хотите использовать поведение экспорта по умолчанию babel@5, вы можете попробовать плагин babel-plugin-add-module-exports .

У меня это работает очень хорошо.

Хаотан
источник
3

Если это не сработает

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

использовать

require('./app').default

Без вызова функции в конце.

Ска
источник
Как говорит Игорь в комментарии выше ( stackoverflow.com/questions/33704714/… ), первый из ваших примеров вызовет функцию, а второй даст ссылку на нее
Стефано