Uwzględnianie definicji klasy JavaScript z innego pliku w Node.js.


115

Piszę prosty serwer dla Node.js i używam własnej klasy o nazwie, Userktóra wygląda następująco:

function User(socket) {
    this.socket = socket;
    this.nickname = null;

    /* ... just the typical source code like functions, variables and bugs ... */

    this.write = function(object) {
        this.socket.write(JSON.stringify(object));
    }
};

a później dużo go tworzę:

var server = net.createServer(function (socket) {
    /* other bugs */
    var user = new User(socket);
    /* more bugs and bad practise */
});

Czy mogę przenieść Userdefinicję klasy do innego pliku javascript i w jakiś sposób ją „dołączyć”?

Odpowiedzi:


202

Możesz to po prostu zrobić:

user.js

class User {
    //...
}

module.exports = User

server.js

const User = require('./user.js')

// Instantiate User:
let user = new User()

Nazywa się to modułem CommonJS .

Eksportuj wiele wartości

Czasami może być przydatne wyeksportowanie więcej niż jednej wartości. Na przykład mogą to być klasy, funkcje lub stałe:

user.js

class User {}

exports.User = User
exports.ROLE_ADMIN = 'admin'
exports.ROLE_USER = 'user'
export.isValidUser = function isValidUser() {
    // ...
}

server.js

const {User, ROLE_ADMIN, ROLE_USER, isValidUser} = require('./user.js')

// Instantiate User:
let user = new User()

Moduły ES

Od wersji 14 Node.js można używać modułów ES z CommonJS. Przeczytaj więcej na ten temat w dokumentacji ESM .

Oto przykład tego samego zachowania zaimplementowanego w ESM:

package.json

{
  "type": "module"
}

user.js

export default class User {}

server.js

import User from './user.js'

let user = new User()

Uwaga

⚠️ Nie używaj globali, stwarza to potencjalne konflikty z przyszłym kodem.


co by było, gdyby użytkownik miał jakieś parametry wejściowe, takie jak module.exports = function User (data). Następnie var user = new User (); co zostało zmienione na var user = new User (data) ;?
Grafika C

Tak. Userjest zwykłą funkcją js.
Paul Rumkin,

2
Nie musisz tworzyć stałego użytkownika w server.js. Zmień ostatnią linię users.js na module.exports = new User();Spowoduje to utworzenie nowej instancji użytkownika za każdym razem, gdy wymagany jest moduł. Następnie można po prostu wymaga modułu do każdej zmiennej tak: let user = require('./user.js');.
Nadav

1
@Barnack Jest kilka moich odpowiedzi. Co jest błędne, a które poprawne?
Paul Rumkin

1
@pashaRumkin Utwórz instancję obiektu lokalnie, ale otrzymałem TypeError: <ClassName> nie jest konstruktorem
Md Alamin

13

Używając ES6, możesz mieć user.js:

export default class User {
  constructor() {
    ...
  }
}

A następnie użyj go w server.js

const User = require('./user.js').default;
const user = new User();

dostaję, SyntaxError: Unexpected token exportkiedy robię to, co opisałeś ... mam wersję węzłav10.16.3
thomas

6

Zmodyfikuj definicję klasy, aby brzmiała następująco:

exports.User = function (socket) {
  ...
};

Następnie zmień nazwę pliku na user.js. Zakładając, że znajduje się w katalogu głównym twojego głównego skryptu, możesz dołączyć go w następujący sposób:

var user = require('./user');
var someUser = new user.User();

To jest szybka i brudna wersja. Przeczytaj o modułach CommonJS, jeśli chcesz dowiedzieć się więcej.


2
Co się stało z gniazdem? czy powinno być var ​​someUser = new user.User (gniazdo);
Grafika C

5

Inny sposób, oprócz tych przedstawionych tutaj dla ES6

module.exports = class TEST{
    constructor(size) {
        this.map = new MAp();
        this.size = size;

    }

    get(key) {
        return this.map.get(key);
    }

    length() {
        return this.map.size;
    }    

}

i zawierają to samo co

var TEST= require('./TEST');
var test = new TEST(1);


1

Chcę tylko zwrócić uwagę, że większość odpowiedzi tutaj nie działa, jestem nowy w NodeJS i IDK, jeśli z biegiem czasu metoda "module.exports.yourClass" uległa zmianie lub jeśli ludzie po prostu wpisali błędną odpowiedź.

// MyClass

module.exports.Ninja = class Ninja{
    test(){
        console.log('TESTING 1... 2... 3...');
    };
}
//Using MyClass in seprate File


const ninjaFw = require('./NinjaFw');

let ninja = new ninjaFw.Ninja();
ninja.test();
  • To jest metoda, której obecnie używam. Podoba mi się ta składnia, ponieważ module.exports znajduje się w tym samym wierszu, co deklaracja klasy, a to czyści kod trochę imo. Możesz to zrobić w inny sposób:
//  Ninja Framework File


class Ninja{
    test(){
        console.log('TESTING 1... 2... 3...');
    };
}


module.exports.Ninja = Ninja;
  • Dwie różne składnie, ale w końcu ten sam wynik. Tylko kwestia środków znieczulających na składnię.

0

Zamiast myFile.js napisz swoje pliki jak myFile.mjs. To rozszerzenie zawiera wszystkie zalety es6, ale mam na myśli to, że polecam Ci webpack i Babel

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.