1.시스템&인프라/개발환경

Node.js(v20.19) 개발환경 세팅: ESLint·Prettier·VSCode·CI까지

쿼드큐브 2025. 11. 18. 09:03
반응형
반응형

 

Node.js(v20.19) 개발환경 세팅: ESLint·Prettier·VSCode·CI까지

 

📚 목차
1. 프로젝트 시작: init과 package-json 구조 이해
2. 코드 품질의 기본: ESLint + Prettier 설치와 설정
3. 개발 효율 극대화: VSCode 확장과  settings.json 통합
4. 자동화의 완성: 저장시 포맷팅 & CI에서 포맷 검증
✔ 마무리 - 개발환경은 곧 개발자의 속도이다

 

Node.js 개발환경 세팅 삽화 이미지
Node.js 개발환경 세팅 삽화 이미

 

 

✔️ VSCode + Node.js 설치하기: VSCode에서 Node.js 포터블 다중 버전 관리하기

 

VSCode에서 Node.js 포터블 다중 버전 관리하기

VSCode에서 Node.js 포터블 다중 버전 관리하기 📚 목차1. Node.js 포터블 설치란?2. 여러 Node.js 버전 병행 설치와 관리3. VS Code에서 프로젝트별 Node.js 버전 자동 적용4. 포터블 Node.js 다중 버전 자동 전

quadcube.tistory.com

 

 

1. 프로젝트 시작:   init과 package.json 구조 이해

🔷Node.js 프로젝트의 첫걸음

모든 Node.js 프로젝트는 단 하나의 명령어에서 시작됩니다.

  init -y

이 명령을 실행하면 루트 디렉토리에 package.json 파일이 생성됩니다.

이 파일은 Node.js 생태계에서 프로젝트의 “정체성 카드이자 통합 설정서” 역할을 합니다.

▸ 어떤 이름(name)으로 배포되는지
▸ 어떤 버전(version)을 사용 중인지
▸ 어떤 명령(script)을 실행할 수 있는지
▸ 어떤 의존성(dependencies)이 필요한지

 

이 모든 정보가 package.json 안에 담겨 있습니다.

 

> Docs › package.json

“The package.json
file is the heart of any Node.js project. It records important metadata about your project and defines functional scripts.”

 

🔷 package.json 기본 구조 예시

아래는 실무에서 많이 사용하는 TypeScript 기반 Node.js 프로젝트의 기본 형태입니다.

{
  "name": "my-node-project",
  "version": "1.0.0",
  "description": "Node.js + TypeScript 실무형 개발환경 예제",
  "main": "dist/index.js",
  "type": "module",
  "scripts": {
    "dev": "node --watch dist/index.js",
    "build": "tsc -p tsconfig.json",
    "lint": "eslint src --ext .ts,.js",
    "format": "prettier --write ."
  },
  "author": "Your Name",
  "license": "MIT"
}
필드 역할 설명
"name" 패키지 이름 배포 시 식별자 역할을 하며, 공백 없이 소문자·하이픈 사용 권장
"version" 프로젝트 버전 SemVer(유의적 버전 규칙: Major.Minor.Patch) 사용
"description" 설명 문서화 및 검색용 설명
"main" 진입 파일 CommonJS 시절의 엔트리 포인트(require() 기준)
"type": "module" 모듈 시스템 ESM 모듈(import/export) 활성화. Node.js 14+부터 정식 지원
"scripts" 실행 명령 단축어 run <명령>으로 스크립트 실행 가능
"author" / "license" 메타데이터 프로젝트 저작자와 라이선스 정보

 

✔️ type: "module" - 2025년 Node.js의 표준 문법

2025년 현재, Node.js는 기본적으로 ESM (ECMAScript Module) 사용을 권장합니다.

"type": "module"을 명시하면 브라우저처럼 import/export 구문을 그대로 사용할 수 있습니다.

// ESM 스타일 (권장)
import fs from "node:fs";
import path from "node:path";

console.log("ESM 기반 Node.js 환경입니다.");

만약 생략하면 Node.js는 CommonJS(require, module.exports)로 인식합니다.

정리: > Modules: ECMAScript modules
🔸 import/export를 사용하려면 반드시 "type": "module" 필요
🔸 CJS 모듈을 혼용하려면 .cjs 확장자를 명시적으로 사용

 

✔️ scripts - 의 생산성 핵심

scripts는  에서 제공하는 간단한 명령어 매핑 기능입니다.
매번 긴 명령어를 기억하지 않아도, run을 통해 일관된 실행 흐름을 구성할 수 있습니다.


예를 들어 위 설정에서 다음 명령들이 정의되어 있습니다

명령어 내용
run dev Node.js가 dist/index.js 파일을 감시(--watch)하며 실행
run build TypeScript를 tsconfig.json 기준으로 컴파일
run lint ESLint로 src 디렉터리 내 코드 검사
run format Prettier로 모든 코드 포맷팅

💡팁:
▸  7 이상에서는   run 생략이 가능합니다.

▸ 예:   run build →   build 도 동작합니다.

 

✔️ dependencies vs devDependencies

나중에 추가할 ESLint, Prettier, TypeScript 같은 도구들은 개발용이므로 --save-dev (혹은 단축 -D) 옵션으로 설치해야 합니다.

  install -D typescript eslint prettier
구분 목적 배포시 포함여부
dependencies 런타임 의존성 (실행 시 필요) ✅ 포함됨
devDependencies 개발용 도구 (빌드, 테스트, 린트 등) ❌ 미포함

이렇게 구분해두면 프로덕션 빌드 시 불필요한 의존성이 배포되지 않아 더 가볍고 안전합니다.

 

🔷 corepack으로 패키지 매니저 버전 관리하기

Node.js 20 이상에서는 corepack이 기본 탑재되어 있습니다.

이 도구는 프로젝트별로   / p  / yarn 버전을 고정할 수 있게 해 줍니다.

corepack enable

이후 package.json에 다음 필드를 추가하면 됩니다

"packageManager": "p @9.0.0"

장점 > Corepack 공식 문서
▸ 팀 전체가 동일한 패키지 매니저 버전을 사용
▸ CI/CD 환경에서도 동일한 환경을 재현 가능
▸ , p , yarn 모두 지원

 

2. 코드 품질의 기본: ESLint + Prettier 설치와 설정

Node.js + TypeScript 프로젝트에서 “코드 품질”과 “코드 스타일”을 유지하는 핵심 도구는 단연 ESLint와 Prettier입니다.

2025년 현재 ESLint는 Flat Config(ESM 기반 eslint.config.js)를 표준으로 채택하고 있으며,

npx eslint --init 명령만으로도 Flat Config + TypeScript 지원 설정이 자동 생성됩니다.

아래에서는 최소한의 수동 설치로, 최신 방식에 맞춰 ESLint와 Prettier를 실무 환경에서 통합하는 전체 흐름을 정리합니다.

 

🔷 1단계 - ESLint 자동 초기화 (npx eslint --init)

Flat Config 시스템은 ESLint v9.0.0에서 “기본 구성 파일 형식(default configuration format)”으로 전환되었다고 합니다.

프로젝트 루트에서 다음 명령을 실행합니다.

npx eslint --init

이 명령을 실행하면 ESLint의 공식 설정 생성기 @eslint/create-config가 호출되어, 프로젝트에 맞는 설정을 만들기 위한 일련의 질문을 보여줍니다.

 

💡 예시 질문 흐름
실제로 실행하면 다음과 같은 과정이 진행됩니다:
1. What do you want to lint?
→ JavaScript, JSON 등 검사할 파일 형식을 선택
2. How would you like to use ESLint?
→ 문법 오류와 문제만 검사할지, 스타일 규칙까지 포함할지 선택 (일반적으로 “problems” 선택)
3. What type of modules does your project use?
→ ESM ("type": "module") 환경 선택
4. Does your project use TypeScript?
→ Yes 선택 → TypeScript 린팅 자동 구성
5. Where does your code run?
→ browser, node 등 환경 선택
6. Which language do you want your configuration file be written in?
→ JavaScript 

ESLint 자동 초기화 설정화면
ESLint 자동 초기화 설정화면
초기화 후 설치된 패키지 목록
초기화 후 설치된 패키지 목록

 

✔️ 생성된 Flat Config 이해하기

자동 생성된 eslint.config.mjs 예시는 다음과 같습니다:

// @eslint/js: ESLint 공식 JavaScript 규칙 세트
import js from "@eslint/js";

// globals: Node.js, Browser 등의 전역 변수 정의 모음
import globals from "globals";

// typescript-eslint: TypeScript 코드를 검사하기 위한 공식 통합 패키지
import tseslint from "typescript-eslint";

// @eslint/json: JSON 파일 린팅을 위한 플러그인
import json from "@eslint/json";

// defineConfig: Flat Config를 더 명확하고 안전하게 정의하도록 도와주는 헬퍼
import { defineConfig } from "eslint/config";

export default defineConfig([
  // -----------------------------
  // 1) JavaScript + TypeScript 공통 규칙
  // -----------------------------
  {
    // 검사할 파일 확장자 지정
    // js/mjs/cjs → JS 파일, ts/mts/cts → TS 파일
    files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],

    // 사용할 플러그인 등록 (여기선 JS 기본 플러그인만)
    plugins: { js },

    // JavaScript 공식 권장 규칙 적용
    // js/recommended는 ESLint 팀에서 제공하는 기본 베스트 프랙티스
    extends: ["js/recommended"],

    // Node.js 환경에서 제공하는 전역 변수 생략 가능하도록 설정
    // 예: require, module, __dirname 등
    languageOptions: {
      globals: globals.node,
    },
  },

  // -----------------------------
  // 2) TypeScript 권장 규칙 적용
  // -----------------------------
  // TypeScript 코드를 올바르게 분석하고 검사하기 위한 기본 규칙 모음
  // 타입 기반 검사(recommendedTypeChecked)는 포함되지 않은 "가벼운 기본세트"
  tseslint.configs.recommended,

  // -----------------------------
  // 3) JSON 파일 전용 규칙
  // -----------------------------
  {
    // JSON 파일만 대상으로 하는 별도의 규칙 집합
    files: ["**/*.json"],

    // JSON 플러그인 사용
    plugins: { json },

    // JSON 전용 언어 파서 적용
    language: "json/json",

    // JSON 문법 오류 및 기본 스타일 검사
    extends: ["json/recommended"],
  },
]);

 

 

🔷 2단계 - Prettier 설치 및 스타일 구성

ESLint는 “코드 품질(문제 탐지)”을 담당하고, Prettier는 “코드 스타일(형식)”을 담당합니다.

두 도구는 목적이 다르므로 별도로 설치해야 합니다.

  install -D prettier eslint-config-prettier

 

✔️ .prettierrc 파일 생성

이 설정은 포맷팅 규칙을 프로젝트 전체에서 일관적으로 유지하기 위한 기반입니다.

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 100,
  "endOfLine": "lf"
}
옵션 의미
semi 세미콜론 사용
singleQuote 문자열 작은따옴표
tabWidth 들여쓰기 2칸
trailingComma 마지막 요소에도 쉼표
printWidth 100자에서 줄바꿈
endOfLine LF로 통일

 

 

🔷 3단계 - ESLint와 Prettier 충돌 방지

ESLint와 Prettier는 서로 역할이 다른 도구입니다.
🔸 ESLint는 코드 품질을 검사합니다.

      (사용되지 않는 변수, 위험한 코드 패턴, 잘못된 import 등)
🔸Prettier는 코드 ‘스타일’을 책임집니다.
     (들여쓰기, 줄바꿈, 따옴표, 세미콜론 등)


문제는, ESLint도 스타일 관련 규칙을 일부 포함하고 있다는 점입니다.

따라서 Prettier가 자동으로 포맷팅 한 코드가 ESLint의 스타일 규칙에 의해 다시 오류로 잡히는 충돌이 발생할 수 있습니다.


이 충돌을 제거하는 가장 확실하고 현대적인 방식이 바로 eslint-config-prettier를 Flat Config의 마지막에 추가하는 것입니다.

 

✔️ 왜 “Flat Config의 마지막”이어야 할까?

Flat Config는 배열 순서대로 규칙이 적용됩니다.

따라서 후순위에 있는 설정이 앞의 설정을 “덮어씌우는(overwrite)” 구조입니다.

즉:
1. JS 추천 규칙 적용
2. TS 추천 규칙 적용
3. JSON 규칙 적용
4. Prettier와 충돌하는 스타일 규칙 모두 비활성화 ← 마지막에 위치
이 순서를 유지해야 모든 스타일 규칙이 완전히 제거됩니다.

 

✔️ 자동 생성된 설정에 Prettier 통합하기(2026.01.09 보완)

import js from '@eslint/js'; // v9.39.2
import globals from 'globals'; // v17.0.0
import tseslint from 'typescript-eslint'; // v8.52.0
import json from '@eslint/json'; // v0.14.0
import prettier from 'eslint-config-prettier'; // v10.1.8
import { defineConfig } from 'eslint/config'; // eslint v9.39.2

export default defineConfig([
  /**
   * --------------------------------------------------------------------
   * 1. 전역 무시 패턴 설정
   * --------------------------------------------------------------------
   * - 적용 기준:
   *   ESLint v9.39.2 (Flat Config 기본 구조)
   *
   * - ESLint가 검사하지 않아야 할 파일/폴더를 지정합니다.
   * - node_modules, 빌드 산출물, 커버리지 결과물 등은
   *   린트 대상이 아니므로 미리 제외합니다.
   *
   * - Flat Config에서는 ignores 설정을
   *   설정 배열의 가장 앞에 두는 것이 공식적으로 권장됩니다.
   */
  {
    ignores: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**', '**/coverage/**'],
  },

  /**
   * --------------------------------------------------------------------
   * 2. JavaScript / TypeScript Recommended Config 적용
   * --------------------------------------------------------------------
   * - 적용 패키지 및 버전:
   *   - @eslint/js v9.39.2
   *   - typescript-eslint v8.52.0
   *
   * - @eslint/js:
   *   ESLint 공식 JavaScript 권장 규칙 세트입니다.
   *   최신 ECMAScript 문법과 일반적인 코드 품질 규칙을 포함합니다.
   *
   * - typescript-eslint:
   *   TypeScript AST 파싱 및 타입 기반 정적 분석을 수행하며,
   *   TS 전용 권장 규칙을 제공합니다.
   *
   * - tseslint.configs.recommended 는 배열 형태이므로
   *   스프레드 연산자(...)로 풀어서 등록합니다.
   */
  js.configs.recommended,
  ...tseslint.configs.recommended,

  /**
   * --------------------------------------------------------------------
   * 3. JavaScript + TypeScript 공통 Language Options 설정
   * --------------------------------------------------------------------
   * - 적용 기준:
   *   - ESLint v9.39.2 (Flat Config)
   *   - globals v17.0.0
   *
   * - Flat Config에서는 기존 parserOptions 대신
   *   languageOptions 객체를 사용합니다.
   *
   * - ecmaVersion: 'latest'
   *   → 현재 설치된 ESLint가 지원하는 최신 ECMAScript 문법을 활성화합니다.
   *
   * - sourceType: 'module'
   *   → ESM(import/export) 기반 프로젝트 구조를 사용합니다.
   *
   * - globals.node (globals v17.0.0):
   *   → Node.js 런타임에서 제공되는 전역 변수(process, Buffer 등)를
   *     ESLint가 미정의 변수로 오탐하지 않도록 설정합니다.
   */
  {
    files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
    languageOptions: {
      ecmaVersion: 'latest',
      sourceType: 'module',
      globals: {
        ...globals.node,
      },
    },
  },

  /**
   * --------------------------------------------------------------------
   * 4. JSON 파일 전용 규칙 설정 (@eslint/json 최신 방식)
   * --------------------------------------------------------------------
   * - 적용 패키지 및 버전:
   *   - @eslint/json v0.14.0
   *
   * - JSON 파일은 JavaScript 파서로 해석할 수 없기 때문에
   *   전용 language 설정이 필요합니다.
   *
   * - @eslint/json 최신 버전에서는
   *   parser 대신 language 키워드를 사용합니다.
   *
   *   language: 'json/json'
   *   → JSON 문법을 올바르게 파싱하고 구조 오류를 검증합니다.
   *
   * - json.configs.recommended.rules:
   *   → 잘못된 JSON 문법, 중복 키, 구조 오류 등을 자동 검출합니다.
   */
  {
    files: ['**/*.json'],
    plugins: { json },
    language: 'json/json',
    rules: {
      ...json.configs.recommended.rules,
    },
  },

  /**
   * --------------------------------------------------------------------
   * 5. Prettier와 ESLint 규칙 충돌 방지
   * --------------------------------------------------------------------
   * - 적용 패키지 및 버전:
   *   - prettier v3.7.4
   *   - eslint-config-prettier v10.1.8
   *
   * - eslint-config-prettier는
   *   코드 포맷팅과 충돌하는 ESLint 규칙을 모두 비활성화합니다.
   *
   * - 실제 코드 스타일(들여쓰기, 줄바꿈, 따옴표 등)은
   *   Prettier가 전담하도록 역할을 분리합니다.
   *
   * - 반드시 설정 배열의 가장 마지막에 위치해야
   *   앞에서 정의한 규칙들을 올바르게 덮어쓸 수 있습니다.
   */
  prettier,
]);

 

🔷 4단계 - package.json 스크립트 구성

ESLint와 Prettier는 모두 CLI(Command Line Interface) 명령어를 제공하는데,

이를 매번 긴 명령으로 실행하는 대신 package.json의 "scripts" 영역에 짧은 명령으로 등록해 두면 훨씬 효율적입니다.

아래 스크립트는 실무에서 가장 많이 사용하는 4가지 구성입니다:

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  }
}

 

package.json 예시

{
  "name": "typescript-examples",
  "version": "1.0.0",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check ."
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "@eslint/js": "^9.39.1",
    "@eslint/json": "^0.14.0",
    "eslint": "^9.39.1",
    "eslint-config-prettier": "^10.1.8",
    "globals": "^16.5.0",
    "prettier": "^3.6.2",
    "typescript-eslint": "^8.46.4"
  }
}

 

✔️ "type": "module" 이 없어도 되는 이유

왜냐하면 ESLint 설정파일이 .mjs 로 생성되었기 때문입니다.

.mjs 확장자는 Node.js에서 언제나 ESM(ECMAScript Module)로 취급되므로, package.json에 "type": "module"을 넣지 않아도 ESM이 정상 동작합니다.

 

실행 예시

1)   run lint
→ 프로젝트 전체 파일을 검사하여 코드 오류와 잠재적 문제를 찾아냅니다.

2)   run lint:fix
→ ESLint가 자동으로 고칠 수 있는 문제들을 즉시 수정합니다.

3)   run format
→ Prettier가 프로젝트 전체 코드를 팀 규칙에 맞게 자동으로 포맷팅합니다.

4)   run format:check
→ Prettier 규칙이 잘 지켜졌는지만 검사하고 자동 수정은 하지 않습니다.
반응형

 

3. 개발 효율 극대화: VSCode 확장과 settings.json 통합

이제 프로젝트에 ESLint와 Prettier가 설치되고 설정까지 완료되었다면, 이 도구들이 VS Code 내부에서 자연스럽게 작동하도록 연결해야 합니다.

이 단계부터는 “설정이 잘 되어 있는 개발환경”이 자동으로 개발자를 도와주는 단계입니다.

즉, 따로 포맷을 신경 쓰지 않아도 되고, 린트 경고도 눈으로 즉시 확인할 수 있으며, 저장만 해도 코드가 깔끔해지는 환경이 완성됩니다.

 

Node.js + TypeScript 기반 프로젝트라면 아래 두 확장은 사실상 기본 구성요소입니다.

둘이 함께 있어야 완전한 자동 포맷팅 환경이 완성됩니다.

 

🔷 필수 확장 설치

이 두 확장은 에디터 레벨에서의 자동화 및 시각화를 담당하고, 실제 린트/포맷 엔진은   install --save-dev eslint prettier … 형태로 프로젝트에 설치되어 있어야 제대로 동작합니다.

 

🔸 ESLint (Marketplace ID: dbaeumer.vscode-eslint)

프로젝트 내 node_modules 등에 설치된 ESLint 엔진을 활용하여 실시간 코드 검사 및 자동 수정(fix) 기능을 제공합니다.

ESLint 확장 설치
ESLint 확장 설치

 

🔸 Prettier – Code Formatter (Marketplace ID: esbenp.prettier-vscode)

코드 포맷터로서, 팀 내 동일한 코드 스타일을 적용하고 저장 시 자동으로 포맷팅 되도록 도와줍니다

Prettier 확장 설치
Prettier 확장 설치

 

🔷 .vscode/settings.json 구성 예시 - 동일한 에디터 환경 유지

아래는 팀별 워크스페이스 수준에서 적용할 수 있는 settings.json 예시입니다. 루트 폴더에 .vscode/settings.json으로 두어 팀원 모두 동일한 에디터 환경을 유지하도록 합니다.

{
  // ===============================================================
  // 1) 저장 시 포맷팅과 ESLint 자동 수정
  // ---------------------------------------------------------------
  // "editor.formatOnSave": true
  //   → 파일을 저장할 때 VSCode가 자동으로 Prettier를 실행해 코드를 포맷팅함.
  //
  // "editor.codeActionsOnSave":
  //   → 파일 저장 시 실행할 "코드 액션"을 정의하는 영역.
  //   → 여기서는 ESLint의 "자동 수정(fix)" 기능을 활성화하여
  //     사용하지 않는 변수, 미사용 import 등 "자동 고칠 수 있는 문제"를 저장할 때 자동으로 해결함.
  //
  // 주의:
  //   VSCode 1.75+ 부터 "source.fixAll.eslint"는 boolean이 아닌
  //   string("explicit", "always", "never")만 허용됨.
  // ===============================================================
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit" // 저장 시 ESLint 자동 수정 실행
  },

  // ===============================================================
  // 2) Prettier를 VSCode 전체의 기본 포맷터로 고정
  // ---------------------------------------------------------------
  // 여러 포맷터가 설치되어 있을 경우 충돌을 막기 위해 반드시 필요.
  // (예: VSCode 내장 JS 포맷터와 충돌 방지)
  //
  // Prettier가 포맷팅의 "최종 결정권"을 가지게 하여 팀의 스타일 일관성을 유지함.
  // ===============================================================
  "editor.defaultFormatter": "esbenp.prettier-vscode",

  // ===============================================================
  // 3) TypeScript 버전을 workspace(local) 버전으로 고정
  // ---------------------------------------------------------------
  // VSCode는 기본적으로 자체 내장된 TypeScript 버전을 사용하려고 함.
  // 하지만 프로젝트별로 TypeScript 버전을 맞춰야 린트/빌드 오류가 일관됨.
  //
  // "node_modules/typescript/lib" 로 경로를 지정하면,
  // 해당 프로젝트에 설치된 TypeScript 버전이 VSCode에서도 사용됨.
  // ===============================================================
  "typescript.tsdk": "node_modules/typescript/lib",

  // ===============================================================
  // 4) 파일 탐색기 & 검색에서 불필요 폴더 제외
  // ---------------------------------------------------------------
  // 개발자가 매번 'node_modules'나 빌드 산출물(Dist/Build 폴더)을 열 필요가 없음.
  // 성능 향상 + 탐색기 가독성 향상 효과가 있음.
  //
  // search.exclude는 VSCode의 '검색' 기능에서 제외하는 설정.
  // ===============================================================
  "files.exclude": {
    "**/node_modules": true,
    "**/dist": true,
    "**/build": true,
    "**/coverage": true
  },
  "search.exclude": {
    "**/node_modules": true,
    "**/dist": true,
    "**/build": true,
    "**/coverage": true
  },

  // ===============================================================
  // 5) 코드 스타일 보조 기능 (Prettier가 최종 결정, VSCode는 보조 역할)
  // ---------------------------------------------------------------
  // "editor.tabSize": 2
  //   → Prettier의 "tabWidth": 2 와 일치시켜 VSCode UI에서도 동일하게 보이도록 함.
  //
  // "editor.insertSpaces": true
  //   → 소프트 탭(스페이스) 사용. Prettier와 동일.
  //
  // "files.trimTrailingWhitespace": true
  //   → 줄 끝 공백 자동 제거. Prettier도 동일한 동작을 하므로 UX 향상.
  //
  // "files.insertFinalNewline": true
  //   → 파일 끝에 자동으로 newline 추가. Prettier "endOfLine" 설정과도 호환됨.
  // ===============================================================
  "editor.tabSize": 2,
  "editor.insertSpaces": true,
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true,

  // ===============================================================
  // 6) Windows 환경 — Portable Node.js 버전 고정
  // ---------------------------------------------------------------
  // Node.js를 전역 설치하지 않고 “폴더형 Node.js”를 프로젝트별로 사용하고 싶은 경우
  // VSCode 내장 터미널이 항상 해당 Node 버전을 사용하도록 PATH를 재정의.
  //
  // 예:
  //   D:\NodejsDevelope\node-v20.19.5
  //
  // 이렇게 하면 프로젝트마다 독립적인 Node 버전을 사용할 수 있어
  // 버전 충돌 문제를 크게 줄일 수 있음.
  // ===============================================================
  "terminal.integrated.env.windows": {
    "PATH": "D:\\NodejsDevelope\\node-v20.19.5;${env:PATH}"
  },

  // ===============================================================
  // 7) Prettier 고급 설정
  // ---------------------------------------------------------------
  // "prettier.requireConfig": true
  //   → .prettierrc 파일이 없는 프로젝트에서는 Prettier가 실행되지 않음.
  //     즉, 프로젝트에 정의된 Prettier 규칙만 사용하도록 강제하여
  //     팀 전체의 동일한 포맷 규칙을 보장함.
  // ===============================================================
  "prettier.requireConfig": true,

  // ===============================================================
  // 8) 파일 이동 시 import 자동 업데이트
  // ---------------------------------------------------------------
  // 파일을 이동하거나 이름을 변경하면,
  // 해당 파일을 import하는 모든 경로를 TypeScript/JavaScript 언어 서버가 자동으로 업데이트함.
  //
  // 대규모 프로젝트에서 매우 유용하며, 경로 오류 예방에 효과적.
  // ===============================================================
  "typescript.updateImportsOnFileMove.enabled": "always",
  "javascript.updateImportsOnFileMove.enabled": "always"
}

 

🔷 .vscode/extensions.json - 팀 추천 확장 목록 공유

.vscode/extensions.json 파일을 프로젝트 루트에 두어 추천 확장 목록을 공유할 수 있습니다. 

이렇게 하면 팀원이 프로젝트를 처음 열었을 때 VS Code가 “이 확장을 설치하시면 좋습니다”라고 제안하게 됩니다.

{
  "recommendations": [
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode"
  ]
}

 

4. 자동화의 완성: 저장 시 포맷팅 & CI에서 포맷 검증

“자동 포맷팅(Prettier) + 자동 코드 품질 체크(ESLint)”는
로컬 편집기(VS Code)에서 시작해 Git Hooks(Husky), CI(GitHub Actions)까지
일관된 기준으로 적용되어야 한다.”

 

코드 품질은 개별 개발자의 습관에 의존해선 안 됩니다.
이 섹션에서는 VS Code 자동 포맷팅 → Git 커밋 단계 자동 검증 → CI 단계 품질 보증으로 이어지는 완성도 높은 코드 품질 관리 파이프라인을 구축합니다.

 

🔷 VSCode 저장 시 자동 포맷팅 자동화 (Format on Save)

저장할 때 Prettier와 ESLint가 동시에 동작하도록 구성하려면, 프로젝트 내부의 .vscode/settings.json 에 다음 설정을 포함해야 합니다.

// settings.json
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": "explicit" // 저장 시 ESLint 자동 수정 실행
},

 ▸ 파일 저장 시( Ctrl+S / Cmd+S )
1. VSCode는 Prettier 확장(esbenp.prettier-vscode)으로 기본 포맷을 수행합니다.
2. 이어서 ESLint의 자동 수정(source.fixAll.eslint)이 적용됩니다.
3. 최종적으로 Prettier + ESLint 규칙이 모두 통일된 코드가 저장됩니다.

즉, 개발자는 “포맷 버튼”을 누를 필요 없이, 그저 저장만 해도 정렬·정돈된 코드가 자동으로 완성됩니다.

 

✔️ 실무 팁

▸ “팀 전체가 같은 포맷팅 경험”을 갖기 위해 .vscode/settings.json은 반드시 Git에 포함하세요.
▸ 사용자(global) 설정보다 workspace 설정이 우선하므로, 팀 환경이 강하게 표준화됩니다.
▸ TypeScript 버전 충돌을 방지하려면 다음을 추가하는 것이 좋습니다:

"typescript.tsdk": "node_modules/typescript/lib"

 

🔷 Git 커밋 시 자동 포맷 검증 — Husky + lint-staged

저장 시 자동 포맷팅을 하더라도, 개발자가 실수로 포맷팅 되지 않은 파일을 커밋할 수 있습니다.

이를 방지하기 위해 Git hook 단계에서 자동으로 코드를 다시 교정합니다.

1. 설치

  install -D husky lint-staged
npx husky install

 

2. pre-commit 훅 생성

# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo "🔧 Running pre-commit hooks..."
npx lint-staged

이 스크립트는 Husky 공식 문서에서 제시하는 기본 pre-commit 구조이며 Windows, macOS, Linux 모두에서 동일하게 사용하도록 설계되어 있습니다.

 

3. package.json에 lint-staged 설정 추가

{
  "lint-staged": {
    "*.{ts,js,jsx,tsx,json,md}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

▸ 커밋 단계에서 수정된 파일만 다시 검사
▸ 포맷팅/린트 오류 있어도 커밋되지 않음
▸ 팀 전체 코드가 항상 일정 품질 이상 유지됨

 

✔️ VSCode에서 커밋하면 pre-commit 실행이 되는 이유

VSCode의 Git 패널에서 커밋을 하면 VSCode는 내부적으로 로컬 Git 클라이언트의 실제 git 명령을 호출합니다.

git commit -m "message"

이 명령이 백그라운드에서 그대로 실행됩니다.
그리고 Git은 다음 순서로 훅을 실행합니다:

.git/hooks/pre-commit
→ (.husky/pre-commit 로 위임)
→ lint-staged 실행
→ eslint --fix / prettier --write

따라서 VSCode의 Commit UI를 사용하더라도, Husky가 설치된 프로젝트라면 pre-commit은 항상 실행됩니다.

 

🔷 CI 환경에서의 포맷 검증 - GitHub Actions

CI에서 포맷 검증을 수행하면 “로컬에서만 잘 되는 환경”을 방지하고, PR 리뷰 전에 시스템이 자동으로 품질을 체크합니다.

 

 ▸ .github/workflows/lint.yml 예시

name: Lint and Format Check   # 워크플로우의 표시 이름

# 워크플로우 실행 조건: push 또는 pull_request 발생 시 실행됨
on:
  push:
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest     # GitHub Actions가 사용할 OS 환경

    steps:
      # 레포지토리 코드를 체크아웃 (GitHub Actions에서 가장 첫 단계)
      - uses: actions/checkout@v4

      # Node.js 환경 설정
      # node-version: 20 → CI에서는 고정된 Node 버전이 중요
      # cache:   →   install 속도 최적화
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache:  

      # 패키지 설치 (CI에서는 재현 가능한 설치를 위해   ci 사용)
      - run:   ci

      # ESLint 실행 (lint script는 package.json에 정의됨)
      - run:   run lint

      # Prettier 포맷 검사 (--check: 파일 수정 없이 검사만 수행)
      - run:   run format -- --check

▸ PR 단계에서 포맷 오류를 즉시 발견
▸ 환경에 따라 포맷이 달라지는 문제 제거
▸ CI의 일관된 Node.js 버전(20 이상)을 기준으로 검증

 

✔ 마무리 - 개발환경은 곧 개발자의 속도이다

지금까지 프로젝트 초기화부터 ESLint·Prettier 설정, VSCode 통합, 그리고 Git Hooks·CI 자동화까지 현대적인 Node.js 개발환경의 전체 흐름을 살펴보았습니다.


이 모든 과정의 핵심은 단 하나입니다:
“개발자가 코드에만 집중할 수 있는 환경을 만드는 것.”


불필요한 포맷팅 고민, 린트 경고, 환경 차이 같은 문제를 도구가 자동으로 처리해 주면 개발자는 더 빠르게, 더 안정적으로, 더 즐겁게 일할 수 있습니다.


작은 설정 하나가 팀의 품질과 생산성을 바꿉니다.
그리고 이번에 구축한 환경은 그 출발점이 될 것입니다.

 

본문의 설명내용은 아래 목록에 표시된 실제 의존성 환경을 그대로 기반으로 작성되었습니다:

>   list
typescript-examples@1.0.0 D:\NodejsDevelope\workspace\TypeScript-Examples
├── @eslint/js@9.39.1
├── @eslint/json@0.14.0
├── eslint-config-prettier@10.1.8
├── eslint@9.39.1
├── globals@16.5.0
├── prettier@3.6.2
└── typescript-eslint@8.46.4

※ 게시된 글 및 이미지 중 일부는 AI 도구의 도움을 받아 생성되거나 다듬어졌습니다.

반응형

 

 

반응형