Node.js ES6-Klassen mit erfordern


102

Bis jetzt habe ich Klassen und Module node.jsfolgendermaßen erstellt:

    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;

Mit ES6 können Sie jetzt einfach "aktuelle" Klassen erstellen:

class Animal{

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

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

Nun, zuallererst liebe ich das :) aber es wirft eine Frage auf. Wie nutzen Sie dies in Kombination mit node.jsder Modulstruktur?

Angenommen, Sie haben eine Klasse, in der Sie ein Modul zur Demonstration verwenden möchten. Sagen Sie, Sie möchten es verwenden fs

So erstellen Sie Ihre Datei:


Animal.js

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

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

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

Wäre das der richtige Weg?

Wie können Sie diese Klasse anderen Dateien in meinem Knotenprojekt aussetzen? Und könnten Sie diese Klasse trotzdem erweitern, wenn Sie sie in einer separaten Datei verwenden?

Ich hoffe einige von euch können diese Fragen beantworten :)


3
Behandeln Sie den ES6-Klassennamen genauso, wie Sie den Konstruktornamen auf ES5-Weise behandelt hätten. Sie sind ein und dasselbe. Die ES6-Syntax ist nur syntaktischer Zucker und erstellt genau denselben zugrunde liegenden Prototyp, dieselbe Konstruktorfunktion und dieselben Objekte.
jfriend00

Das IIFE, das Ihr erstellt, animalModuleist in einem Knotenmodul, das ohnehin einen eigenen Modulbereich hat, ziemlich sinnlos.
Bergi

Antworten:


155

Ja, Ihr Beispiel würde gut funktionieren.

Wenn Sie Ihre Klassen verfügbar machen möchten, können Sie exporteine Klasse wie alles andere erstellen:

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

Oder je kürzer:

module.exports = class Animal {

};

Nach dem Import in ein anderes Modul können Sie es so behandeln, als ob es in dieser Datei definiert wäre:

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

class Cat extends Animal {
    ...
}

8
Sie können auch so etwas wie module.exports = class Animal {}
Paul

das ist wahr, ich vergesse immer wieder, dass man Dinge während der Aufgabe benennen kann.
Wikipedia

Es kommt auf den Codestil und die Klarheit an. module.exportswird normalerweise für einen anonymen Export verwendet, während exporter für einen benannten Export verwendet wird. Dies ist eine grundlegende Codierungshöflichkeit (könnte man sagen), die anderen helfen kann, zu wissen, wie Sie Ihre Klasse, Ihr Modul usw. importieren.
Greg.arnott

7
module.exports = Animal;wäre die Antwort oder das direkteste Äquivalent zur Frage und ist zusammen mit dem const Animal = require('./animal');aufrufenden Code gültig . Können Sie Ihre Antwort aktualisieren, um sie aufzunehmen?
Sonne

1
Danke Alter, ich habe 2 Stunden lang darum gekämpft, dass Klassenimporte richtig funktionieren.
Kiwicomb123

11

Behandeln Sie den ES6-Klassennamen genauso, wie Sie den Konstruktornamen auf ES5-Weise behandelt hätten. Sie sind ein und dasselbe.

Die ES6-Syntax ist nur syntaktischer Zucker und erstellt genau denselben zugrunde liegenden Prototyp, dieselbe Konstruktorfunktion und dieselben Objekte.

In Ihrem ES6-Beispiel mit:

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

var a = new Animal();

module.exports = {Animal: Animal};

Sie können einfach Animalwie den Konstruktor Ihres Objekts behandeln (genau wie in ES5). Sie können den Konstruktor exportieren. Sie können den Konstruktor mit aufrufen new Animal(). Für die Verwendung ist alles gleich. Nur die Deklarationssyntax ist unterschiedlich. Es gibt sogar noch eine Animal.prototype, die alle Ihre Methoden enthält. Der ES6-Weg erzeugt wirklich das gleiche Codierungsergebnis, nur mit einer schickeren / schöneren Syntax.


Auf der Importseite würde dies dann folgendermaßen verwendet:

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

let a = new Animal();

Dieses Schema exportiert den Animal-Konstruktor als .AnimalEigenschaft, mit der Sie mehr als eine Sache aus diesem Modul exportieren können.

Wenn Sie nicht mehr als eine Sache exportieren müssen, können Sie dies tun:

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

module.exports = Animal;

Und dann importieren Sie es mit:

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

let a = new Animal();

Ich weiß nicht warum, aber das hat bei mir einfach nicht funktioniert. module.exports = Animalist die einzige Lösung, die funktioniert.
Sam

1
@Sam - Was mein Export zeigt, muss anders sein require()als das, was Ihr Export zeigt. Deshalb würde einer funktionieren und der andere nicht. Sie müssen die Funktionsweise des Imports mit der Definition des Exports abgleichen. Weitere Details, um dies zu erklären, fügten meiner Antwort hinzu.
jfriend00

5

Die ES6-Art der Anforderung ist import. Sie können exportIhre Klasse mithilfe der import { ClassName } from 'path/to/ClassName'Syntax an eine andere Stelle importieren .

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';

4
Es wäre gut zu klären, dass dies eine Option, aber keine Anforderung ist. Dies ist die ES6-Modulsyntax, Sie können jedoch weiterhin eine ES6-Klasse mit den normalen CommonJS-Exporten von Node verwenden. Es ist nicht erforderlich, dass Sie die ES6-Exportsyntax für Klassen verwenden. Es zu nennen The ES6 wayist etwas irreführend.
Loganfsmyth

2
Das stimmt, es ist eine persönliche Präferenz. Persönlich würde ich importover requirenur aus Gründen der Syntaxkonsistenz verwenden.
Fan Jin

2
Ja, es ist ein solider Ansatz, und ich mache es auch. Denken Sie daran, dass die Art und Weise, wie Babel importmit CommonJS-Modulen zusammenarbeitet, wahrscheinlich nicht in Node funktioniert. Daher könnten in Zukunft Codeänderungen erforderlich sein, um mit Node ohne Babel kompatibel zu sein .
Loganfsmyth

4
ES6-Module (Import und Export) sind in Knoten 10 noch experimentell und müssen beim Starten von Knoten
aktiviert

Zum @ dorking-Punkt hinzufügen. Knoten 10.15.3 ist die LTS-Version (Long Term Support) und wird bis April 2020 verfügbar sein. Weitere Details hier: nodejs.org/en/about/releases
gtzilla

1

Verwenden von Klassen im Knoten -

Hier benötigen wir das ReadWrite-Modul und rufen ein makeObject () auf, das das Objekt der ReadWrite-Klasse zurückgibt. Womit wir die Methoden aufrufen. 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

Hier erstellen wir eine makeObject-Methode, die sicherstellt, dass ein Objekt nur zurückgegeben wird, wenn ein Objekt nicht verfügbar ist.

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;

Weitere Erklärungen finden Sie unter https://medium.com/@nynptel/node-js-boiler-plate-code-using-singleton-classes-5b479e513f74


0

In der Klassendatei können Sie entweder Folgendes verwenden:

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

oder Sie können diese Syntax verwenden

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

module.exports = ClassNameHere;

Um diese Klasse in einer anderen Datei zu verwenden, müssen Sie diese Schritte ausführen. Benötigen Sie zuerst diese Datei mit dieser Syntax: const anyVariableNameHere = require('filePathHere');

Dann erstellen Sie ein Objekt const classObject = new anyVariableNameHere();

Danach können Sie classObjectauf die eigentlichen Klassenvariablen zugreifen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.