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 defaultexportaciones de ES6 en realidad también se denominan exportaciones, excepto que defaultes 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 exportsobjeto, al igual que foo.
Importar el módulo
Podemos importar el módulo de dos maneras: usando CommonJS o usando la importsintaxis ES6 .
Su problema: creo que está haciendo algo como:
var bar = require('./input');
new bar();
esperando que barse 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 defaultpropiedad.
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 barse convierte en acceso .default.
module.exports,exportsymodule.exportstienen valores diferentes, entonces la asignación aexports.defaultsno tiene efecto (porquemodule.exportses 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
SlimShadydebe compilarse usando Babel con'use strict'.Estoy usando
babel-cli6.18.0 en el proyecto donde inicialmente encontré este error.Sin
'use strict'es malas noticias osos'uso estricto', por favor
fuente
importdeclaraciones es un módulo, y esos ya son estrictos. La diferencia real es sobre requerir vs importar.importlugar derequirey enexport defaultlugar deexports.default.