รวมนิยามคลาส 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คำจำกัดความของคลาสไปยังไฟล์จาวาสคริปต์อื่นและ "รวม" ได้หรือไม่

คำตอบ:


203

คุณสามารถทำได้ง่ายๆ:

user.js

class User {
    //...
}

module.exports = User

เซิร์ฟเวอร์ 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() {
    // ...
}

เซิร์ฟเวอร์ js

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

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

โมดูล ES

ตั้งแต่ Node.js เวอร์ชัน 14 จึงสามารถใช้ ES Modules กับ CommonJS ได้ อ่านข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ในเอกสาร ESM

นี่คือตัวอย่างของพฤติกรรมเดียวกันที่ใช้กับ ESM:

package.json

{
  "type": "module"
}

user.js

export default class User {}

เซิร์ฟเวอร์ js

import User from './user.js'

let user = new User()

บันทึก

⚠️อย่าใช้ globals มันจะสร้างความขัดแย้งที่อาจเกิดขึ้นกับรหัสในอนาคต


จะเกิดอะไรขึ้นถ้าผู้ใช้มีพารามิเตอร์อินพุตบางอย่างเช่น module.exports = function User (data) จากนั้นผู้ใช้ var = ผู้ใช้ใหม่ (); จะเปลี่ยนเป็น var user = new User (data);?
กราฟิก C

ใช่. Userเป็นฟังก์ชัน js ปกติ
Paul Rumkin

2
คุณไม่จำเป็นต้องสร้าง User คงที่ใน server.js เปลี่ยนบรรทัดสุดท้ายของ users.js เป็นmodule.exports = new User();สิ่งนี้จะสร้างอินสแตนซ์ใหม่ของ User ทุกครั้งที่ต้องใช้โมดูล let user = require('./user.js');แล้วคุณก็จะต้องโมดูลสำหรับตัวแปรแต่ละตัวเช่นนี้
Nadav

1
@ Barnack มีหลายคำตอบของฉัน ข้อใดผิดและข้อใดถูก
Paul Rumkin

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 = ผู้ใช้ใหม่ผู้ใช้ (ซ็อกเก็ต);
กราฟิก 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();

  • นี่คือวิธีที่ฉันกำลังใช้อยู่ ฉันชอบไวยากรณ์นี้เพราะ module.exports อยู่ในบรรทัดเดียวกับการประกาศคลาสและทำความสะอาดโค้ดด้วย imo เล็กน้อย อีกวิธีหนึ่งที่คุณสามารถทำได้คือ:
//  Ninja Framework File


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


module.exports.Ninja = Ninja;

  • ไวยากรณ์ที่แตกต่างกันสองแบบ แต่สุดท้ายผลลัพธ์ก็เหมือนกัน เพียงแค่เรื่องของยาชาไวยากรณ์

0

แทนที่จะเขียน myFile.js ไฟล์ของคุณเช่น myFile.mjs ส่วนขยายนี้มาพร้อมกับสารพัดของ es6 แต่ฉันหมายความว่าฉันแนะนำให้คุณรู้จักกับ webpack และ Babel

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.