Node.js ES6 classes com requer

103

Então, até agora, criei classes e módulos node.jsda seguinte maneira:

    var fs = require('fs');

var animalModule = (function () {
    /**
     * Constructor initialize object
     * @constructor
     */
    var Animal = function (name) {
        this.name = name;
    };

    Animal.prototype.print = function () {
        console.log('Name is :'+ this.name);
    };

    return {
        Animal: Animal
    }
}());

module.exports = animalModule;

Agora, com o ES6, você é capaz de criar classes "reais" assim:

class Animal{

 constructor(name){
    this.name = name ;
 }

 print(){
    console.log('Name is :'+ this.name);
 }
}

Agora, em primeiro lugar, adoro isto :) mas levanta uma questão. Como você usa isso combinado com node.jsa estrutura do módulo de?

Digamos que você tenha uma classe na qual deseja usar um módulo para fins de demonstração, digamos que deseja usar fs

então você cria seu arquivo:


Animal.js

var fs = require('fs');
class Animal{

 constructor(name){
    this.name = name ;
 }

 print(){
    console.log('Name is :'+ this.name);
 }
}

Esse seria o caminho certo?

Além disso, como você expõe essa classe a outros arquivos dentro do meu projeto de nó? E você ainda seria capaz de estender esta classe se estiver usando em um arquivo separado?

Espero que alguns de vocês sejam capazes de responder a essas perguntas :)

Marc Rasmussen
fonte
3
Apenas trate o nome da classe ES6 da mesma forma que trataria o nome do construtor da maneira ES5. Eles são um e o mesmo. A sintaxe ES6 é apenas um açúcar sintático e cria exatamente o mesmo protótipo subjacente, função de construtor e objetos.
jfriend00
Aquele IIFE que cria seu animalModuleé bastante inútil em um módulo de nó que tem seu próprio escopo de módulo de qualquer maneira.
Bergi,

Respostas:

156

Sim, seu exemplo funcionaria bem.

Quanto a expor suas aulas, você pode fazer exportuma aula como qualquer outra coisa:

class Animal {...}
module.exports = Animal;

Ou o mais curto:

module.exports = class Animal {

};

Depois de importado para outro módulo, você pode tratá-lo como se estivesse definido naquele arquivo:

var Animal = require('./Animal');

class Cat extends Animal {
    ...
}
Rossipedia
fonte
8
Você também pode fazer algo como module.exports = class Animal {}
Paulo,
é verdade, sempre esqueço que você pode dar nomes às coisas durante a atribuição.
rossipedia,
Tudo se resume ao estilo e à clareza do código. module.exportsé normalmente usado para uma exportação anônima, enquanto exporté usado para uma exportação nomeada. Esta é uma cortesia básica de codificação (você pode dizer), que pode ajudar outras pessoas a saber como importar sua classe, módulo e outros etc.
greg.arnott
7
module.exports = Animal;seria a resposta ou o equivalente mais direto da pergunta e é válido junto com o const Animal = require('./animal');código de chamada. Você pode atualizar sua resposta para incluí-lo?
dom de
1
Obrigado cara, tenho lutado para fazer as importações de classe funcionarem corretamente por 2 horas.
kiwicomb123
11

Apenas trate o nome da classe ES6 da mesma forma que trataria o nome do construtor da maneira ES5. Eles são um e o mesmo.

A sintaxe ES6 é apenas um açúcar sintático e cria exatamente o mesmo protótipo subjacente, função de construtor e objetos.

Então, em seu exemplo ES6 com:

// animal.js
class Animal {
    ...
}

var a = new Animal();

module.exports = {Animal: Animal};

Você pode apenas tratar Animalcomo o construtor do seu objeto (o mesmo que faria no ES5). Você pode exportar o construtor. Você pode chamar o construtor com new Animal(). Tudo é igual para usá-lo. Apenas a sintaxe da declaração é diferente. Ainda existe um Animal.prototypeque contém todos os seus métodos. A maneira ES6 realmente cria o mesmo resultado de codificação, apenas com uma sintaxe mais sofisticada / agradável.


No lado da importação, isso seria usado assim:

const Animal = require('./animal.js').Animal;

let a = new Animal();

Este esquema exporta o construtor Animal como a .Animalpropriedade que permite exportar mais de uma coisa desse módulo.

Se você não precisa exportar mais de uma coisa, pode fazer o seguinte:

// animal.js
class Animal {
    ...
}

module.exports = Animal;

E, em seguida, importe-o com:

const Animal = require('./animal.js');

let a = new Animal();
jfriend00
fonte
Não sei por que, mas isso simplesmente não funcionou para mim. module.exports = Animalé a única solução que funciona.
Sam
1
@Sam - O que minha exportação mostra precisa ser diferente require()do que sua exportação mostra, então é por isso que um funcionaria e o outro não. Você tem que combinar como a importação funciona com a forma como a exportação é definida. Mais detalhes para explicar isso foram adicionados à minha resposta.
jfriend00
5

A maneira ES6 de exigir é import. Você pode exportsua classe e importá-la para outro lugar usando a import { ClassName } from 'path/to/ClassName'sintaxe.

import fs from 'fs';
export default class Animal {

  constructor(name){
    this.name = name ;
  }

  print(){
    console.log('Name is :'+ this.name);
  }
}

import Animal from 'path/to/Animal.js';
Fan Jin
fonte
4
Seria bom esclarecer que esta é uma opção, mas não um requisito. Esta é a sintaxe do módulo ES6, mas você ainda pode usar uma classe ES6 com as exportações CommonJS normais do Node. Não há nenhum requisito de usar a sintaxe de exportação ES6 com classes. Chamar isso The ES6 wayé um pouco enganoso.
loganfsmyth
2
É verdade, é uma preferência pessoal. Pessoalmente, eu usaria importover requireapenas por uma questão de consistência de sintaxe.
Fan Jin
2
Sim, é uma abordagem sólida e eu também faço isso, apenas tenha em mente que a maneira como o Babel importinteropera com os módulos CommonJS provavelmente não vai funcionar no Node, portanto, pode exigir alterações de código no futuro para ser compatível com o Node sem Babel .
loganfsmyth
4
Módulos ES6 (importação e exportação) ainda são experimentais no Nó 10 e precisam ser ativados ao iniciar o nó
dcorking
Para adicionar ao ponto de @dorking. O nó 10.15.3 é a versão LTS (suporte de longo prazo) e ficará até abril de 2020. Detalhes adicionais aqui: nodejs.org/en/about/releases
gtzilla
1

Usando classes no nó -

Aqui, estamos exigindo o módulo ReadWrite e chamando makeObject (), que retorna o objeto da classe ReadWrite. Que estamos usando para chamar os métodos. index.js

const ReadWrite = require('./ReadWrite').makeObject();
const express = require('express');
const app = express();

class Start {
  constructor() {
    const server = app.listen(8081),
     host = server.address().address,
     port = server.address().port
    console.log("Example app listening at http://%s:%s", host, port);
    console.log('Running');

  }

  async route(req, res, next) {
    const result = await ReadWrite.readWrite();
    res.send(result);
  }
}

const obj1 = new Start();
app.get('/', obj1.route);
module.exports = Start;

ReadWrite.js

Aqui estamos fazendo um método makeObject, que garante que um objeto seja retornado, apenas se um objeto não estiver disponível.

class ReadWrite {
    constructor() {
        console.log('Read Write'); 
        this.x;   
    }
    static makeObject() {        
        if (!this.x) {
            this.x = new ReadWrite();
        }
        return this.x;
    }
    read(){
    return "read"
    }

    write(){
        return "write"
    }


    async readWrite() {
        try {
            const obj = ReadWrite.makeObject();
            const result = await Promise.all([ obj.read(), obj.write()])
            console.log(result);
            check();
            return result
        }
        catch(err) {
            console.log(err);

        }
    }
}
module.exports = ReadWrite;

Para obter mais explicações, acesse https://medium.com/@nynptel/node-js-boiler-plate-code-using-singleton-classes-5b479e513f74

Nayan Patel
fonte
0

No arquivo de classe, você pode usar:

module.exports = class ClassNameHere {
 print() {
  console.log('In print function');
 }
}

ou você pode usar esta sintaxe

class ClassNameHere{
 print(){
  console.log('In print function');
 }
}

module.exports = ClassNameHere;

Por outro lado, para usar esta classe em qualquer outro arquivo, você precisa seguir estas etapas. Primeiro, exija esse arquivo usando esta sintaxe: const anyVariableNameHere = require('filePathHere');

Em seguida, crie um objeto const classObject = new anyVariableNameHere();

Depois disso, você pode usar classObjectpara acessar as variáveis ​​de classe reais

Burhan Maseel
fonte