36

I am new to NodeJS so probably I am doing some mistakes.

I have written a bunch of code in an external file called myapp. I start NodeJS for windows and from the interpreter window I type:

var myapp = require('d:/myapp.js');

then I can use my functions and variables in the external module.

The problem is that if I update the code in myapp then the interpreter does not re-read the file and it uses the old version.

Now, is this normal in the first place? How to work around this problem?

P.S.: I have spent hours in internet and searched in many forums including this. It was more confusing then anything else.

Thanks.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
az1mov
  • 469
  • 1
  • 4
  • 3

3 Answers3

31

There are some answers here as suggested in the comments.

However they are not REPL friendly, and might even use extra modules.

Here is a one line solution that you can paste in your REPL, inspired by the discussion on the other question:

function nocache(module) {require("fs").watchFile(require("path").resolve(module), () => {delete require.cache[require.resolve(module)]})}

The function will delete your module from the cache each time the file changes. To use it, just paste it in the REPL, call nocache("d:/myapp.js"), then use require normally.

> function nocache(module) {require("fs").watchFile(require("path").resolve(module), () => {delete require.cache[require.resolve(module)]})}
> nocache("d:/myapp.js");
> var myapp = require("d:/myapp.js");
......
> myapp = require("d:/myapp.js");
....
mihai
  • 37,072
  • 9
  • 60
  • 86
  • 3
    After looking for a quick plug n play solution for a while, I think that your solution is by far the best one out there. You could copy and paste this answer into the tons of similar questions and get a bunch of points. – Nic Szerman Jul 04 '19 at 19:10
  • 1
    Where you write "uncache", you should have written "nocache", right? – Pedro Machado Apr 30 '21 at 19:32
  • 1
    @PedroMachado that is correct, updated answer. Thanks for spotting it. – mihai May 08 '21 at 08:49
17

The other answers (in duplicate and by @mihai) are all correct, but the most direct answer to this specific example, is

delete require.cache['d:/myapp.js'];

The module is cached in require.cache keyed to the full filename. In this particular case, the full filename (i.e. d:/myapp.js) was used to load, and so the solution to the problem is very straight forward.

In most cases, however, the full filename is not used or even known. For example, require('fs') would be used to load the filesystem module, but the developer is as a loss to the full and proper filename. As such, require.resolve('fs') will return the filename used as key to cache the module.

codechimp
  • 1,509
  • 1
  • 14
  • 21
  • 7
    I used `delete require.cache[require.resolve('../path/to/file.js')];` -- easier than finding the full file name – jcollum Feb 03 '21 at 22:49
7

I solved this by adding the following above the require statements:

Object.keys(require.cache).forEach(function(key) { delete require.cache[key] })

Taken from @Dancrumb's comment here

Lee
  • 29,398
  • 28
  • 117
  • 170