Vite 内など ES Module 指定のフォルダ内で __dirname を通すメモ
Vite 内など ES Module 指定のフォルダ内で __dirname を通すメモです。
背景
Vite で生成したフォルダなど ES Module 指定になっています。
{
"name": "vite-project",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "node server.js & vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"devDependencies": {
"typescript": "^5.2.2",
"vite": "^5.2.0"
},
"dependencies": {
"express": "^4.19.2"
}
}
package.json で "type": "module" な指定をしていると、そうなります。
さてこういった ES Module 指定のフォルダ内で Express での app.use(express.static(__dirname + '/public')); を使ったフォルダ指定など __dirname を使いたいときにエラーになるので、使えるようにしたいことがあります。
console.log(__dirname);
こういう記述があるとして、実行すると
file:///workspaces/vite-server-test/vite-project/app.js:1
console.log(__dirname);
^
ReferenceError: __dirname is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/workspaces/vite-server-test/vite-project/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///workspaces/vite-server-test/vite-project/app.js:1:13
at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
at async loadESM (node:internal/process/esm_loader:28:7)
at async handleMainPromise (node:internal/modules/run_main:113:12)
エラーの内容はこんな感じになります。
__dirname を使えるようにする
というわけで __dirname を通しましょう。
こちらの記事を参考にしつつ、このように修正します。
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
console.log(__dirname);
このように修正すると
/workspaces/vite-server-test/vite-project (main) $ node app.js
/workspaces/vite-server-test/vite-project
と同じように動作するようになりました!
実際、今回のエラーで調べてみると、以下のようにみなさんハマっているようです。
この機会にうまく解消できてよかったです。