Bao gồm định nghĩa lớp JavaScript từ một tệp khác trong Node.js


115

Tôi đang viết một máy chủ đơn giản cho Node.js và tôi đang sử dụng lớp của riêng mình có tên Usergiống như sau:

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

và sau đó trong quá trình này, tôi tạo ra nó rất nhiều:

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

Tôi có thể di chuyển Userđịnh nghĩa lớp của mình sang một tệp javascript khác và "bao gồm" nó bằng cách nào đó không?

Câu trả lời:


202

Bạn chỉ có thể làm điều này:

user.js

class User {
    //...
}

module.exports = User

server.js

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

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

Đây được gọi là mô-đun CommonJS .

Xuất nhiều giá trị

Đôi khi, việc xuất nhiều giá trị có thể hữu ích. Ví dụ, nó có thể là các lớp, hàm hoặc hằng số:

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ô-đun ES

Kể từ phiên bản Node.js 14, bạn có thể sử dụng Mô-đun ES với CommonJS. Đọc thêm về nó trong tài liệu ESM .

Đây là một ví dụ về cùng một hành vi được thực hiện với ESM:

package.json

{
  "type": "module"
}

user.js

export default class User {}

server.js

import User from './user.js'

let user = new User()

Ghi chú

⚠️ Không sử dụng hình cầu, nó có thể tạo ra xung đột với mã trong tương lai.


điều gì sẽ xảy ra nếu Người dùng có một số tham số đầu vào, như module.exports = function Người dùng (dữ liệu). Sau đó, var user = new User (); ai nên đã được thay đổi thành var user = new User (data) ;?
Đồ họa C

Đúng. Userlà hàm js thông thường.
Paul Rumkin

2
Bạn không cần tạo Người dùng cố định trong server.js. Thay đổi dòng cuối cùng của users.js thành module.exports = new User();Điều này sẽ tạo một phiên bản mới của Người dùng mỗi khi mô-đun được yêu cầu. Sau đó, bạn chỉ có thể yêu cầu các module cho mỗi biến như thế này: let user = require('./user.js');.
Nadav

1
@Barnack Có một số câu trả lời của tôi. Cái nào sai và cái nào đúng?
Paul Rumkin

1
@pashaRumkin Instantiate đối tượng cục bộ, nhưng tôi nhận được TypeError: <ClassName> không phải là một hàm tạo
Md Alamin

13

Sử dụng ES6, bạn có thể có user.js:

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

Và sau đó sử dụng nó trong server.js

const User = require('./user.js').default;
const user = new User();

tôi nhận được một SyntaxError: Unexpected token exportkhi tôi làm như bạn mô tả ... tôi có phiên bản nútv10.16.3
thomas

6

Sửa đổi định nghĩa lớp của bạn để đọc như sau:

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

Sau đó đổi tên tệp thành user.js. Giả sử nó nằm trong thư mục gốc của tập lệnh chính, bạn có thể bao gồm nó như sau:

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

Đó là phiên bản nhanh chóng và bẩn thỉu. Đọc về Mô-đun CommonJS nếu bạn muốn tìm hiểu thêm.


2
Điều gì đã xảy ra với ổ cắm? nó phải là var someUser = new user.User (socket);
Đồ họa C

5

Một cách khác ngoài những cách được cung cấp ở đây cho 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;
    }    

}

và bao gồm giống như

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

1

Nếu bạn nối cái này vào user.js:

exports.User = User;

sau đó server.jsbạn có thể làm:

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

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

Một cách khác là:

global.User = User;

thì điều này sẽ là đủ trong server.js:

require('./user.js');

1

Tôi chỉ muốn chỉ ra rằng hầu hết các câu trả lời ở đây không hoạt động, tôi mới sử dụng NodeJS và IDK nếu trong suốt thời gian phương thức "module.exports.yourClass" đã thay đổi hoặc nếu mọi người vừa nhập sai câu trả lời.

// 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();
  • Đây là phương pháp hiện tôi đang sử dụng. Tôi thích cú pháp này, becuase module.exports nằm trên cùng dòng với khai báo lớp và làm sạch mã một chút imo. Cách khác bạn có thể làm là như sau:
//  Ninja Framework File


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


module.exports.Ninja = Ninja;
  • Hai cú pháp khác nhau, nhưng cuối cùng, cùng một kết quả. Chỉ là vấn đề của thuốc mê cú pháp.

0

Thay vì myFile.js, hãy viết các tệp của bạn như myFile.mjs. Tiện ích mở rộng này đi kèm với tất cả các tính năng của es6, nhưng ý tôi là tôi giới thiệu bạn với bạn webpack và Babel

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.