https://nodejs.org/api/esm.html#importmetadirname
https://github.com/nodejs/node/pull/48740

import.meta.filename
import.meta.dirname

で取得できます

root@cca30b68b828:/# cat /tmp/a.js
console.log(import.meta.filename)
console.log(import.meta.dirname)

root@cca30b68b828:/# node --experimental-detect-module /tmp/a.js
/tmp/a.js
/tmp

これまでは import.meta.url から自身のファイルのパスを file:// 形式で取得してローカルパス形式に変換する必要がありました

import path from "node:path"
import url from "node:url"

const __filename = url.fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

これを毎回書くのが面倒だったのでかなり便利になりますね



ところで 18 や 20 でも使いたいなと思って Polyfill できないか考えてみました
こんなものを作ってみたのですが 期待通りには動かなかったです

import url from "node:url"
import path from "node:path"

if (!import.meta.filename) {
Object.defineProperties(import.meta, {
filename: {
get() {
return url.fileURLToPath(this.url)
},
},
dirname: {
get() {
return path.dirname(this.filename)
},
},
})
}

import.meta ってグローバルオブジェクト風に見えて 特殊なもので モジュールごとに別の実体があるのでどこかでプロパティを追加しても他のモジュールには影響しないです
プロトタイプのないオブジェクトなので プロトタイプの方を拡張することもできません

loader を使って全モジュールの最初に import.meta.filename などを追加する方法は取れなくもないですが ソースコードを暗黙的に書き換えるようなことはあまりしたくないですし 諦めてバックポートを待とうと思います(需要的に安定すればきっとされるはず)