Dart 프로그래밍에서 라이브러리패키지는 코드를 재사용하고 모듈화하는 데 중요한 역할을 한다. 이 장에서는 Dart의 라이브러리 시스템과 패키지 관리 도구인 Pub에 대해 설명하며, 패키지를 설치하고 사용하는 방법, 그리고 패키지의 의존성을 관리하는 방법에 대해 다룬다.

라이브러리의 개념

라이브러리는 코드를 조직화하고 재사용하기 위한 가장 기본적인 단위이다. Dart에서 라이브러리는 namespace를 제공한다. 즉, 하나의 라이브러리에 정의된 이름은 다른 라이브러리의 이름과 충돌하지 않도록 보호된다.

// my_library.dart
library my_library;

void myFunction() {
  print('This is a function in my library.');
}

라이브러리를 선언할 때 library 키워드를 사용하며, Dart 코드의 최상단에 위치한다. 다른 파일에서 이 라이브러리를 가져올 수 있는데, 이때는 import 문을 사용한다.

import 'my_library.dart';

void main() {
  myFunction();
}

내장 라이브러리

Dart에는 여러 가지 내장 라이브러리가 제공되며, dart: 접두사를 사용해 불러올 수 있다. 예를 들어, 기본적으로 제공되는 dart:core 라이브러리는 별도의 import 없이도 자동으로 포함된다.

내장 라이브러리 예시: - dart:core: Dart의 핵심 기능을 제공한다. (예: List, String, int) - dart:async: 비동기 프로그래밍을 지원하는 Future 및 Stream을 제공한다. - dart:io: 파일 입출력과 네트워크 관련 기능을 제공한다. (웹 환경에서는 사용 불가)

import 'dart:math';

void main() {
  var randomNumber = Random().nextInt(100);
  print(randomNumber);
}

패키지와 Pub

Dart에서 패키지는 여러 라이브러리와 자원 파일을 하나의 단위로 묶은 것이다. 패키지를 통해 프로젝트 간에 코드를 공유하고 관리할 수 있다. Pub은 Dart의 패키지 관리 도구로, pub.dev에서 수많은 오픈 소스 패키지를 사용할 수 있다.

dependencies:
  http: ^0.13.3

pubspec.yaml 파일에서 프로젝트의 의존성을 정의하며, Pub을 사용해 패키지를 설치하고 관리할 수 있다. 위 예시에서 http 패키지의 특정 버전을 의존성으로 추가한 것이다.

Pub.dev에서 패키지 검색 및 설치

Pub.dev는 Dart와 Flutter의 공식 패키지 저장소로, 다양한 패키지를 검색하고 사용할 수 있다. 원하는 패키지를 설치하려면 먼저 Pub.dev에서 패키지를 검색한 후, pubspec.yaml 파일에 의존성을 추가한다. 그 후, 명령어를 사용해 패키지를 설치한다.

$ dart pub get

이 명령어는 프로젝트에 필요한 모든 의존성 패키지를 다운로드하고 프로젝트에 통합한다. 이제 프로젝트에서 패키지를 사용할 수 있게 된다.

패키지 사용 예시

패키지를 설치한 후에는, Dart 파일에서 해당 패키지를 import하여 사용할 수 있다. 예를 들어, http 패키지를 설치한 후에 다음과 같이 HTTP 요청을 보낼 수 있다.

import 'package:http/http.dart' as http;

void main() async {
  var url = Uri.parse('https://jsonplaceholder.typicode.com/posts');
  var response = await http.get(url);

  if (response.statusCode == 200) {
    print('Response data: ${response.body}');
  } else {
    print('Request failed with status: ${response.statusCode}.');
  }
}

이 코드는 http 패키지를 사용해 GET 요청을 보내고, 서버에서 받은 응답을 출력한다. 패키지를 사용하여 복잡한 기능을 간단하게 구현할 수 있다.

패키지 의존성 관리

Dart 프로젝트에서는 다양한 패키지를 사용하며, 각 패키지가 다른 패키지에 의존할 수 있다. 이러한 의존성을 관리하는 것이 중요하며, Pub은 의존성 관리를 자동으로 처리한다. 예를 들어, 특정 버전의 패키지가 다른 버전과 충돌하지 않도록 조정해준다.

의존성 버전 지정

pubspec.yaml 파일에서는 의존성의 버전을 지정할 수 있다. 예를 들어, 특정 패키지의 최신 버전을 사용하거나 특정 범위의 버전만 사용하도록 제한할 수 있다.

dependencies:
  http: ^0.13.0

여기서 ^0.13.0은 0.13.0 이상, 1.0.0 미만의 모든 버전을 허용하는 것을 의미한다. Dart의 세맨틱 버저닝(semantic versioning) 규칙에 따라 패키지 버전을 관리할 수 있다.

dependencies:
  provider: ">=4.0.0 <5.0.0"

이 예시에서는 provider 패키지의 4.0.0 이상, 5.0.0 미만의 버전만 사용 가능하도록 설정하였다.

패키지 잠금 파일

패키지를 설치하면 pubspec.lock 파일이 생성된다. 이 파일에는 프로젝트에서 사용하는 모든 패키지와 그들의 버전 정보가 기록된다. 이 잠금 파일을 통해 프로젝트에서 사용하는 패키지 버전을 고정할 수 있으며, 팀 간 협업 시 동일한 환경을 유지할 수 있다.

# pubspec.lock 파일 예시
packages:
  http:
    version: "0.13.3"
    resolved-url: "https://pub.dev/packages/http/versions/0.13.3"

잠금 파일은 버전 충돌을 방지하고, 패키지의 일관성을 유지하기 위한 중요한 역할을 한다.

패키지 의존성 해결 전략

Pub은 패키지 의존성을 해결할 때 다음과 같은 전략을 사용한다.

  1. 직접 의존성: 프로젝트에서 명시적으로 정의한 의존성.
  2. 간접 의존성: 직접 의존성이 의존하는 패키지들.

패키지 간의 충돌이 발생하면, Pub은 세맨틱 버저닝을 기반으로 최적의 버전을 선택하려고 시도한다. 만약 충돌을 해결할 수 없다면, 오류 메시지를 표시하고 수동으로 해결할 것을 요구한다.

$ dart pub upgrade

pub upgrade 명령어를 사용하면 최신 버전의 패키지로 업데이트할 수 있다. 이를 통해 프로젝트의 의존성을 최신 상태로 유지할 수 있다.

패키지 생명 주기 관리

Dart 프로젝트에서 패키지는 주기적으로 업데이트되고, 개발자는 이를 관리해야 한다. Dart의 Pub 도구는 이러한 패키지의 생명 주기를 효율적으로 관리할 수 있도록 돕는다.

패키지 업데이트

프로젝트의 패키지를 최신 상태로 유지하려면, pub upgrade 명령어를 사용하여 모든 의존성을 최신 버전으로 업그레이드할 수 있다. 이 명령어는 pubspec.yaml에 지정된 버전 범위 내에서 가능한 최신 버전을 찾는다.

$ dart pub upgrade

의존성 동결

특정 패키지 버전에 문제가 발생하거나, 프로젝트가 안정된 환경을 유지해야 할 때는 의존성 버전을 동결시킬 수 있다. 이를 위해 pubspec.lock 파일을 유지하며, 이 파일이 모든 개발자에게 동일한 환경을 제공할 수 있도록 버전 컨트롤에 포함시킨다.

$ dart pub get

이 명령어는 pubspec.yaml 파일의 의존성 정보를 기반으로 패키지를 설치하되, pubspec.lock에 정의된 버전과 일치시키는 작업을 수행한다. 이 과정에서 새로운 패키지가 추가되더라도, 기존 의존성은 고정된 상태로 유지된다.

사용자 정의 패키지 작성

개발자는 자신의 코드를 패키지로 만들어 다른 프로젝트에서도 재사용할 수 있다. 사용자 정의 패키지를 작성하려면 먼저 프로젝트 구조를 설정해야 한다.

$ dart create --template=package-simple my_package

이 명령어는 새로운 패키지 프로젝트를 생성하며, 파일과 폴더 구조가 자동으로 설정된다.

name: my_package
version: 0.1.0
description: My custom Dart package.
environment:
  sdk: '>=2.12.0 <3.0.0'

pubspec.yaml 파일에서 패키지의 이름, 버전, 환경 정보를 정의한다. 패키지 이름은 Pub.dev에 게시될 때 중요한 요소이며, 고유한 이름이어야 한다.

패키지 배포

패키지를 작성한 후에는 Pub.dev에 배포할 수 있다. 배포하려면 패키지의 모든 필수 요소가 제대로 설정되어 있어야 하며, 다음 명령어를 사용하여 Pub.dev에 게시한다.

$ dart pub publish

배포 전에 dart pub publish --dry-run 명령어로 문제가 없는지 확인할 수 있다.

패키지 내 라이브러리 구조

패키지를 구성할 때는 여러 라이브러리를 포함할 수 있다. 라이브러리는 코드의 특정 기능을 모듈화한 부분으로, 패키지 내에서 상호 참조하거나 외부에서 특정 라이브러리만 불러올 수 있다. Dart 패키지에서는 주로 lib 디렉토리를 통해 라이브러리를 관리한다.

이 구조는 패키지의 공개 인터페이스와 내부 구현을 구분할 수 있도록 돕는다.

// lib/my_package.dart
library my_package;

export 'src/my_package_base.dart';

Pubspec의 주요 필드

pubspec.yaml 파일은 패키지의 정보를 정의하는 핵심 파일이다. 이 파일에서 정의된 내용에 따라 패키지의 의존성, 환경, 그리고 배포 관련 설정이 결정된다. 주요 필드는 다음과 같다.

name: http
version: 0.13.3
description: A composable, multi-platform, Future-based API for HTTP requests.
environment:
  sdk: '>=2.12.0 <3.0.0'

dependencies:
  async: ^2.5.0

위와 같은 구조로 pubspec.yaml 파일을 작성하여 패키지의 구성을 설정할 수 있다.