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
と同じように動作するようになりました!
実際、今回のエラーで調べてみると、以下のようにみなさんハマっているようです。
この機会にうまく解消できてよかったです。