이번 여름 인턴을 진행하던 중, cybersecurity 팀과 frontend팀이 협력하여 현재 개발중인 애플리케이션의 보안등 문제를 개발하는 단계에 이르렀다. 제일 첫번째 스텝은 팀 내에서 역할을 세분화 하여 의존성 패키지 코드를 작성하는것인데, 개발을 진행하며 의존성, dependency에 관한 얘기를 수없이 들어봤지만, 내가 여지껏 개발했던 애플리케이션들의 개발 규모가 작았기 때문에 의존성에 관련된 문제들은 구글을 검색해 코드를 가져오거나 GPT한테 물어봤다. 하지만, 이렇게 실제로 나에게 dependency에 관련한 코드를 작성하라니 정말 아무것도 모르겠어서 오늘은 의존성이 뭔지 정도만 확인하고 다음 포스팅에서는 실제 코드로 의존성이 어떻게 동작하는지 알아 볼 예정이다.

 

※Dependency(의존성)이란 프로그래밍에서 무엇일까?

아래는 GPT를 통해 얻은 답변이다.

더보기

프로그래밍에서 "의존성(Dependency)"이란, 특정 소프트웨어가 제대로 작동하기 위해 필요로 하는 외부 소프트웨어, 라이브러리, 프레임워크 또는 모듈을 의미합니다. 의존성은 개발자가 기존의 잘 검증된 코드를 재사용하여 개발 시간을 절약하고 코드의 신뢰성을 높이는 데 중요한 역할을 합니다.

의존성의 장점

1. 재사용성:
   - 이미 개발되고 검증된 코드를 재사용함으로써 개발 시간을 단축하고 오류를 줄일 수 있습니다. 예를 들어, HTTP 요청을 쉽게 처리하기 위해 `axios` 같은 라이브러리를 사용할 수 있습니다.

2. 유지보수성:
   - 외부 라이브러리나 모듈을 사용하면 버그 수정이나 기능 개선이 해당 라이브러리의 업데이트를 통해 자동으로 적용될 수 있습니다. 이는 유지보수 비용을 줄이고 코드의 품질을 유지하는 데 도움이 됩니다.

3. 협업:
   - 여러 개발자가 참여하는 프로젝트에서 동일한 라이브러리와 버전을 사용하여 일관된 개발 환경을 유지할 수 있습니다.

의존성의 유형

1. 직접 의존성(Direct Dependency):
   - 프로젝트에서 직접적으로 사용하는 라이브러리나 모듈입니다. 예를 들어, 웹 서버를 구축하기 위해 `express`를 사용하는 경우, `express`는 직접 의존성입니다.

2. 간접 의존성(Indirect Dependency):
   - 직접 의존성에서 다시 필요로 하는 의존성입니다. 예를 들어, `express`가 내부적으로 사용하는 여러 라이브러리가 간접 의존성이 됩니다.

의존성 관리 도구

NPM (Node Package Manager)은 Node.js 애플리케이션에서 가장 널리 사용되는 의존성 관리 도구입니다. NPM을 사용하면 패키지 설치, 버전 관리, 패키지 업데이트 등을 쉽게 할 수 있습니다.

 

`package.json` 파일

`package.json` 파일은 NPM 프로젝트의 메타데이터와 의존성을 정의하는 파일입니다. 이 파일에는 프로젝트 이름, 버전, 설명, 스크립트, 의존성 등이 포함됩니다. 다음은 `package.json` 파일의 예입니다:

{
  "name": "my-project",
  "version": "1.0.0",
  "description": "A sample project",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.17.1",
    "axios": "^0.21.1"
  },
  "devDependencies": {
    "jest": "^26.6.3"
  }
}

 주요 NPM 명령어

1. `npm install`:
   - `package.json` 파일에 정의된 모든 dependencies와 devDependencies를 설치합니다. 이 명령어는 `node_modules` 디렉토리에 모든 패키지를 다운로드하고 설치합니다.

2. `npm install <package>`:
   - 특정 패키지를 설치하고, 자동으로 `package.json` 파일의 dependencies 섹션에 추가합니다.
   - 예: `npm install express`

3. `npm install <package> --save-dev`:
   - 특정 패키지를 devDependencies 섹션에 추가합니다.
   - 예: `npm install jest --save-dev`

4. `npm update`:
   - 현재 설치된 패키지들을 최신 버전으로 업데이트합니다.

5. `npm uninstall <package>`:
   - 특정 패키지를 제거하고, `package.json` 파일에서 해당 패키지를 제거합니다.
   - 예: `npm uninstall axios`

의존성 관리의 모범 사례

1. 버전 관리:
   - 특정 버전 범위를 지정하여 예기치 않은 변경으로부터 프로젝트를 보호합니다. 예를 들어, `^1.0.0`은 1.x.x 버전에 대해서만 업데이트를 허용합니다.

2. 의존성 정리:
   - 더 이상 필요하지 않은 의존성을 제거하여 프로젝트를 간소화하고 유지보수를 용이하게 합니다.

3. 보안 검사:
   - 정기적으로 의존성의 보안 취약점을 검사하고, 발견된 취약점을 신속히 해결합니다. NPM의 `npm audit` 명령어를 사용하여 보안 문제를 확인할 수 있습니다.

4. 잠금 파일 사용:
   - `package-lock.json` 파일을 사용하여 설치된 패키지의 정확한 버전을 기록합니다. 이는 팀 내의 일관된 개발 환경을 유지하는 데 도움이 됩니다.

5. 의존성 업데이트 주기 관리:
   - 정기적으로 의존성을 업데이트하여 최신 기능과 보안 패치를 받을 수 있도록 합니다. 그러나 주요 버전 업데이트는 신중하게 검토하고 테스트해야 합니다.

이와 같은 의존성 관리 방법을 통해 프로젝트의 안정성, 보안성, 유지보수성을 높일 수 있습니다.

내가 이번 학부 연구를 진행하며 써왔던 모든것들, npm, axios, express 등등이 모두 의존성과 관련되어 있었다. 

 

예를들어, 내가 frontend 디렉토리에서 npm i cookie_parser 같은 패키지를 설치한다면, pack.json 파일의 dependencies에서 내가 방금 설치한 패키지를 확인 할 수 있다.

 

 

'Internship' 카테고리의 다른 글

Monorepo, Multirepo는 무엇인가?  (0) 2024.06.26

이번 인턴을 진행하며 패키지를 관리하던 도중, 이번 프로젝트는 monorepo방식으로 구현되어 있다는걸 들었다. Team Lead가 항상 monorepo에 들어가 무엇을 구현, 수정 등등을 요구했었는데 monorepo가 그저 저장소 이름인줄 알았는데 아니였다! 

 

그렇다면, Monorepo란 무엇일까?

더보기

모노리포(Monorepo)는 여러 프로젝트(패키지)를 단일 저장소(repository)에서 관리하는 방법론을 말합니다. 이는 다수의 관련된 프로젝트를 한 곳에서 관리하고 배포할 수 있도록 돕습니다. 

### 모노리포의 특징

1. **단일 저장소**:
   - 여러 프로젝트를 하나의 저장소에서 관리합니다.
   
2. **코드 재사용**:
   - 공통 코드나 라이브러리를 여러 프로젝트에서 쉽게 재사용할 수 있습니다.
   
3. **일관된 버전 관리**:
   - 저장소 전체에 대해 일관된 버전 관리와 의존성 관리를 할 수 있습니다.
   
4. **일관된 빌드 및 테스트**:
   - 여러 프로젝트에 대해 일관된 빌드 및 테스트 파이프라인을 설정할 수 있습니다.

### 모노리포의 장점

1. **통합된 개발 환경**:
   - 모든 프로젝트가 동일한 환경에서 개발되므로 일관성을 유지하기 쉽습니다.
   
2. **코드 공유**:
   - 공통 모듈이나 유틸리티 코드를 쉽게 공유하고 유지 관리할 수 있습니다.
   
3. **의존성 관리**:
   - 모든 프로젝트에서 동일한 의존성 버전을 사용하므로 버전 충돌을 피할 수 있습니다.
   
4. **코드 리팩토링**:
   - 리팩토링 시 단일 커밋으로 모든 관련 프로젝트에 변경 사항을 반영할 수 있습니다.
   
5. **일관된 테스트 및 빌드**:
   - 통합된 빌드 및 테스트 스크립트를 통해 모든 프로젝트에 대해 일관된 빌드 및 테스트를 수행할 수 있습니다.

### 모노리포의 단점

1. **빌드 시간 증가**:
   - 모든 프로젝트를 한 번에 빌드하면 빌드 시간이 길어질 수 있습니다.
   
2. **복잡한 의존성 관리**:
   - 여러 프로젝트의 의존성을 동시에 관리해야 하므로 의존성 관리가 복잡해질 수 있습니다.
   
3. **저장소 크기 증가**:
   - 모든 프로젝트의 코드를 단일 저장소에 포함하므로 저장소 크기가 커질 수 있습니다.

### 모노리포 도구
모노리포를 효율적으로 관리하기 위해 다양한 도구들이 사용됩니다. 대표적인 도구로는 다음이 있습니다:

- **Lerna**: JavaScript/TypeScript 프로젝트에서 모노리포를 관리하는 도구로, 여러 패키지의 버전 관리를 쉽게 할 수 있습니다.
- **Nx**: 모노리포 관리와 빌드를 최적화하는 데 도움을 주는 도구로, 특히 대규모 프로젝트에 적합합니다.
- **Bazel**: 구글에서 개발한 빌드 도구로, 대규모 코드베이스를 효율적으로 빌드하고 테스트할 수 있게 도와줍니다.

### 모노리포 예시
모노리포 구조의 예시는 다음과 같습니다:

```
/monorepo
├── /packages
│   ├── /package-a
│   │   ├── package.json
│   │   └── src/
│   ├── /package-b
│   │   ├── package.json
│   │   └── src/
│   └── /shared-utils
│       ├── package.json
│       └── src/
├── package.json
└── lerna.json (or nx.json)
```

여기서 `/packages` 디렉토리 아래에 여러 개의 패키지가 있으며, 각 패키지는 독립적인 `package.json` 파일을 가지고 있지만 공통된 유틸리티(`shared-utils` 같은)를 공유할 수 있습니다.

이와 같은 구조를 통해 프로젝트 관리와 개발의 효율성을 높일 수 있습니다. 모노리포에서 `cookie-parser`와 같은 의존성을 추가하고 관리하는 것도 이러한 구조 덕분에 일관되게 수행할 수 있습니다.

그렇다. 여러 프로젝트 패키지를 하나의 저장소에서 통합/관리하는 시스템이다. 이렇게 보니 이해가 간다. 현재 진행중인 프로젝트의 디렉토리를 보면 root - apps 안에 3개의 서로 다른 app들이 있으며, 이것들을 같이 관리 하는 것이였다.

 

 

그렇다면, monorepo와 반대되는 개념인 Multirepo는 무엇일까?

더보기

모노리포(Monorepo)와 반대되는 개념은 멀티리포(Multi-repo)입니다. 멀티리포는 각 프로젝트나 패키지를 독립된 저장소에서 관리하는 방법입니다. 이 접근 방식은 많은 개별 저장소로 프로젝트를 분리하여 관리합니다.

### 멀티리포의 특징

1. **다중 저장소**:
   - 각 프로젝트나 패키지가 독립된 저장소에서 관리됩니다.
   
2. **독립된 버전 관리**:
   - 각 프로젝트는 독립적으로 버전 관리를 합니다.
   
3. **독립된 빌드 및 배포**:
   - 각 프로젝트는 독립적으로 빌드하고 배포됩니다.

### 멀티리포의 장점

1. **독립성**:
   - 프로젝트가 완전히 독립적이므로 각 프로젝트가 다른 프로젝트에 영향을 받지 않습니다.
   
2. **작은 규모의 저장소**:
   - 각 저장소가 상대적으로 작기 때문에 관리가 용이합니다.
   
3. **특화된 빌드 및 배포**:
   - 각 프로젝트가 자신만의 빌드 및 배포 파이프라인을 가질 수 있어 특정 요구사항에 맞게 최적화할 수 있습니다.
   
4. **팀별 관리 용이**:
   - 각 팀이 자신들의 프로젝트만 관리하기 때문에 책임 범위가 명확해집니다.

### 멀티리포의 단점

1. **코드 공유 어려움**:
   - 공통 모듈이나 유틸리티 코드를 여러 저장소에서 공유하고 유지 관리하기 어렵습니다.
   
2. **의존성 관리 복잡성**:
   - 여러 저장소 간의 의존성을 관리하는 것이 복잡할 수 있습니다.
   
3. **중복 작업**:
   - 공통된 설정이나 스크립트가 여러 저장소에 중복될 수 있습니다.
   
4. **일관된 버전 관리 어려움**:
   - 여러 프로젝트의 버전을 일관되게 유지하는 것이 어려울 수 있습니다.

### 멀티리포 예시
멀티리포 구조의 예시는 다음과 같습니다:

```
/repo1
├── package.json
└── src/

/repo2
├── package.json
└── src/

/repo-shared-utils
├── package.json
└── src/
```

여기서 각 프로젝트(`repo1`, `repo2`, `repo-shared-utils`)는 독립된 저장소에서 관리됩니다. 공통 유틸리티는 `repo-shared-utils`에서 관리되며, 필요한 경우 이를 다른 프로젝트에 의존성으로 추가하여 사용할 수 있습니다.

### 모노리포와 멀티리포 비교

- **코드베이스 관리**: 모노리포는 하나의 큰 저장소에서 모든 코드를 관리하지만, 멀티리포는 각 프로젝트를 별도의 저장소에서 관리합니다.
- **코드 공유**: 모노리포에서는 공통 코드를 쉽게 공유할 수 있지만, 멀티리포에서는 코드 공유가 어렵고 번거로울 수 있습니다.
- **의존성 관리**: 모노리포에서는 의존성 관리를 통합하여 쉽게 할 수 있지만, 멀티리포에서는 각 프로젝트마다 별도로 관리해야 합니다.
- **빌드 및 배포**: 모노리포는 통합된 빌드 및 배포 파이프라인을 사용하지만, 멀티리포는 각 프로젝트별로 별도의 빌드 및 배포 파이프라인을 가질 수 있습니다.

각 접근 방식은 특정 상황에서 더 유리할 수 있으므로, 프로젝트의 성격과 팀의 요구에 따라 적절한 방식을 선택하는 것이 중요합니다.

 

 

'Internship' 카테고리의 다른 글

Dependency? 의존성은 무엇일까?  (0) 2024.06.27

+ Recent posts