Babel 6 cambia la forma en que exporta los valores predeterminados

Resuelto kentcdodds asked hace 8 años • 4 respuestas

Antes, babel añadía la línea module.exports = exports["default"]. Ya no hace esto. Lo que esto significa es antes de que pudiera hacer:

var foo = require('./foo');
// use foo

Ahora tengo que hacer esto:

var foo = require('./foo').default;
// use foo

No es gran cosa (y supongo que esto es lo que debería haber sido desde el principio). El problema es que tengo una gran cantidad de código que depende de la forma en que solían funcionar las cosas (puedo convertir la mayor parte a importaciones de ES6, pero no todas). ¿Alguien puede darme consejos sobre cómo hacer que la forma anterior funcione sin tener que revisar mi proyecto y solucionar este problema (o incluso algunas instrucciones sobre cómo escribir un codemod para hacer esto sería bastante ingenioso)?

¡Gracias!

Ejemplo:

Aporte:

const foo = {}
export default foo

Salida con Babel 5

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;
module.exports = exports["default"];

Salida con Babel 6 (y el complemento es2015):

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;

Observe que la única diferencia en la salida es el archivo module.exports = exports["default"].


Editar

Quizás le interese esta entrada de blog que escribí después de resolver mi problema específico: Malentendido sobre los módulos ES6, actualización de Babel, Tears y una solución

kentcdodds avatar Nov 04 '15 00:11 kentcdodds
Aceptado

Si desea el comportamiento de exportación de CommonJS, deberá usar CommonJS directamente (o usar el complemento en la otra respuesta). Este comportamiento se eliminó porque causaba confusión y conducía a una semántica de ES6 no válida, en la que algunas personas habían confiado, por ejemplo.

export default {
  a: 'foo'
};

y luego

import {a} from './foo';

que no es válido ES6 pero funcionó debido al comportamiento de interoperabilidad de CommonJS que está describiendo. Desafortunadamente, no es posible admitir ambos casos y permitir que las personas escriban ES6 no válido es un problema peor que obligarlo a hacerlo .default.

El otro problema era que era inesperado para los usuarios si agregaban una exportación con nombre en el futuro, por ejemplo

export default 4;

entonces

require('./mod');
// 4

pero

export default 4;
export var foo = 5;

entonces

require('./mod')
// {'default': 4, foo: 5}
loganfsmyth avatar Nov 03 '2015 18:11 loganfsmyth

También puede utilizar este complemento para exportrecuperar el comportamiento anterior.

SimenB avatar Nov 15 '2015 22:11 SimenB

Para los autores de bibliotecas, es posible que puedan solucionar este problema.

Normalmente tengo un punto de entrada, index.jsque es el archivo al que apunto desde el campo principal en package.json. No hace nada más que reexportar el punto de entrada real de la biblioteca:

export { default } from "./components/MyComponent";

Para solucionar el problema de Babel, cambié esto a una importdeclaración y luego asigne el valor predeterminado a module.exports:

import MyComponent from "./components/MyComponent";
module.exports = MyComponent;

Todos mis demás archivos permanecen como módulos ES6 puros, sin soluciones alternativas. Así que sólo el punto de entrada necesita un ligero cambio :)

Esto funcionará para los requisitos de commonjs y también para las importaciones de ES6 porque babel no parece haber eliminado la interoperabilidad inversa (commonjs -> es6). Babel inyecta la siguiente función para reparar commonjs:

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 

He pasado horas luchando contra esto, ¡así que espero que esto le ahorre el esfuerzo a alguien más!

WickyNilliams avatar Nov 12 '2015 23:11 WickyNilliams

He tenido ese tipo de problema. Y esta es mi solución:

//src/arithmetic.js

export var operations = {
  add: function (a, b) {
      return a + b;
  },

  subtract: function (a, b) {
      return a - b;
  }
};

//src/main.js

import { operations }  from './arithmetic';

let result = operations.add(1, 1);

console.log(result);
Ihor Pavlyk avatar Apr 21 '2016 00:04 Ihor Pavlyk