On Writing Platform Independent Node Scripts
One day you write a simple Node script that traverses the file system and copies all the files you need from A-Z to destination folder B. In a matter of seconds your new script will accomplish something that would have taken much longer, in a way that is less error prone.
You make a juicy PR containing your changes. However, when others try to run your script many immediately hit an error:
Error: ENOENT: no such file or directory
Yikes. Your primary development environment is Linux but other people are using Windows. You hard-coded the path to a file you wanted
…but this won’t be recognized by Windows because it doesn’t recognize those forward slashes. You consider using some sort of conditional statement to handle filepaths for these two types of systems, but that seems messy. And the reality is that you shouldn’t do that because there is, in fact, a much cleaner option.
Node’s Path Module
The Node path module is a core module that provides a set of functions/utilities that can be used to deal with filepaths. It is a very useful tool for cross-platform development and is great for open source projects, where different contributors are likely to use different systems.
Windows vs. POSIX
These are the two main file systems a developer will need to worry about when working with Node (both Mac and Linux use POSIX), and most of Path’s functions support both by default. There are a lot of useful utilities provided by this module and you might find it worthwhile to look through them all, but here I’ll cover a few I thought were especially noteworthy and relevant to this post.
At first glance it might seem like this function simply joins filepath segments. However when reading through its documentation you’ll notice it mentions an extra benefit.
path.join()method joins all given
pathsegments together using the platform-specific separator as a delimiter, then normalizes the resulting path.
To avoid hard-coding slashes in filepaths and therefore introducing bugs, path.join should be used instead. This function will output a string with forward or backward slashes based on the system. For example:
path.join('path', 'to', 'file');
// On Linux/Mac returns: 'path/to/file'
// On Windows returns: 'path\to\file'
What if you have a path, and want to create an array from each of its segments? For example, you do something like the following:
'path/to/file'.split('/');// Returns ['path', 'to', 'file'] on Linux/Mac
If you write a function that searches for the
/ delimiter and creates an array based off that, it will create an error on Windows.
'path\\to\\file'.split('/');// Throws error on Windows
To avoid this problem
path.sep can be used. It isn’t a function, but a constant, and will be the path segment separator used by the corresponding system.
// path.sep == '/'
// Returns['path', 'to', 'file'] on Linux/Mac
// path.sep == '\'
// Returns ['path', 'to', 'file'] on Windows
Like path.sep, path.delimiter provides a single constant value; on Windows this will be
; , on POSIX it’s
One place where you’ll likely see this sort of delimiter being used is in the PATH environment variable for your system. So if you ever need to parse that value, path.delimiter will be useful to you.
// On POSIX returns ['/usr/bin', '/bin', '/usr/sbin', '/sbin', '/usr/local/bin']
// On Windows returns ['C:\\Windows\\system32', 'C:\\Windows', 'C:\\Program Files\\node\\']