Incluyendo la definición de clase de JavaScript de otro archivo en Node.js

115

Estoy escribiendo un servidor simple para Node.js y estoy usando mi propia clase llamada Userque se ve así:

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

y luego, más adelante en el proceso, lo estoy instanciando mucho:

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

¿Puedo mover mi Userdefinición de clase a otro archivo javascript e "incluirla" de alguna manera?

martín
fuente

Respuestas:

202

Simplemente puede hacer esto:

user.js

class User {
    //...
}

module.exports = User

server.js

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

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

Esto se llama módulo CommonJS .

Exportar varios valores

A veces puede resultar útil exportar más de un valor. Por ejemplo, podrían ser clases, funciones o 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 la versión 14 de Node.js, es posible usar módulos ES con CommonJS. Lea más sobre esto en la documentación de ESM .

A continuación, se muestra un ejemplo del mismo comportamiento implementado con ESM:

package.json

{
  "type": "module"
}

user.js

export default class User {}

server.js

import User from './user.js'

let user = new User()

Nota

⚠️ No use globales, crea posibles conflictos con el código futuro.

Paul Rumkin
fuente
y si, el usuario tuviera algunos parámetros de entrada, como module.exports = function User (data). Luego, var user = new User (); ¿Qué habría cambiado a var user = new User (data) ;?
Gráficos C
Si. Useres la función js habitual.
Paul Rumkin
2
No es necesario crear el usuario constante en server.js. Cambie la última línea de users.js a module.exports = new User();Esto creará una nueva instancia de Usuario cada vez que se requiera el módulo. A continuación, puede requerir el módulo para cada variable de la siguiente manera: let user = require('./user.js');.
Nadav
1
@Barnack Hay varias respuestas mías. ¿Qué está mal y cuál es correcto?
Paul Rumkin
1
@pashaRumkin Crear una instancia del objeto localmente, pero obtuve TypeError: <ClassName> no es un constructor
Md Alamin
13

Con ES6, puede tener user.js:

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

Y luego úsalo en server.js

const User = require('./user.js').default;
const user = new User();
yedidyak
fuente
obtengo un SyntaxError: Unexpected token exportcuando hago lo que describiste ... tengo la versión de nodov10.16.3
thomas
6

Modifica la definición de tu clase para que se lea así:

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

Luego cambie el nombre del archivo a user.js. Suponiendo que está en el directorio raíz de su script principal, puede incluirlo así:

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

Esa es la versión rápida y sucia. Lea acerca de los módulos CommonJS si desea obtener más información.

Sevenflow
fuente
2
¿Qué pasó con el enchufe? debería ser var someUser = new user.User (socket);
C graphics
5

Otra forma además de las proporcionadas aquí 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 incluir lo mismo que

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

Si agrega esto a user.js:

exports.User = User;

entonces server.jspuedes hacer:

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

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

Otra forma es:

global.User = User;

entonces esto sería suficiente en server.js:

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

Solo quiero señalar que la mayoría de las respuestas aquí no funcionan, soy nuevo en NodeJS e IDK si a lo largo del tiempo el método "module.exports.yourClass" cambió, o si la gente simplemente ingresó la respuesta incorrecta.

// 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 es el método que estoy usando actualmente. Me gusta esta sintaxis, porque module.exports se encuentra en la misma línea que la declaración de clase y eso limpia el código un poco en mi opinión. La otra forma en que puede hacerlo es así:
//  Ninja Framework File


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


module.exports.Ninja = Ninja;
  • Dos sintaxis diferentes pero, al final, el mismo resultado. Es solo una cuestión de anestésicos sintácticos.
Aft3rL1f3
fuente
0

En lugar de myFile.js, escriba sus archivos como myFile.mjs. Esta extensión viene con todas las ventajas de es6, pero me refiero a que te recomiendo webpack y Babel

Ernesto
fuente