Incluindo a definição de classe JavaScript de outro arquivo em Node.js

115

Estou escrevendo um servidor simples para Node.js e estou usando minha própria classe chamada, Userque se parece com:

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));
    }
};

e mais tarde no processo estou criando várias instâncias:

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

Posso mover minha Userdefinição de classe para outro arquivo javascript e "incluí-lo" de alguma forma?

Martin
fonte

Respostas:

202

Você pode simplesmente fazer isso:

user.js

class User {
    //...
}

module.exports = User

server.js

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

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

Isso é chamado de módulo CommonJS .

Exportar vários valores

Às vezes, pode ser útil exportar mais de um valor. Por exemplo, podem ser classes, funções ou constantes:

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()

Módulos ES

Desde a versão 14 do Node.js, é possível usar Módulos ES com CommonJS. Leia mais sobre isso na documentação do ESM .

Aqui está um exemplo do mesmo comportamento implementado com ESM:

package.json

{
  "type": "module"
}

user.js

export default class User {}

server.js

import User from './user.js'

let user = new User()

Nota

⚠️ Não use globais, isso cria conflitos potenciais com o código futuro.

Paul Rumkin
fonte
e se o usuário tivesse alguns parâmetros de entrada, como module.exports = function User (data). Em seguida, o var user = new User (); que teria sido alterado para var user = new User (data) ;?
Gráficos C de
Sim. Useré a função js usual.
Paul Rumkin de
2
Você não precisa criar o usuário constante em server.js. Altere a última linha de users.js para module.exports = new User();Isso criará uma nova instância de User sempre que o módulo for necessário. Então você pode simplesmente exigir o módulo para cada variável como este: let user = require('./user.js');.
Nadav
1
@Barnack Existem várias respostas minhas. O que está errado e o que está correto?
Paul Rumkin
1
@pashaRumkin Instancie o objeto localmente, mas obtive TypeError: <ClassName> não é um construtor
Md Alamin
13

Usando ES6, você pode ter user.js:

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

E então use-o em server.js

const User = require('./user.js').default;
const user = new User();
Yedidyak
fonte
recebo um SyntaxError: Unexpected token exportquando faço como você descreveu ... tenho a versão do nóv10.16.3
thomas
6

Modifique sua definição de classe para ler assim:

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

Em seguida, renomeie o arquivo para user.js. Supondo que esteja no diretório raiz de seu script principal, você pode incluí-lo desta forma:

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

Essa é a versão rápida e suja. Leia sobre os Módulos CommonJS se quiser saber mais.

sete fluxo
fonte
2
O que aconteceu com o soquete? deve ser var someUser = new user.User (socket);
Gráficos C de
5

Outra forma além das fornecidas aqui para 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;
    }    

}

e inclui o mesmo que

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

Se você anexar isso a user.js:

exports.User = User;

então server.jsvocê pode fazer:

var userFile = require('./user.js');
var User = userFile.User;

http://nodejs.org/docs/v0.4.10/api/globals.html#require

Outra maneira é:

global.User = User;

então isso seria o suficiente em server.js:

require('./user.js');
pimvdb
fonte
1

Só quero salientar que a maioria das respostas aqui não funciona, sou novo no NodeJS e no IDK se ao longo do tempo o método "module.exports.yourClass" mudou ou se as pessoas simplesmente inseriram a resposta errada.

// 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();
  • Este é o método que estou usando atualmente. Eu gosto dessa sintaxe, porque module.exports fica na mesma linha que a declaração de classe e isso limpa o código um pouco mais. A outra maneira de fazer isso é assim:
//  Ninja Framework File


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


module.exports.Ninja = Ninja;
  • Duas sintaxes diferentes mas, no final, o mesmo resultado. É só uma questão de anestésicos de sintaxe.
Aft3rL1f3
fonte
0

Em vez de myFile.js, escreva seus arquivos como myFile.mjs. Esta extensão vem com todas as guloseimas do es6, mas quero dizer, eu recomendo a vocês webpack e Babel

Ernesto
fonte