No se puede requerir () el valor de exportación predeterminado en Babel 6.x

85

En Babel 5.x, puedo escribir el siguiente código:

app.js

export default function (){}

index.js

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

Entonces, puedo ejecutar node index.jssin errores. Sin embargo, usando Babel 6.x, ejecutando el siguiente código

index.es6.js

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

da como resultado un error

require (...) no es una función

¿Quiero saber por qué?

XGHeaven
fuente
¿Tienes un .babelrc? ¿Estás especificando opciones de Babel en alguna parte? Lo pregunto porque Babel 6 no transpila nada de forma predeterminada y no está especificando el es2015ajuste preestablecido en el código que ha publicado.
Igor Raush
@IgorRaush Realmente tengo un .babelrc, el otro script es6 se está ejecutando normalmente
XGHeaven
Lea las descripciones de las etiquetas. babeles para preguntas sobre una biblioteca de Python con dicho nombre.
Felix Kling
Eso sí, no exportar una función a partir app.js, pero ejecutarlo de inmediato
Bergi
@FelixKling lo siento, no sé el mismo nombre también en python ...
XGHeaven

Respuestas:

156

TL; DR

Tienes que usar

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

Explicación

Babel 5 solía tener un truco de compatibilidad para export default: si un módulo contenía solo una exportación, y era una exportación predeterminada, se le asignaba module.exports. Entonces, por ejemplo, su módulo app.js

export default function () {}

se trasladaría a esto

"use strict";

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

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

module.exports = exports["default"];

Esto fue hecho exclusivamente para la compatibilidad con require-ing módulos transpiled-Babel (como lo está haciendo). También fue inconsistente; si un módulo contiene exportaciones con nombre y predeterminadas, no puede ser require-d.

En realidad, de acuerdo con la especificación del módulo ES6, una exportación predeterminada no es diferente de una exportación con nombre con el nombre default. Es solo azúcar sintáctico que se puede resolver estáticamente en tiempo de compilación, por lo que este

import something from './app';

es lo mismo que este

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

Dicho esto, parece que Babel 6 decidió eliminar el truco de interoperabilidad al transpilar módulos. Ahora, su módulo app.js se transpila como

'use strict';

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

exports.default = function () {};

Como ves, no hay más asignaciones a module.exports. Para requireeste módulo, debe hacer

require('./app').default();
Igor Raush
fuente
19
Para mí require('./app').default;funcionó. default()regresóundefined
thinklinux
14
@thinklinux, require(...).defaultda una referencia a la función exportada. default()lo llama. Si su función no devuelve nada (o está vacía), entonces, por supuesto, el resultado será undefined.
Igor Raush
10
require('path').default()no funciona, require('path').defaultfunciona para mí
soulmachine
2
Debería utilizar require('./app').default;Si exporta un objeto en lugar de una función.
Tokenyet
2

Si esto no funciona

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

utilizar

require('./app').default

Sin la llamada a la función al final.

Ska
fuente
Como dice Igor en el comentario anterior ( stackoverflow.com/questions/33704714/… ), el primero de sus ejemplos llamará a la función, mientras que el segundo le dará una referencia
Stefano