WABBIT0111
WABBIT0111

Reputation: 2313

nodejs fs.exists() and fs.existsAsync() are deprecated, but why can I still use it with Node v4 and v6

I am reading Nodejs documentation here https://nodejs.org/api/fs.html#fs_fs_exists_path_callback

And it says fs.exists() and fs.existsAsync() are deprecated.

So my intuition would be that it will throw an error if I am using a newer version of NodeJs.

However, using both NodeJs v4.3.2 and v6, I still see the fs.exists() working. why is it so? does that mean that If I migrate my system from NodeJS v0.10.0, I don't necessarily have to update my dependencies that is invoking such function, and it's backward compatible?

Upvotes: 1

Views: 3987

Answers (3)

jfriend00
jfriend00

Reputation: 707836

It means that the community behind node.js development are recommending against using this feature now because it has problems and they MAY get rid of it sometime in the future to force people to stop using it.

So my intuition would be that it will throw an error if I am using a newer version of NodeJs.

They have not yet made it throw an error.

However, using both NodeJs v4.3.2 and v6, I still see the fs.exists() working. why is it so?

And, from the title of your question:

but why can I still use it with Node v4 and v6?

Because though they are recommending against using it now, they have not yet removed it.

does that mean that If I migrate my system from NodeJS v0.10.0, I don't necessarily have to update my dependencies that is invoking such function, and it's backward compatible?

No. The community behind node.js is telling you that they are reserving the right to remove those two functions in any future version.

Bottom line: If you want compatibility with future versions, stop using both fs.exists() now.


fs.exists() is also inconsistent with other node.js async APIs in that the callback is has does not follow the typical calling convention of fn(err, data). It does not have the err parameter which makes it an oddball.

You may also want to understand the reason they are problematic to use. A modern operating system is a multi-tasking system and the file system is a shared resource among potentially many processes. That means that if you do:

if (fs.existsSync("somefile")) {
    // execute some code when somefile does exist 
} else {
    // execute some code when somefile does not exist
}

Then, the state of whether somefile exists or not could change between the time you run the fs.existsSync() call and the time you execute the code that assumes it knows whether the file exists or not. That's called a "race condition" and it's considered very bad design because it creates the possibility for extremely hard-to-reproduce bugs that may hit just occasionally (probably the worst kind of bug to try to find).

Note this directly from the node.js doc for fs.exists():

Using fs.exists() to check for the existence of a file before calling fs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file does not exist.

If you're using the asynchronous version fs.exists(), then the race condition is even worse because your own node.js code could even change the state of the file because your if/else logic runs.

Depending upon what you are generally trying to do, the non-race-condition substitute is to just attempt to open the file with some sort of exclusive access. If the file exists, you will successfully open it with no race condition. If the file did not exist, you will simply get an error and you can then handle that error. In some other cases, you just attempt to create the file with a mode that will fail if it already exists. Both of these situations use an atomic comparison inside the OS file system code so they do not have "race conditions".

You should fix your code now. If you still don't understand what the recommended fix is, then please post your code that is using fs.exists() and the surrounding code context and we can help you with a better design.

Upvotes: 3

Dan Field
Dan Field

Reputation: 21661

Per the documentation

Stability: 0 - Deprecated This feature is known to be problematic, and changes are planned. Do not rely on it. Use of the feature may cause warnings. Backwards compatibility should not be expected.

In other words, it may drop out or otherwise completely stop working at any point without further notice. It may or may not work if/when you migrate.

For what it's worth, it's not atypical to have deprecated features remain for multiple major versions in other software as well. In the OSS world, I've seen deprecated features that lasted for as long as the project was maintained. Presumably because the maintainer/user base had some use for the deprecated feature because it was good enough for their use case (even if it wasn't as good as it should/could have been, and even when a newer API was developed).

Upvotes: 1

Clarence Leung
Clarence Leung

Reputation: 2566

Stability level 0 (or deprecated) in Node.js means it can be removed at anytime, though not necessarily with the immediate next version.

Don't rely on them being backwards-compatible, or even to have similar behaviors across versions even if they are present.

Upvotes: 1

Related Questions