From 52ee1ea5c5db973ed9681faefcd042eb1066f075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A3=A8=EB=B0=80LuMir?= Date: Sat, 14 Sep 2024 23:20:10 +0900 Subject: [PATCH] docs(post): create when-loading-files-in-a-server-...-dirname.md --- ...ent-should-i-use-process-cwd-or-dirname.md | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/docs/languages/nextjs/when-loading-files-in-a-server-component-should-i-use-process-cwd-or-dirname.md diff --git a/src/docs/languages/nextjs/when-loading-files-in-a-server-component-should-i-use-process-cwd-or-dirname.md b/src/docs/languages/nextjs/when-loading-files-in-a-server-component-should-i-use-process-cwd-or-dirname.md new file mode 100644 index 0000000..28ecaac --- /dev/null +++ b/src/docs/languages/nextjs/when-loading-files-in-a-server-component-should-i-use-process-cwd-or-dirname.md @@ -0,0 +1,100 @@ +# 서버 컴포넌트에서 파일을 불러올 때, `process.cwd()`와 `__dirname` 중 어떤 것을 사용해야 할까? + +**Vercel**(**Next.js**)의 공식 가이드 [How to Load Data from a File in Next.js](https://vercel.com/guides/loading-static-file-nextjs-api-route)를 읽다 문득 궁금한 점이 생겼다. + +```javascript +import { promises as fs } from 'fs'; + +export default async function Page() { + const file = await fs.readFile(process.cwd() + '/app/data.json', 'utf8'); + //... +} +``` + +앞선 공식 가이드 링크에서 언급된 위 코드를 살펴보자. 불러올 파일의 경로를 지정할 때 `process.cwd()`를 사용한다. 이때, Node.js의 전역변수인 `__dirname`을 대신 사용하면 안되는 것일까? + +## 1. `process.cwd()`와 `__dirname` + +`process.cwd()`와 `__dirname`은 Node.js에서 현재 디렉토리를 나타내지만, 사용하는 상황과 의미가 다르다. + +### 1-1. [`process.cwd()`](https://nodejs.org/api/process.html#processcwd) + +현재 프로세스를 시작한 디렉토리를 반환하며, 이는 프로세스를 실행한 위치에 따라 변할 수 있다. 즉, 코드가 있는 위치와는 관계없이 동작하며, 현재 프로세스가 실행되는 작업 디렉토리(working directory)를 반환한다. + +- 동작 방식: Node.js 프로세스가 시작될 때의 디렉토리를 기준으로 반환한다. +- 특징: `process.chdir()`을 통해 작업 디렉토리를 변경할 수 있다. + +### 1-2. [`__dirname`](https://nodejs.org/docs/latest/api/globals.html#__dirname) + +실행 중인 JavaScript 파일이 위치한 폴더의 경로를 반환하며, 고정된 경로를 제공한다. 즉, 프로세스를 실행한 위치와는 무관하게 파일 위치를 기준으로 하며, 현재 JavaScript 파일이 저장된 디렉토리에 따른 경로만을 나타낸다. + +- 동작 방식: 실행 중인 JavaScript 파일의 저장 위치를 기준으로 반환한다. +- 특징: `__dirname`은 고정되어 있으며, 항상 파일이 저장된 디렉토리 경로만을 반환한다. + +### 1-3 예시 + +현재 작업 디렉토리를 `/`(루트)라 하자. `/my-folder` 경로에 아래와 같은 JavaScript 파일을 만든다. (이때, 작업 디렉토리는 여전히 `/`여야 한다.) + +```javascript +/* code.js */ + +console.log(process.cwd()); +console.log(__dirname); +``` + +아래 명령어를 통해 `/my-folder/code.js`파일을 실행한다. + +```bash +node my-folder/code.js +``` + +출력 결과는 아래와 같다. + +```bash +/ # process.cwd() +/my-folder # __dirname +``` + +## 2. **Next.js** 서버 컴포넌트에서의 활용 + +Next.js에서는 `__dirname`을 사용하는 것이 일반적인 Node.js 환경과 다르게 동작할 수 있다. 그 이유는 Next.js가 빌드 타임에 코드를 번들링하고, 서버와 클라이언트 환경을 구분하기 때문이다. Next.js에서 `__dirname`은 서버에서 실행될 때 번들링된 파일의 경로를 가리키기에, 예상과는 다른 경로를 반환할 수 있어 주의해야 한다. + +### 2-1. 차이점 + +1. `process.cwd()`: 현재 프로세스를 실행하는 디렉토리, 즉 **프로젝트 루트 디렉토리**를 반환한다. Next.js의 경우, 이는 주로 프로젝트의 루트 디렉토리를 가리키며, 파일을 찾을 때 사용하기 적합하다. + +1. `__dirname`: 현재 파일이 위치한 디렉토리를 반환하는데, Next.js에서는 이 값이 번들링된 파일의 경로가 될 수 있다. 즉, Next.js가 빌드하고 배포한 후에는 경로가 다르게 동작할 수 있어 상대 경로를 설정하기 어려울 수 있다. + +### 2-2. 예시 + +```javascript +/* /src/app/page.js */ + +export default function Page() { + return ( + <> +

process.cwd(): {process.cwd()}

+

__dirname: {__dirname}

+ + ); +} +``` + +현재 작업 디렉토리를 `/`(루트)라 하자. 위 코드에서 `page.js`가 위치한 디렉토리는 `/src/app`이다. 만약, `__dirname`을 사용하여 특정 파일을 불러온다면, `path.resolve()`등의 함수와 조합하여 `/src/app/../data/data.json`과 같은 상대 경로를 이용하는 경우가 많을 것이다. + +하지만, Next.js 빌드 후 `__dirname`이 번들링된 파일의 경로로 바뀌기에 원하는 파일을 찾지 못할 가능성이 매우 높아진다. 즉, 우리가 기대한 `__dirname`의 경로는 `/src/app`이었지만, 실제로는 `/.next/server/app`과 같은 번들링된 파일의 경로가 반환된다. 앞선 코드를 브라우저의 HTML에서 살펴보면, 아래와 같이 출력된다. + +```text +process.cwd(): / +__dirname: /.next/server/app +``` + +### 2-3. 결론 + +Next.js 프로젝트에서 파일 경로를 찾을 때는 `process.cwd()`를 사용하는 것이 훨씬 안정적이다. `process.cwd()`는 항상 프로젝트의 루트 디렉토리를 가리키기 때문에, 파일 경로를 지정할 때 더 일관성 있게 사용할 수 있다. **따라서, Next.js 환경에서는 `__dirname`보다는 `process.cwd()`의 사용을 권장한다.** + +## Reference + +- +- +-