I’ve been spending some of my time recently making sure WordPress Playground works in Windows.
While working on Windows fixes I learned a lot about making sure Javascript code works POSIX and Windows when running it in Node.js.
One thing that I learned is that you shouldn’t use URL
to construct paths.
If you construct a path using new URL(import.meta.url)
in Node.js and use pathname
to to obtain the path, it will always have a leading slash in front of the path.
This is ok for POSIX but in Windows it results in invalid paths
like /C:/Users/
.
What to use instead of URL
You can use fileURLToPath
from the URL
package, it will correctly construct both POSIX and Windows paths from file:///
paths.
Polyfilling __dirname and __filename in Node 20+
In Node 20 and above you can use import.meta.filename
and import.meta.dirname
to polyfill __dirname
and __filename
.
Example
import { fileURLToPath } from 'url';
import path from 'path';
const windowsImportMetaUrl = "file:///C:/Users/me/Downloads/index.js";
console.log('windowsImportMetaUrl', windowsImportMetaUrl);
let __dirname = new URL('.', windowsImportMetaUrl).pathname;
let __filename = new URL(windowsImportMetaUrl).pathname;
console.log('__filename', __filename);
console.log('__dirname', __dirname);
__filename = fileURLToPath(
windowsImportMetaUrl,
{
windows: true,
}
);
__dirname = path.win32.dirname(__filename);
console.log('__filename', __filename);
console.log('__dirname', __dirname);
__filename = import.meta.filename;
__dirname = import.meta.dirname;
console.log('__filename', __filename);
console.log('__dirname', __dirname);
The above code will result in:
windowsImportMetaUrl file:///C:/Users/me/Downloads/index.js
# new URL output
__filename /C:/Users/me/Downloads/index.js
__dirname /C:/Users/me/Downloads/
# fileURLToPath output
__filename C:\Users\me\Downloads\index.js
__dirname C:\Users\me\Downloads
# import.meta.filename and import.meta.dirname output
__filename C:\Users\me\Downloads\index.js
__dirname C:\Users\me\Downloads
Leave a Reply