Как добавить модуль из другого приложения в Node.js

У меня есть два node приложения/службы, которые работают вместе, 1. основное приложение 2. второе приложение

Главное приложение отвечает за то, чтобы в конце показать все данные из разных приложений. Теперь я помещаю код второго приложения в основное приложение и теперь его работаю, но я хочу, чтобы он был развязан. Я имею в виду, что код приложения secnod не будет в главном приложении (каким-то образом, чтобы ввести его во время выполнения)

как и вторая услуга, зарегистрирована в главном приложении, вставляя ее код. код его всего два модуля, возможно ли это сделать в nodejs?

const Socket = require('socket.io-client');
const client = require("./config.json");

module.exports =  (serviceRegistry, wsSocket) =>{
    var ws = null;
    var consumer = () => {
        var registration = serviceRegistry.get("tweets");
        console.log("Service: " + registration);
        //Check if service is online
        if (registration === null) {
            if (ws != null) {
                ws.close();
                ws = null;
                console.log("Closed websocket");
            }
            return
        }
        var clientName = `ws://localhost:${registration.port}/`
        if (client.hosted) {
            clientName = `ws://${client.client}/`;
        }
        //Create a websocket to communicate with the client
        if (ws == null) {
            console.log("Created");
            ws = Socket(clientName, {
                reconnect: false
            });
            ws.on('connect', () => {
                console.log("second service is connected");
            });
            ws.on('tweet', function (data) {
                wsSocket.emit('tweet', data);
            });
            ws.on('disconnect', () => {
                console.log("Disconnected from blog-twitter")
            });
            ws.on('error', (err) => {
                console.log("Error connecting socket: " + err);
            });
        }
    }
    //Check service availability
    setInterval(consumer, 20 * 1000);
}

В основном модуле я помещаю этот код, и я хочу его отделить, введя его каким-то образом во время выполнения? пример будет очень полезен...

Ответ 1

Для этого вам понадобится модуль vm. Более подробная техническая информация здесь https://nodejs.org/api/vm.html. Позвольте мне объяснить, как вы можете это использовать:

  • Вы можете использовать API vm.script для создания скомпилированного кода js из кода, который вы хотите запустить позже. См. Описание из официальной документации.

Создание нового объекта vm.Script компилирует код, но не запускает его. Скомпилированный vm.Script может запускаться несколько раз. Это важно обратите внимание, что код не привязан к глобальному объекту; скорее, это связанный перед каждым прогоном, только для этого прогона.

  1. Теперь, когда вы хотите вставить или запустить этот код, вы можете использовать API script.runInContext.

Еще один хороший пример из их официальной документации:

'use strict';
const vm = require('vm');

let code =
`(function(require) {

   const http = require('http');

   http.createServer( (request, response) => {
     response.writeHead(200, {'Content-Type': 'text/plain'});
     response.end('Hello World\\n');
   }).listen(8124);

   console.log('Server running at http://127.0.0.1:8124/');
 })`;

 vm.runInThisContext(code)(require);

Другой пример непосредственного использования js файла:

var app = fs.readFileSync(__dirname + '/' + 'app.js');
vm.runInThisContext(app);

Вы можете использовать этот подход для условного кода, который вы хотите вставить.

Ответ 3

Существует несколько способов отделить два приложения. Одним из простых способов является шаблон pub/sub (в случае, если вам не нужен ответ).
(Теперь, если у вас есть приложение, которое очень пара, будет очень сложно отделить его, если вы не выполните какой-либо рефакторинг.)
zeromq предлагает очень хорошую реализацию pub/sub и очень быстро.
например,

import zmq from "zmq";
socket.connect('tcp://127.0.0.1:5545');
socket.subscribe('sendConfirmation');

socket.on('message', function (topic, message) {
    // you can get the data from message.
    // something like:
    const msg = message.toString('ascii');
    const data = JSON.parse(msg);
    // do some actions.
    // .....

});

//don't forget to close the socket.
process.on('SIGINT', () => {
    debug("... closing the socket ....");
    socket.close();
    process.exit();
});

//-----------------------------------------
import zmq from "zmq";
socket.bind('tcp://127.0.0.1:5545');
socket.send(['sendConfirmation', someData]);

process.on('SIGINT', function() {
  socket.close();
});

Таким образом, у вас могут быть два разных контейнера (докер) для ваших модулей, просто обязательно откройте соответствующий порт.
Я не понимаю, почему вы вставляете wsSocket, а также создаете новый Socket. Вероятно, я бы просто послал идентификатор сокета, а затем просто используйте его как:

const _socketId = "/#" + data.socketId;     
io.sockets.connected[socketId].send("some message");

Вы также можете использовать другое решение, например kafka вместо zmq, просто подумайте, что это медленнее, но он будет хранить журналы.
Надеюсь, это поможет вам понять, как решить вашу проблему.

Ответ 4

Вы можете использовать функцию связи npm.

Процесс компоновки состоит из двух шагов:

  • Объявление модуля как глобальной ссылки путем запуска ссылки npm в корневой папке модулей
  • Установка связанных модулей в вашем целевом модуле (приложении) путем запуска ссылки npm в целевой папке

Это работает очень хорошо, если только один из ваших локальных модулей не зависит от другого локального модуля. В этом случае соединение не выполняется, поскольку он не может найти зависимый модуль. Чтобы решить эту проблему, нужно связать зависимый модуль с родительским модулем, а затем установить родителя в приложение.

https://docs.npmjs.com/cli/link