¿Cómo exportar correctamente una clase ES6 en el Nodo 4?

4 minutos de lectura

avatar de usuario
Jérôme Verstrynge

Definí una clase en un módulo:

"use strict";

var AspectTypeModule = function() {};
module.exports = AspectTypeModule;

var AspectType = class AspectType {
    // ...    
};

module.export.AspectType = AspectType;

Pero me sale el siguiente mensaje de error:

TypeError: Cannot set property 'AspectType' of undefined
    at Object.<anonymous> (...\AspectType.js:30:26)
    at Module._compile (module.js:434:26)
    ....

¿Cómo debo exportar esta clase y usarla en otro módulo? He visto otras preguntas de SO, pero recibo otros mensajes de error cuando trato de implementar sus soluciones.

  • En ES6 no necesitas 'use strict' en un módulo o clase; es el comportamiento predeterminado. Árbitro. 10.2.1 Código de modo estricto

    – Jason Leach

    14 de noviembre de 2016 a las 0:25

avatar de usuario
sitrakay

// person.js
'use strict';

module.exports = class Person {
   constructor(firstName, lastName) {
       this.firstName = firstName;
       this.lastName = lastName;
   }

   display() {
       console.log(this.firstName + " " + this.lastName);
   }
}
// index.js
'use strict';

var Person = require('./person.js');

var someone = new Person("First name", "Last name");
someone.display();

  • @sitrakay, realmente debería agregar una explicación de cómo esto soluciona la pregunta.

    – Alexis Tyler

    24 de febrero de 2017 a las 6:27

  • esto da el error: TypeError no capturado: no se puede asignar a la propiedad de solo lectura ‘exportaciones’ del objeto ‘# ‘ ¿cómo es que esto se vota tanto?

    – henon

    24 de noviembre de 2018 a las 15:45

  • Creo que poner una definición de clase completa dentro de la asignación de exportaciones es un patrón anti cuando una sola línea al final debería hacer lo mismo.

    – usuario1944491

    8 de mayo de 2020 a las 16:11

  • en mi caso, el display la función no se exporta a menos que esté en el constructor que escribí this.display = display¿alguna idea de por qué?

    – Zennichimaro

    18 de septiembre de 2020 a las 5:19

Si usa ES6 en Node 4, no puede usar la sintaxis del módulo ES6 sin un transpilador, pero los módulos CommonJS (módulos estándar de Node) funcionan de la misma manera.

module.export.AspectType

debiera ser

module.exports.AspectType

de ahí el mensaje de error “No se puede establecer la propiedad ‘AspectType’ de indefinido” porque module.export === undefined.

También por

var AspectType = class AspectType {
    // ...    
};

puedes simplemente escribir

class AspectType {
    // ...    
}

y obtener esencialmente el mismo comportamiento.

  • DIOS MÍO export en vez de exports¿cómo me perdí eso?

    – Jérôme Verstrynge

    18/09/2015 a las 17:48

  • al final pongo module.exports = ClassName y funciona bien

    –David Welborn

    20/09/2017 a las 20:40

avatar de usuario
jonas brandel

Con ECMAScript 2015 puede exportar e importar múltiples clases como esta

class Person
{
    constructor()
    {
        this.type = "Person";
    }
}

class Animal{
    constructor()
    {
        this.type = "Animal";
    }
}

module.exports = {
    Person,
    Animal
};

entonces donde los usas:

const { Animal, Person } = require("classes");

const animal = new Animal();
const person = new Person();

En caso de colisión de nombres, o si prefiere otros nombres, puede renombrarlos así:

const { Animal : OtherAnimal, Person : OtherPerson} = require("./classes");

const animal = new OtherAnimal();
const person = new OtherPerson();

  • Equivocado. Motivo: si usa ES6 en Node 4, no puede usar la sintaxis del módulo ES6 sin un transpilador, pero los módulos CommonJS (los módulos estándar de Node) funcionan de la misma manera. (según arriba)

    – AaronHS

    21 de abril de 2018 a las 15:42

  • Además, no debe declarar dos clases en el mismo archivo.

    – ariel

    3 sep 2018 a las 20:16

  • Está bien tener clases “de tipo privado” (que ayuden a la única clase pública) en el mismo archivo, siempre que las clases privadas no se exporten. También es aceptable si aún no los ha refactorizado en dos archivos. Al hacerlo, no olvide dividir sus pruebas en archivos separados también. O simplemente haga lo que necesite para su situación.

    – TamusJRoyce

    17 de febrero de 2019 a las 8:33


  • @AaronHS, ¿cuál es la diferencia exacta a la que te refieres? Tampoco está claro en la respuesta “arriba”.

    – usuario1944491

    8 de mayo de 2020 a las 16:13

avatar de usuario
mulán

Usar

// aspect-type.js
class AspectType {

}

export default AspectType;

Luego para importarlo

// some-other-file.js
import AspectType from './aspect-type';

Leer http://babeljs.io/docs/learn-es2015/#modules para más detalles

Simplemente lo escribo de esta manera.

en el archivo AspectType:

class AspectType {
  //blah blah
}
module.exports = AspectType;

e importarlo así:

const AspectType = require('./AspectType');
var aspectType = new AspectType;

avatar de usuario
masakielastic

expresión de clase se puede usar para simplificar.

 // Foo.js
'use strict';

// export default class Foo {}
module.exports = class Foo {}

// main.js
'use strict';

const Foo = require('./Foo.js');

let Bar = new class extends Foo {
  constructor() {
    super();
    this.name="bar";
  }
}

console.log(Bar.name);

avatar de usuario
Cajas

Varias de las otras respuestas se acercan, pero, sinceramente, creo que es mejor optar por la sintaxis más limpia y simple. El OP solicitó un medio para exportar una clase en ES6/ES2015. No creo que puedas ser mucho más limpio que esto:

'use strict';

export default class ClassName {
  constructor () {
  }
}

  • Equivocado. Motivo: si usa ES6 en Node 4, no puede usar la sintaxis del módulo ES6 sin un transpilador, pero los módulos CommonJS (los módulos estándar de Node) funcionan de la misma manera. (según arriba)

    – AaronHS

    21 de abril de 2018 a las 15:41

  • ¿Quién diablos sigue usando el Nodo 4? Creo que esta es una respuesta válida para el 99% de las personas.

    – Cajas

    29 de enero de 2019 a las 16:20

  • Está literalmente en el título de la pregunta.

    – AaronHS

    10 de mayo de 2020 a las 2:26

¿Ha sido útil esta solución?