Включение определения класса JavaScript из другого файла в Node.js

115

Я пишу простой сервер для Node.js и использую свой собственный класс, Userкоторый выглядит так:

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

а затем позже в процессе я часто создаю его экземпляры:

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

Могу ли я переместить Userопределение моего класса в другой файл javascript и каким-то образом "включить" его?

Мартин
источник

Ответы:

202

Вы можете просто сделать это:

user.js

class User {
    //...
}

module.exports = User

server.js

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

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

Это называется модулем CommonJS .

Экспорт нескольких значений

Иногда бывает полезно экспортировать более одного значения. Например, это могут быть классы, функции или константы:

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

Модули ES

Начиная с Node.js версии 14, можно использовать модули ES с CommonJS. Подробнее об этом читайте в документации по ESM .

Вот пример того же поведения, реализованного в ESM:

package.json

{
  "type": "module"
}

user.js

export default class User {}

server.js

import User from './user.js'

let user = new User()

Заметка

⚠️ Не используйте глобальные переменные, это создает потенциальные конфликты с будущим кодом.

Пол Рамкин
источник
что, если у пользователя есть некоторые входные параметры, например module.exports = function User (data). Затем var user = new User (); что могло быть изменено на var user = new User (data) ;?
C graphics
Да. Userэто обычная функция js.
Paul Rumkin
2
Вам не нужно создавать постоянного пользователя в server.js. Измените последнюю строку файла users.js на. module.exports = new User();Это будет создавать новый экземпляр User каждый раз, когда потребуется модуль. Тогда вы можете просто потребовать модуль для каждой переменной , как это: let user = require('./user.js');.
Надав
1
@Barnack Есть несколько моих ответов. Что не так, а что правильно?
Павел Рамкин
1
@pashaRumkin Создать экземпляр объекта локально, но я получил TypeError: <ClassName> не является конструктором
М. Д. Аламин
13

Используя ES6, вы можете user.js:

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

А затем использовать его в server.js

const User = require('./user.js').default;
const user = new User();
едидяк
источник
я получаю, SyntaxError: Unexpected token exportкогда делаю, как вы описали ... у меня есть версия узлаv10.16.3
Томас
6

Измените определение вашего класса, чтобы оно выглядело так:

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

Затем переименуйте файл в user.js. Предполагая, что он находится в корневом каталоге вашего основного скрипта, вы можете включить его следующим образом:

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

Это быстрая и грязная версия. Прочтите о модулях CommonJS, если хотите узнать больше.

семипоток
источник
2
Что случилось с сокетом? должно ли это быть var someUser = new user.User (socket);
C graphics
5

Другой способ в дополнение к представленным здесь для 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;
    }    

}

и включить то же, что и

var TEST= require('./TEST');
var test = new TEST(1);
Гаурав Рават
источник
1

Если вы добавите это в user.js:

exports.User = User;

тогда server.jsвы можете:

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

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

Другой способ:

global.User = User;

тогда этого будет достаточно server.js:

require('./user.js');
pimvdb
источник
1

Я просто хочу указать, что большинство ответов здесь не работают, я новичок в NodeJS и IDK, если с течением времени метод "module.exports.yourClass" менялся или люди просто вводили неправильный ответ.

// 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();
  • Я использую этот метод в настоящее время. Мне нравится этот синтаксис, потому что module.exports находится в той же строке, что и объявление класса, и это немного очищает код imo. Другой способ сделать это:
//  Ninja Framework File


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


module.exports.Ninja = Ninja;
  • Два разных синтаксиса, но в итоге один и тот же результат. Просто вопрос синтаксической анестезии.
Aft3rL1f3
источник
0

Вместо myFile.js напишите свои файлы вроде myFile.mjs. Это расширение поставляется со всеми преимуществами es6, но я имею в виду, что рекомендую вам webpack и Babel

Эрнесто
источник