如何在运行时重新加载所需的模块?

时间:2016-12-03 10:02:18

标签: javascript node.js express babeljs

我想知道如何在运行时重新加载Node.js模块。

假设我有以下代码:

index.js

var myModule = require("./app.js");

app.js

var express = require("express");
express.listen(3000, function() {
    console.log("app listening on port 3000");
});

我尝试了多种方法来重新加载index.js模块中所需的模块。但Express应用程序不会重新启动。

我想保持index.js运行,因为它处理动态重新编译Babel模块。并且需要完全重新启动带有快速服务器的app.js模块。

  

如果没有启动app.js的第二个流程,有没有办法做到这一点?

4 个答案:

答案 0 :(得分:6)

require-uncached是一个npm模块,它将清除缓存并每次从源代码加载模块,这正是您根据标题感兴趣的内容。要使用它,您只需使用以下代码:

const requireUncached = require('require-uncached');
requireUncached('./app.js');

在执行此操作之前,可能需要确保所有先前的app.js代码(包括Express服务器)都已停止,以便它们不会在同一端口发生冲突。

另外,我建议考虑这种方法是否真的 是最佳答案 - 我确信像pm2这样的库可以处理停止和重新启动Node实例而不会有风险不需要的数据,可能会导致内存泄漏。

答案 1 :(得分:2)

如果你要做的只是重新启动服务器而不重新启动过程,我建议使用http.Server.close方法。根据express docs,app.listen方法返回一个http.Server对象,因此重新加载看起来像这样:

app.js

const express = require("express");

app = express();

// Define the listener function separately so it can be used on restart
function listener() {
  console.log("app listening on port 3000");
}

// start the server and save a reference to it for our restart function
const server = app.listen(3000, listener);

// Export a restart function to be used by index.js
exports.restart = function() {
  server.close(function() {
    // Server is closed, start listening again
    server.listen(3000, listener) // Use the same listener function as app.listen
  });
};

index.js

const myModule = require("./app.js"); // Output: "app listening on port 3000"

// Restart the server, keep the process
myModule.restart(); // Output: "app listening on port 3000"

答案 2 :(得分:1)

我建议您在网络包中使用 lazyload ,我在此link中有自己的帖子。

First App

angular.module('myApp', ['ui.router','oc.lazyLoad'])
    .config(function ($stateProvider, $locationProvider, $ocLazyLoadProvider) {
            $stateProvider
                .state("home", {
                    url: "/home",
                    templateUrl: "Home.html",
                    controller: 'homeCtrl',
                    resolve: { 
                        loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
                            return $ocLazyLoad.load('homeCtrl.js');
                        }]
                    }
                })
            .state("profile", {
                url:"/profile",
                templateUrl: "profile.html",
                 resolve: {
                      loadMyCtrl: ['$ocLazyLoad', function ($ocLazyLoad) {
                      return $ocLazyLoad.load('someModule.js');
                        }]
                    }
            })

    });

第二个应用程序

(function () {
var mynewapp=angular.module('someApp',['myApp']);

mynewapp.config(function(){

  //your code to route from here! 

});
      mynewapp.controller("profileCtrl", function ($scope) {

            console.log("reached profile controller");
        });

})();

也是直播Plunker

答案 3 :(得分:0)

现在很简单,我希望自己编写它以减少依赖。


function clearModule(moduleName) {
  let mp = require.resolve(moduleName)
  if (require.cache[mp]) {
    delete require.cache[mp]
    console.log(`[clear] module: ${mp}`)
  }
}

function requireReload(moduleName) {
  clearModule(moduleName);
  return require(moduleName);
}