ES Modulesでは__filenameと__dirnameは使えない
Node.jsのES Modulesでは、以下のグローバル変数は存在しないため使用できません。
requireexportsmodule__filename__dirnameglobal
しかし、現状ではこれらの変数を使ったコードをTypeScriptの型チェックで弾く方法はありません。
詳細は以下のissueやdiscussionを参照してください。
現在はDefinitelyTypedが対応するのを待つしかないようです。
__filenameや__dirnameの使用をESLintで弾く
前述したように、TypeScriptの型チェックで弾くことはできません。しかし、実行時エラーになるのは避けたいです。
そこで、ESLitntを使ってこれらの変数を静的解析で弾くことを考えます。
ESLintのFlat Configを使っている場合
languageOptionsプロパティにglobals.nodeではなくglobals.nodeBuiltinを指定します。
import globals from "globals";
// ...(中略)
languageOptions: {
- globals: globals.node,
+ globals: globals.nodeBuiltin,
},
globalsパッケージのnodeBuiltinという定義を利用しています。
For Node.js this package provides two sets of globals:
globals.nodeBuiltin: Globals available to all code running in Node.js. These will usually be available as properties on theglobalobject and includeprocess,Buffer, but not CommonJS arguments likerequire. See: https://nodejs.org/api/globals.htmlglobals.node: A combination of the globals fromnodeBuiltinplus all CommonJS arguments ("CommonJS module scope"). See: https://nodejs.org/api/modules.html#modules_the_module_scopeWhen analyzing code that is known to run outside of a CommonJS wrapper, for example, JavaScript modules, nodeBuiltin can find accidental CommonJS references.
出典:https://www.npmjs.com/package/globals
(翻訳)
Node.jsに対して、このパッケージは2つのグローバル変数の定義を提供します:
globals.nodeBuiltin:Node.jsで実行されるすべてのコードで利用可能なグローバル変数。これらは通常、globalオブジェクトのプロパティとして利用可能で、processやBufferが含まれますが、requireのようなCommonJS用変数は含まれません。参照: https://nodejs.org/api/globals.htmlglobals.node:nodeBuiltinのグローバル変数とCommonJS用の全ての変数の組み合わせ(「CommonJSモジュール・スコープ」)。参照: https://nodejs.org/api/modules.html#modules_the_module_scopeCommonJS以外で実行されることが知られているコード、例えば JavaScript モジュールを分析するとき、
nodeBuiltinは偶発的に参照されているCommonJS変数を見つけることができます。
出典: https://www.npmjs.com/package/globals
他のグローバル変数も無効化したい場合は、以下のように書きます。
import globals from "globals";
// ...(中略)
languageOptions: {
globals: {
...globals.nodeBuiltin,
process: "off", // 例: グローバル変数processを無効化できる
},
},
設定ファイルが.eslintrc形式の場合
Flat Configではなく古い形式の設定ファイルを使っている場合、以下の設定を行うことで個別にグローバル変数を無効化できます。
"env": {
"node": true
},
"globals": {
"require":"off",
"exports":"off",
"module":"off",
"__filename":"off",
"__dirname":"off",
"global":"off"
}
globalsプロパティに使用したくないグローバル変数をoffと設定することで、ソースコード中で使用した場合にESLintでエラーを出すことができます。
まとめ
-
__filenameや__dirnameが使えるのはCommon JSのみ。ES Moduleでは使えない。 - しかし、2023年9月現在ではES Moduleのコードで
__filenameや__dirnameを使っても型エラーにならない。 - ESLintで
__filenameや__dirnameの使用をエラーにするには、以下の方法を使う- Flat Configを使用している場合:
globals.nodeBuiltinを設定する - Flat Configを使用していない場合
globalsプロパティを設定することでグローバル変数の定義を制御できる。
- Flat Configを使用している場合: