본 포스트는 Node.js 에서 모듈 시스템 방식을 ES 방식으로 사용할 경우 __dirname을 찾을 수 없는 오류에 대한 설명입니다.

 

Node.js와 express로 서버를 구성할 때 html 등 Static resources에 대한 경로 설정을 아래와 같이 합니다.

const express = require('express');
const path = require('path');

const app = express();

app.use(express.static(path.join(__dirname, '../public')));
app.get('/', (req,res) => {
    res.sendFile(path.join(__dirname, '../public/index.html'));
});

 

위 소스코드는 static resources는 /public 하위 경로에 두고 초기 화면을 index.html로 설정한 경우이며, 서버를 구동하고 localhost 로 접속하면 /public/index.html을 응답합니다.

 

모듈 시스템을 CommonJS가 아닌 ES 방식을 사용해서 구성하면 require 되신 import ~ from을 사용하여 아래와 같이 작성할 수 있습니다.

import express from "express";
import path from "path";

const app = express();

app.use(express.static(path.join(__dirname, '../public')));
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, '../public/index.html'));
});

 

 

위와 같이 작성한 후 서버를 구동해 보면 아래와 같은 오류가 표시됩니다.

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 '/Users/a20201022/Documents/expressServer/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at file:///Users/a20201022/Documents/expressServer/src/app.js:7:34
    at ModuleJob.run (node:internal/modules/esm/module_job:185:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)
error Command failed with exit code 1.

 

오류 메시지 그대로 __dirname 이라는 전역 변수는 ES 모듈에서는 선언되지 않아 사용할 수 없다는 의미입니다. 해결을 위해서는 해당 변수를 아래와 같이 선언합니다.

import express from "express";
import path from "path";

const app = express();
//__dirname 선언
const __dirname = path.resolve();

app.use(express.static(path.join(__dirname, '../public')));
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, '../public/index.html'));
});

 

위와 같이 작성한 후 서버를 구동해 보면 정상 구동됨을 확인할 수 있습니다.

300x250

본 포스트는 Node.js 에서 모듈 시스템 방식을 ES 방식을 사용했을 경우 발생하는 오류 및 해결에 대한 설명입니다.

 

 

Node.js의 모듈 시스템은 기본적으로 CommonJs 명세를 따릅니다. 하여 모듈을 사용할 경우에는 아래와 같이 require를 사용하여 필요한 모듈을 참조할 수 있습니다.

const express = require('express');

 

하지만 요즘은 많은 프로젝트 들에서 ES 기반의 모듈 시스템을 사용하여 아래와 같이 모듈을 참조할 수 있습니다.

import express from 'express';

 

위 두 구분은 동일한 역할을 하지만 Node.js 애플리케이션을 작성할 때 위와 같이 작성하면 서버를 구동할 때 아래와 같은 오류를 만나게 됩니다.

(node:1463) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/a20201022/Documents/expressServer/src/app.js:1
import express from "express";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1031:15)
    at Module._compile (node:internal/modules/cjs/loader:1065:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:17:47

 

해당 오류를 해결하기 위해서는 package.json에 아래 한 줄을 추가합니다.

{
    "type": "module"
}

 

위 설정은 프로젝트 전체에 적용되며 해당 프로젝트에 ES 기반의 모듈 시스템을 사용할 수 있게 해줍니다.

300x250

+ Recent posts