Classes Node.js ES6 avec require

104

Donc jusqu'à présent, j'ai créé des classes et des modules de node.jsla manière suivante:

    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;

Maintenant avec ES6, vous pouvez créer des classes "réelles" comme ceci:

class Animal{

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

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

Maintenant, tout d'abord, j'adore ça :) mais cela soulève une question. Comment utilisez-vous cela combiné avec node.jsla structure des modules de?

Disons que vous avez une classe où vous souhaitez utiliser un module à des fins de démonstration, dites que vous souhaitez utiliser fs

donc vous créez votre fichier:


Animal.js

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

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

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

Serait-ce la bonne manière?

De plus, comment exposez-vous cette classe à d'autres fichiers dans mon projet de nœud? Et seriez-vous toujours en mesure d'étendre cette classe si vous l'utilisez dans un fichier séparé?

J'espère que certains d'entre vous pourront répondre à ces questions :)

Marc Rasmussen
la source
3
Traitez simplement le nom de la classe ES6 de la même manière que vous auriez traité le nom du constructeur à la manière ES5. Ils sont identiques. La syntaxe ES6 n'est que du sucre syntaxique et crée exactement le même prototype sous-jacent, la même fonction constructeur et les mêmes objets.
jfriend00
Cet IIFE qui crée votre animalModuleest assez inutile dans un module de nœud qui a de toute façon sa propre portée de module.
Bergi

Réponses:

157

Oui, votre exemple fonctionnerait bien.

Quant à exposer vos classes, vous pouvez exportune classe comme n'importe quoi d'autre:

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

Ou le plus court:

module.exports = class Animal {

};

Une fois importé dans un autre module, vous pouvez le traiter comme s'il était défini dans ce fichier:

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

class Cat extends Animal {
    ...
}
Rossipedia
la source
8
Vous pouvez également faire quelque chose comme module.exports = class Animal {}
Paul
c'est vrai, j'oublie toujours que vous pouvez nommer des choses pendant la mission.
rossipedia
Cela se résume au style et à la clarté du code. module.exportsest généralement utilisé pour une exportation anonyme, tandis que exportpour une exportation nommée. C'est une courtoisie de codage de base (vous pourriez dire), qui peut aider les autres à savoir comment importer votre classe, module et autres, etc.
greg.arnott
7
module.exports = Animal;serait la réponse ou l'équivalent le plus direct de la question et est valide avec le const Animal = require('./animal');code d'appel. Pouvez-vous mettre à jour votre réponse pour l'inclure?
dim
1
Merci mec, je me bats pour que les importations de classes fonctionnent correctement depuis environ 2 heures.
kiwicomb123
11

Traitez simplement le nom de la classe ES6 de la même manière que vous auriez traité le nom du constructeur à la manière ES5. Ils sont identiques.

La syntaxe ES6 n'est que du sucre syntaxique et crée exactement le même prototype sous-jacent, la même fonction constructeur et les mêmes objets.

Donc, dans votre exemple ES6 avec:

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

var a = new Animal();

module.exports = {Animal: Animal};

Vous pouvez simplement traiter Animalcomme le constructeur de votre objet (comme vous l'auriez fait dans ES5). Vous pouvez exporter le constructeur. Vous pouvez appeler le constructeur avec new Animal(). Tout est pareil pour son utilisation. Seule la syntaxe de la déclaration est différente. Il y a même toujours un Animal.prototypequi a toutes vos méthodes dessus. La manière ES6 crée vraiment le même résultat de codage, juste avec une syntaxe plus sophistiquée / plus agréable.


Du côté de l'importation, cela serait alors utilisé comme ceci:

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

let a = new Animal();

Ce schéma exporte le constructeur Animal en tant que .Animalpropriété qui vous permet d'exporter plus d'un élément de ce module.

Si vous n'avez pas besoin d'exporter plus d'une chose, vous pouvez le faire:

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

module.exports = Animal;

Et puis importez-le avec:

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

let a = new Animal();
jfriend00
la source
Je ne sais pas pourquoi mais cela n'a tout simplement pas fonctionné pour moi. module.exports = Animalest la seule solution qui fonctionne.
Sam le
1
@Sam - Ce que mon exportation montre a besoin d'un différent require()de ce que votre exportation montre, c'est pourquoi l'un fonctionnerait et l'autre pas. Vous devez faire correspondre la façon dont l'importation fonctionne avec la façon dont l'exportation est définie. Plus de détails pour expliquer cela ajouté à ma réponse.
jfriend00 du
6

La manière ES6 d'exiger est import. Vous pouvez exportvotre classe et l'importer ailleurs en utilisant la import { ClassName } from 'path/to/ClassName'syntaxe.

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
la source
4
Il serait bon de préciser qu'il s'agit d'une option, mais non d'une exigence. Il s'agit de la syntaxe du module ES6, mais vous pouvez toujours utiliser une classe ES6 avec les exportations CommonJS normales de Node. Il n'est pas nécessaire d'utiliser la syntaxe d'exportation ES6 avec les classes. L'appeler The ES6 wayest quelque peu trompeur.
loganfsmyth
2
C'est vrai, c'est une préférence personnelle. Personnellement, j'utiliserais importover requirejuste pour des raisons de cohérence syntaxique.
Fan Jin
2
Oui, c'est une approche solide et je le fais aussi, gardez simplement à l'esprit que la façon dont Babel importinteragit avec les modules CommonJS n'est pas susceptible de fonctionner dans Node, donc cela pourrait nécessiter des changements de code à l'avenir pour être compatible avec Node sans Babel .
loganfsmyth
4
Les modules ES6 (importation et exportation) sont encore expérimentaux dans Node 10 et doivent être activés lors du lancement du nœud
dcorking
Pour ajouter au point de @ dorking. Node 10.15.3 est la version LTS (support à long terme) et le sera jusqu'en avril 2020. Détails supplémentaires ici: nodejs.org/en/about/releases
gtzilla
1

Utilisation des classes dans Node -

Ici, nous avons besoin du module ReadWrite et appelons un makeObject (), qui renvoie l'objet de la classe ReadWrite. Ce que nous utilisons pour appeler les méthodes. 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

Ici, nous créons une méthode makeObject, qui s'assure qu'un objet est retourné, uniquement si un objet n'est pas disponible.

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;

Pour plus d'explications, rendez-vous sur https://medium.com/@nynptel/node-js-boiler-plate-code-using-singleton-classes-5b479e513f74

Nayan Patel
la source
0

Dans le fichier de classe, vous pouvez soit utiliser:

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

ou vous pouvez utiliser cette syntaxe

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

module.exports = ClassNameHere;

En revanche, pour utiliser cette classe dans tout autre fichier, vous devez effectuer ces étapes. Exigez d'abord ce fichier en utilisant cette syntaxe: const anyVariableNameHere = require('filePathHere');

Puis créez un objet const classObject = new anyVariableNameHere();

Après cela, vous pouvez utiliser classObjectpour accéder aux variables de classe réelles

Burhan Maseel
la source