Confusing paths in Windows vs POSIX

Confusing paths in Windows vs POSIX header image

The cool thing about Node.js is the option to write cross platform. So that must have played role in the decision to build the O365 CLI using Node.js. However, we recently encountered a bug in our test on Windows that where working flawlessly on OSX. And while I started my developer career on windows systems, it did bother me that we had this bug. What followed was an interesting discussion on how this could happen and a fix (you can find it on GitHub). A short write-up on what happened.

The famous path options

As described in Writing cross-platform Node.js the biggest issue you will run into is paths. Now that was all working good in the CLI except when we introduced a set of upgrade rules for SPFx. The thing is that the path module gives different results on Windows versus OSX and Linux. That is expected as both systems use a different way of handling paths. However, that could also result in unforeseen consequences. In our case we used the path.join to combine two relative to validate against the contents of a JSON file. Using the path.join on Windows resulted in folder\\file.png versus the folder/file.png on OSX and Linux. You can imagine that if you are then using automated tests to validate if the folder structure is correct it will fail.

But wait why would it then fail on Windows? In our test cases it did fail in the following scenario. We are using the CLI to determine the validity of SPFx packages. These packages contain JSON files with relative paths to other files (like most package.json files do). The thing is, a package.json always writes out the paths as folder/file.png. Never as folder\\file.png. In our case it thus made sense to always make sure we use the / as a separator. Now it took me a bit longer to figure out how to that as there is no easy way to set the separator. Luckily, you do not need to set a separator, but you specify what type of path you want, in our case not the Windows path but the POSIX path. So instead of using path.join we resorted to path.posix.join. The POSIX option is available on all path methods and thus makes it easy to retrieve the correct value.

In case you ever are validating package files, and want to make sure you get expected results, make sure to use the correct path style.

Loading comments…