Git Product home page Git Product logo

node-hotswap's Introduction

Basic usage

Just write this in your main file (or in the repl):

require('hotswap');

And then add this line to modules you want to be reloaded (it tells node-hotswap to watch this file):

module.change_code = 1;

Now if you change your modules, they will be reloaded automatically.

Demo (you have to wait more than 1 second between writings - it's file system limitations):

var fs = require('fs');
var hotswap = require('hotswap');

// writing the initial version of test.js
fs.writeFileSync("hotswap-test.js", "module.exports.version = 0; module.change_code = true;");

// requiring it
var test = require('./hotswap-test')
console.log(test);

hotswap.on('swap', function() {
        // we are going to console.log(test) whenever it's changed
        console.log(test);
});

setTimeout(function() {
        fs.writeFile("hotswap-test.js", "module.exports.version = 1; module.change_code = true;")
}, 1000);

setTimeout(function() {
        fs.writeFile("hotswap-test.js", "module.exports.hi_there = function(){}; module.change_code = true;")
}, 2000);

setTimeout(function() {
        fs.writeFile("hotswap-test.js", "module.exports = {wow: 'thats working'}; module.change_code = true;")
}, 3000);

/* outputs:
 * { version: 0 }
 * { version: 1 }
 * { hi_there: [Function] }
 * { wow: 'thats working' }
 */

What does it do?

This module overrides default functions in require.extension and do some magic there. It remembers all references to exports objects of modules with function module.change_code defined. When module is changed, contents of it's old exports object is replaced with contents of the new one.

// So, this will work fine, m will be changed:
var m = require('hot-swapping-module');

// but "hotswap" have to way to replace m.func with new value
// so dont do this unless you really want to use old code, 
var m.func = require('hot-swapping-module').func;

Events

require('hotswap') returns an EventEmitter that emits the following events:

  • change - when one of the watched modules has changed
  • swap - after successful replacing an old module with a new version
  • error - if there was a filesystem error or something like that

Local variables

When old module is replaced by the new one, local variables of the old module will be lost. If you want to save them, you can use module.change_code.

If module.change_code is defined as a function it will be called before module is reloaded. So you can write up something like that:

module.cache = {} // it's important data you want to save

module.change_code = function(oldmod, newmod, exports_object) {
  newmod.cache = oldmod.cache;
}

Configuration

You can configure node-hotswap using configure function.

require('hotswap').configure({
	// a list of extensions registered by hotswap
	//
	// you can define your own extension for such files if you are afraid 
	// that this module would mess up with some other modules (shouldn't 
	// happen though)
    //
	// default: {'.js': 'js', '.coffee': 'coffee'}
	extensions: {'.js': ['js', 'jsx'], '.coffee': 'coffee'},

	// enable or disable fs.watch() on hotswapping files
	// default: true
	watch: true,

	// automatically reload files on change
	// default: true
	autoreload: true,
});

Todo

I should really write up some good documentation and examples here -_-

node-hotswap's People

Contributors

rlidwka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-hotswap's Issues

Check for syntax errors

This module has been super helpful for me - thank you.

For my use case, I wanted to check each hotswapped file for syntax errors before requiring it. I implemented this here.

Would folks be interested in integrating this feature? Shall I make a PR?

Arrays break it

I tried to enable hotswap for every module (patching it), to see if it works in a real project.

I didn't test the reloading. Just tried to run it.

The app died with undefined is not a function somewhere deep in the modules (under node_modules).

I tried to move require('hotswap') lower in the code, to exclude some modules, so the server actually started running, but then there was another error of the same kind.

To give a glimpse of what's happening:

undefined is not a function

   at Object.<anonymous> (/js/javascript-nodejs/node_modules/image-size/lib/detector.js:7:7)
   at Module._compile (module.js:460:26)
   at extension_js (/js/javascript-nodejs/node_modules/hotswap/hotswap.js:220:10)
   at Module.load (module.js:355:32)
   at Function.Module._load (module.js:310:12)
   at Module.require (module.js:365:17)
   at require (module.js:384:17)
   at Object.<anonymous> (/js/javascript-nodejs/node_modules/image-size/lib/index.js:7:16)

And here I paste the code from the image-size module (from npm):

'use strict';

var typeMap = {};
var types = require('./types');

// load all available handlers
types.forEach(function (type) {
  typeMap[type] = require('./types/' + type).detect;
});

module.exports = function (buffer, filepath) {
  var type, result;
  for (type in typeMap) {
    result = typeMap[type](buffer, filepath);
    if (result) {
      return type;
    }
  }
};

Looks like the reason why doesn't work is types being an array.

Example returns other than expected

The example on the read me only returns the following:

{ version: 0, prototype: undefined }
{ wow: 'thats working', prototype: undefined }

use class will mack an exception

node version: v10.14.0
express
my router.js:
const a = require('../api/test.js');
router.get('/', (req, res, next) => new a(req, res, next).main() );
my test.js
module.change_code = 1;
class test {
constructor(req, res, next) {
this.req = req;
this.res = res;
// super(req, res, next);
}
main() {
const b = {
a: 1,
b: 2
}
this.res.render('index', { title: 'Express11' , ...b})
}
}
module.exports = test;

Hotswap attempts to read/compile source map (".js.map") files

My web application is written in TypeScript. Hotswap is used to swap out the generated JS on the app server. If I generate source maps as well as JS, it looks like Hotswap attempts to read/compile the source map files.

I've played with the configuration but couldn't work out a way to exclude ".js.map" files from hotswap.

Could I be doing something odd in my imports/requires to trigger this behaviour?

Example stack trace:

debugger listening on port 5858
NODE_ENV: development

/Users/laurence/digitalstack/generated/server/models/db/AccessToken.js.map:1
ction (exports, require, module, __filename, __dirname) { {"version":3,"file":
                                                                    ^
SyntaxError: Unexpected token :
    at Module._compile (module.js:439:25)
    at extension_js (/Users/laurence/digitalstack/node_modules/hotswap/hotswap.js:220:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at module.exports.Sequelize.import (/Users/laurence/digitalstack/node_modules/sequelize/lib/sequelize.js:621:63)
    at /Users/laurence/digitalstack/generated/server/models/db/index.js:29:44
    at Array.forEach (native)
    at new DbContainer (/Users/laurence/digitalstack/generated/server/models/db/index.js:28:14)
    at Object.<anonymous> (/Users/laurence/digitalstack/generated/server/models/db/index.js:43:10)
    at Module._compile (module.js:456:26)
    at extension_js (/Users/laurence/digitalstack/node_modules/hotswap/hotswap.js:220:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)

ES6: Importing an instance of a class, using "module.exports = instance;" syntax, does not preserve the prototype/inheritance chain

Please see the project I've set up to reproduce the problem, here:
https://github.com/laurence-myers/hotswap-export-issue

(The project is written in TypeScript, but the JavaScript output is located in the "dist" directory.)

When "module.change_code = 1" is present in the module, a singleton instance, exported as "module.exports", will lose its inheritance chain.

This affects files using ES6 classes and inheritance. When using a custom extends function (like when targeting ES5), it works okay.

In TypeScript, using the syntax "export default instance;" will also fix the problem; presumably, this is because it actually generates the export like "module.exports = { default: instance };".

hotswap tries to compile a streamed file to early

Occasionally, module._compile [line 221] throws a syntax error and crashes the app.
This happens when the watched file is streamed to disk.

I suggest to wrap the module._compile calls in a try-catch-block and emit an event if it fails.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.