RHUK2

브라우저 단에서 node_moduels

node_modules 안에 라이브러리는 절대/상대 경로없이 참조 가능하다

NPM

맞습니다! 레지스트리는 주로 패키지의 메타데이터를 저장하고 관리하는 역할을 합니다. 이 메타데이터에는 패키지의 이름, 버전, 설명, 의존성 정보 등이 포함됩니다. 이러한 메타데이터를 통해 사용자는 필요한 패키지를 쉽게 검색하고 식별할 수 있습니다.

npm과 같은 패키지 관리 도구는 이러한 레지스트리를 사용하여 패키지를 검색하고 설치합니다. 사용자가 패키지를 검색하면 패키지 관리 도구는 레지스트리에서 해당 패키지의 메타데이터를 가져와 사용자에게 보여줍니다. 그러면 사용자는 필요한 패키지를 선택하고 설치할 수 있습니다.

설치할 때 실제로 다운로드되는 파일은 레지스트리가 아니라, 해당 패키지의 소스 코드가 호스팅되는 곳에서 제공됩니다. 예를 들어, npm의 경우 패키지의 소스 코드는 npm 레지스트리에서 다운로드됩니다. 이렇게 다운로드된 소스 코드를 기반으로 패키지를 설치하고 사용할 수 있습니다.

따라서 레지스트리는 패키지의 메타데이터를 저장하고 색인을 쉽게 해주는 도구이며, 패키지의 실제 소스 코드는 해당 패키지가 호스팅되는 곳에서 제공됩니다.

package.json

속성설명
name패키지의 이름을 정의한다. 이 이름은 패키지를 식별하는 데 사용된다.
version패키지의 버전을 정의한다. 버전은 Semantic Versioning(의존성 관리를 위한 표준 방법론)을 따른다.
description패키지의 간단한 설명을 제공한다.
keywords패키지와 관련된 키워드 목록을 포함한다.
author패키지의 작성자를 식별한다.
license패키지의 라이선스를 지정한다.
repository패키지의 소스 코드 저장소 정보를 제공한다.
dependencies패키지가 의존하는 다른 패키지들과 그들의 버전을 명시한다.
devDependencies개발 중에만 필요한 패키지들을 명시한다.
peerDependencies패키지가 함께 사용될 다른 패키지들과의 호환성을 명시한다.
optionalDependencies설치 과정에서 실패해도 애플리케이션의 기능에 큰 영향을 미치지 않는 패키지들을 명시한다.
bundledDependencies패키지가 번들링된 의존성을 명시한다.
engines패키지가 의존하는 Node.js 및 npm의 버전을 지정한다.
scripts패키지의 사용자 정의 스크립트들을 정의한다.
main패키지의 진입점(entry point)을 지정한다.
typingsTypeScript로 작성된 패키지의 경우 타입 정의 파일의 경로를 지정한다.
files패키지가 배포될 파일 및 디렉터리를 명시한다.
private이 속성이 true로 설정된 경우, 해당 패키지는 npm 레지스트리에 게시되지 않는다.
workspaces모노레포(모놀리식 저장소)에서 사용하는 패키지들의 위치를 지정한다.

devDependencies

개발과정에서만 필요한 패키지들, 대표적으로 포맷팅, 번들러, 바벨, 테스트툴, 타입스크립트가 해당된다.

peerDependencies..

의존성 캐럿 의미도 파악 필요 ^ 같은 거

scripts

scripts 속성은 String 값으로 Node 프로젝트 내에서 실행 가능한 커맨드 명령어를 정의한다. 쉘 스크립트와 유사한 개념이며 아래와 같이 몇 가지 차이점이 있다.

  • 쉘 스크립트는 운영체제의 쉘에서 실행되지만, scripts 속성은 Node 환경에서 실행된다. 즉, Node 환경의 내장된 스크립팅 기능과 npm 패키지 관리자의 기능을 활용할 수 있다.
  • 쉘 스크립트는 쉘 문법과 쉘 명령어를 혼합해 사용한다. scripts 속성은 보통 쉘 명령어를 직접 사용하기보다 패키지 이름과 옵션을 명시해서 사용하는 경우가 일반적이다.

workspaces

npm workspace는 종속성 관리지 설정 파일 관리는 아님

monorepo

좋은 질문이야! npm이 중복 의존성을 자동으로 없애주는지에 대해 이야기하려면, npm의 동작 방식과 의존성 관리 메커니즘을 시간의 흐름에 따라 살펴봐야 해. 결론부터 말하면: npm은 중복 의존성을 완전히 자동으로 없애주지는 않지만, 특정 상황에서 중복을 줄이려고 노력해. 그리고 이건 npm 버전과 설정에 따라 달라졌어. 이제 자세히 풀어볼게.


초기 npm (v1 ~ v2, 2010년 ~ 2014년경): 중첩 구조와 중복 의존성

npm이 처음 등장했을 때(v1, v2 시절), 의존성은 중첩 구조(nested dependencies)로 설치되었어. 각 패키지가 자신만의 node_modules 폴더를 가지며, 필요한 의존성을 그 안에 독립적으로 설치했지.

  • 동작 방식:
    • 패키지 A가 lodash@1.0.0을 의존하고, 패키지 B도 lodash@1.0.0을 의존하면, 각각의 node_modules에 별도로 설치.
    • 예:
      /node_modules
        /A
          /node_modules
            /lodash@1.0.0
        /B
          /node_modules
            /lodash@1.0.0
      
  • 중복 의존성: 같은 버전이라도 중복 설치되었어. npm은 중복을 없애려고 하지 않고, 각 패키지가 독립적으로 동작하도록 보장했지.
  • 왜 이렇게 했나?:
    • 당시엔 단순함과 안정성을 우선시했어. 서로 다른 패키지가 같은 의존성을 공유하면 충돌 위험이 있으니 격리한 거야.
  • 문제점:
    • node_modules가 엄청 커짐 (디스크 공간 낭비).
    • 설치 속도 느려짐.

결론: 초기 npm은 중복 의존성을 자동으로 없애주지 않았어. 오히려 중복이 기본이었지.


npm v3 (2015년 ~): 평평한 구조와 중복 감소

npm v3에서 큰 변화가 생겼어. 평평한 구조(flat dependency tree)를 도입하면서 중복 의존성을 줄이려는 시도가 시작됐지.

  • 동작 방식:
    • 같은 버전의 의존성은 루트 node_modules에 한 번만 설치하고 공유.
    • 예: A와 B가 lodash@1.0.0을 의존하면:
      /node_modules
        /lodash@1.0.0
        /A
        /B
      
    • 서로 다른 버전이 필요하면 별도로 설치:
      /node_modules
        /lodash@1.0.0  (A가 사용)
        /lodash@2.0.0  (B가 사용)
        /A
        /B
      
  • 중복 감소:
    • 같은 버전이라면 자동으로 중복을 없애고 루트에 하나만 설치.
    • 다른 버전은 여전히 중복 설치 (semver 충돌 해결 불가).
  • 장점:
    • 디스크 사용량 줄고 설치 속도 빨라짐.
    • 코드에서 require('lodash') 호출 시 루트에서 찾으니 단순해짐.
  • 한계:
    • 버전이 다르면 여전히 중복 발생.
    • 설치 순서에 따라 의존성 충돌(호이스팅 문제)이 생길 수 있음.

결론: npm v3부터는 같은 버전의 중복은 자동으로 없애주지만, 다른 버전은 그대로 남겨.


npm v7 ~ v8 (2020년 ~ 현재): Lockfile과 개선

npm v7에서 package-lock.json이 기본으로 생성되면서 의존성 관리가 더 정교해졌어. 그리고 v8(2025년 기준 최신 안정 버전)까지 이어졌지.

  • Lockfile의 역할:
    • package-lock.json은 의존성 트리를 정확히 고정시켜 중복 포함 여부를 명시.
    • 팀 간 동일한 설치 결과 보장.
  • 중복 처리:
    • 여전히 같은 버전은 루트로 호이스팅(flat)해서 중복 제거.
    • 다른 버전은 별도 설치로 중복 허용.
    • 예:
      "dependencies": {
        "A": "^1.0.0",  // lodash@1.0.0 필요
        "B": "^1.0.0"   // lodash@1.0.0 필요
      }
      
      node_modules/lodash@1.0.0 하나만 설치.
  • npm dedupe 명령어:
    • npm dedupe를 실행하면 가능한 한 중복을 줄여줘. 같은 버전의 의존성을 분석해서 불필요한 중복 제거.
    • 예: 설치 후 중복이 생겼다면 이 명령어로 정리 가능.

결론: 기본적으로 같은 버전 중복은 없애주고, dedupe로 추가 최적화 가능. 하지만 다른 버전은 자동 제거 불가.


번들링 환경에서의 중복 관리

Node.js 런타임 자체는 npm이 설치한 node_modules를 그대로 쓰지만, 브라우저로 번들링할 때는 Webpack이나 Rollup 같은 도구가 중복을 더 적극적으로 처리해:

  • 트리 쉐이킹: 사용하지 않는 코드를 제거하며 중복 최소화.
  • 의존성 통합: ESM 기반으로 같은 모듈을 한 번만 포함.

최종 답변

  • npm은 중복 의존성을 자동으로 없애주나?
    • 같은 버전: 예, v3부터 평평한 구조로 자동 제거.
    • 다른 버전: 아니요, 중복 허용 (semver 충돌 방지).
    • 추가 최적화: npm dedupe로 수동 정리 가능.
  • 2025년 기준: npm v8은 꽤 효율적이지만, 완전 자동 중복 제거는 불가능하고, 프로젝트 요구사항(버전 호환성)에 따라 달라져.

궁금한 거 더 있으면 물어봐! 중복 관리에서 특정 케이스가 궁금한가?

npm install vs npm ci

npm install: package.json과 package-lock.json을 비교해 최신 버전 설치 가능. node_modules가 없으면 생성, 있으면 업데이트. npm ci: package-lock.json만 참조해 정확한 버전 설치. 기존 node_modules 삭제 후 완전 새로 설치.

Nestjs 폴더구조

NestJS 폴더 구조 아키텍처 설명

1. 기본 구조

  • src/: 핵심 소스 코드 디렉토리
    • main.ts: 애플리케이션 진입점
    • app.module.ts: 루트 모듈

2. 주요 디렉토리

  • modules/: 기능별 모듈 분리 (DDD 방식 권장)
    • 예: users/, products/
  • common/: 공유 유틸리티
    • interceptors/, filters/, decorators/

3. 모듈 내부 구조 (예: users/)

  • users.controller.ts: 라우팅 처리
  • users.service.ts: 비즈니스 로직
  • users.module.ts: 의존성 관리
  • dto/: 데이터 전송 객체
  • entities/: DB 엔티티
  • interfaces/: 타입 정의

4. 환경 설정

  • config/: 환경변수 관리
  • env/: 환경별 설정 파일

5. 테스트

  • test/: E2E/유닛 테스트
    • e2e/: 엔드투엔드 테스트
    • *.spec.ts: 유닛 테스트

6. 빌드/배포

  • dist/: 컴파일된 출력물 (자동 생성)
  • public/: 정적 파일
  • views/: 템플릿 (사용시)

💡 권장 사항

  • 기능 단위로 모듈화
  • 계층형 아키텍처 적용 (Controller-Service-Repository)
  • 공통 기능은 공유 모듈로 추출

pnpm workspace

pnpm --filter @repo/ui add
pnpm add --workspace @repo/ui
pnpm

local package

패키지가 react-hook-form을 사용할 경우, 해당 패키지를 다운받았다고해서 메인앱에서 사용할 수 있는 개념이 아님 import를 통해 넘어온 기능만 사용가능함