ES Modulesでは__filename
と__dirname
は使えない
Node.jsのES Modulesでは、以下のグローバル変数は存在しないため使用できません。
require
exports
module
__filename
__dirname
global
しかし、現状ではこれらの変数を使ったコードを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 theglobal
object and includeprocess
,Buffer
, but not CommonJS arguments likerequire
. See: https://nodejs.org/api/globals.htmlglobals.node
: A combination of the globals fromnodeBuiltin
plus 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を使用している場合: