Включення визначення класу 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 = функція User (дані). Тоді var user = new User (); що було б змінено на var user = new User (дані) ;?
C графіка

Так. Userє звичайною функцією js.
Пол Румкін

2
Вам не потрібно створювати постійного користувача в server.js. Змініть останню рядок users.js на Налаштування module.exports = new User();цього користувача створюватиме новий примірник кожного разу, коли потрібен модуль. Тоді ви можете просто зажадати модуль для кожної змінної , як це: let user = require('./user.js');.
Надав

1
@Barnack Є кілька моїх відповідей. Що неправильно, а що правильно?
Пол Румкін

1
@pashaRumkin Об’єкт Instantiate локально, але я отримав TypeError: <ClassName> не є конструктором
Md Alamin

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
thomas

6

Змініть визначення свого класу таким чином:

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

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

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

Це швидка та брудна версія. Читайте про модулі CommonJS, якщо хочете дізнатися більше.


2
Що сталося з сокетом? чи має бути var someUser = новий користувач.User (socket);
C графіка

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

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();
  • Це метод, який я зараз використовую. Мені подобається цей синтаксис, becuase module.exports сидить у тому ж рядку, що і декларація класу, і це трохи очищає код. Інший спосіб, як ви це зробите, такий:
//  Ninja Framework File


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


module.exports.Ninja = Ninja;
  • Два різних синтаксису, але, зрештою, той самий результат. Просто питання синтаксичних знеболюючих засобів.

0

Замість myFile.js запишіть файли як myFile.mjs. Це розширення постачається з усіма смакотами es6, але я маю на увазі, що рекомендую вам веб-пакунок та Babel

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.