El problema es con
- Cómo se emulan los módulos ES6 en CommonJS
- cómo importas el módulo
ES6 a CommonJS
Al momento de escribir esto, ningún entorno admite módulos ES6 de forma nativa. Al usarlos en Node.js, debe usar algo como Babel para convertir los módulos a CommonJS. Pero, ¿cómo sucede eso exactamente?
Muchas personas consideran module.exports = ...
equivalente export default ...
y exports.foo ...
equivalente a export const foo = ...
. Sin embargo, eso no es del todo cierto, o al menos no cómo lo hace Babel.
Las default
exportaciones de ES6 en realidad también se denominan exportaciones, excepto que default
es un nombre "reservado" y hay un soporte especial de sintaxis para ello. Veamos cómo compila Babel las exportaciones con nombre y predeterminadas:
// input
export const foo = 42;
export default 21;
// output
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var foo = exports.foo = 42;
exports.default = 21;
Aquí podemos ver que la exportación predeterminada se convierte en una propiedad del exports
objeto, al igual que foo
.
Importar el módulo
Podemos importar el módulo de dos maneras: usando CommonJS o usando la import
sintaxis ES6 .
Su problema: creo que está haciendo algo como:
var bar = require('./input');
new bar();
esperando que bar
se le asigne el valor de la exportación predeterminada. Pero como podemos ver en el ejemplo anterior, la exportación predeterminada se asigna a la default
propiedad.
Entonces, para acceder a la exportación predeterminada, en realidad tenemos que hacer
var bar = require('./input').default;
Si usamos la sintaxis del módulo ES6, a saber
import bar from './input';
console.log(bar);
Babel lo transformará a
'use strict';
var _input = require('./input');
var _input2 = _interopRequireDefault(_input);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
console.log(_input2.default);
Puede ver que cada acceso a bar
se convierte en acceso .default
.
module.exports
,exports
ymodule.exports
tienen valores diferentes, entonces la asignación aexports.defaults
no tiene efecto (porquemodule.exports
es lo que se exporta). En otras palabras, es exactamente lo mismo que si solo lo hicierasmodule.exports = { ... }
.Debe configurar Babel correctamente en su proyecto para usar el valor predeterminado de exportación y exportar
luego agregue la siguiente configuración en .babelrc
fuente
Felix Kling hizo una gran comparación con esos dos, para cualquiera que se pregunte cómo hacer un valor predeterminado de exportación junto con las exportaciones nombradas con module.exports en nodejs
fuente
tl; dr ahora para que esto funcione, el archivo que requiere o importa
SlimShady
debe compilarse usando Babel con'use strict'
.Estoy usando
babel-cli
6.18.0 en el proyecto donde inicialmente encontré este error.Sin
'use strict'
es malas noticias osos'uso estricto', por favor
fuente
import
declaraciones es un módulo, y esos ya son estrictos. La diferencia real es sobre requerir vs importar.import
lugar derequire
y enexport default
lugar deexports.default
.