Não é possível exigir () o valor de exportação padrão no Babel 6.x

88

No Babel 5.x, posso escrever o seguinte código:

app.js

export default function (){}

index.js

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

Então, posso executar node index.jssem erros. No entanto, usando Babel 6.x, executando o seguinte código

index.es6.js

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

resulta em um erro

require (...) não é uma função

Eu quero saber porque

XGHeaven
fonte
Você tem um .babelrc? Você está especificando opções do Babel em algum lugar? Eu pergunto porque o Babel 6 não transpila nada por padrão e você não está especificando a es2015predefinição no código que postou.
Igor Raush
@IgorRaush Eu realmente tenho um .babelrc, o outro script es6 está rodando normalmente
XGHeaven
Por favor, leia as descrições das tags. babelé para perguntas sobre uma biblioteca Python com o referido nome.
Felix Kling de
Não exporte uma função de app.js, mas execute-a imediatamente
Bergi
@FelixKling, desculpe, não sei o mesmo nome também em python ...
XGHeaven

Respostas:

157

TL; DR

Você tem que usar

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

Explicação

O Babel 5 costumava ter um hack de compatibilidade para export default: se um módulo continha apenas uma exportação, e era uma exportação padrão, ele era atribuído module.exports. Então, por exemplo, seu módulo app.js

export default function () {}

seria transpilado para este

"use strict";

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

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

module.exports = exports["default"];

Isso foi feito puramente para compatibilidade com requiremódulos -ing Babel-transpilados (como você está fazendo). Também era inconsistente; se um módulo contivesse exportações nomeadas e padrão, não poderia ser require-d.

Na realidade, de acordo com as especificações do módulo ES6, uma exportação padrão não é diferente de uma exportação nomeada com o nome default. É apenas açúcar sintático que pode ser resolvido estaticamente em tempo de compilação, então este

import something from './app';

é o mesmo que este

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

Dito isto, parece que o Babel 6 decidiu abandonar o hack de interoperabilidade ao transpilar módulos. Agora, seu módulo app.js é transpilado como

'use strict';

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

exports.default = function () {};

Como você vê, não há mais atribuição para module.exports. Para requireeste módulo, você precisa fazer

require('./app').default();
Igor Raush
fonte
19
Para mim require('./app').default;funcionou. default()retornouundefined
thinklinux
14
@thinklinux, require(...).defaultfornece uma referência à função exportada. default()chama isso. Se sua função não retornar nada (ou estiver vazia), então, é claro, o resultado será undefined.
Igor Raush,
10
require('path').default()não funciona, require('path').defaultfunciona para mim
soulmachine
2
Você deve usar require('./app').default;Se exportar um objeto em vez de uma função.
Tokenyet
7

Apenas para acompanhar com a resposta correta acima.

Se você quiser usar o comportamento padrão de exportação de babel@5, você pode tentar o plugin babel-plugin-add-module-exports .

Está funcionando muito bem para mim.

Haotang
fonte
3

Se isso não funcionar

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

usar

require('./app').default

Sem a chamada de função no final.

Ska
fonte
Como Igor disse no comentário acima ( stackoverflow.com/questions/33704714/… ), o primeiro de seus exemplos chamará a função enquanto o segundo fornecerá uma referência
Stefano