저는 @einere/common-utils 라는 패키지명으로 배포하기위해, 다음과 같이 폴더를 만들었습니다.
common-utils
- src
- index.ts// 모듈 진입점- common-utils.ts// 모듈 정의 파일-.gitignore// GitHub 에 올리지 않을 파일들을 명시-.npmignore// NPM 에 올리지 않을 파일들을 명시
package.json 및 README.md 설정
그리고 디렉토리 내에서 CLI를 이용해 pakcage.json 설정을 해줍니다.
$ npm init --scope=einere
기본적인 정보를 입력해주면, 다음과 같이 package.json 파일이 만들어집니다. 여기서, 필요한 추가 속성을 추가해줍니다.
{"name":"@einere/common-utils","version":"1.0.0","description":"Einere's common utilities","type":"module",// 해당 패키지가 ESM을 사용하도록 지정합니다."main":"./dist/index.js",// 패키지의 진입점입니다."types":"./dist/index.d.ts",// 패키지의 타입 정의 파일의 위치입니다."files":["dist"// npm 배포 시 'dist' 폴더의 내용만 포함합니다.],"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc","prepublishOnly":"npm run build",// npm에 배포하기 직전, 빌드를 합니다.},"publishConfig":{"access":"public"// NPM에 배포하기 위해서는 공개로 지정해야 합니다.},"devDependencies":{"typescript":"^5.8.3"},// ...}
그리고 루트 경로에 README.md 파일을 만들어줍니다. 내용은 자유롭게 채워주세요.
진입점 구현
진입점인 index.ts 를 구현해줍니다.
// index.tsexport*from'./common-utils.js';
노드 환경에서 모듈을 가져올 때 확장자를 명시하지 않으면 모듈을 제대로 가져오지 못합니다. 그래서 위와 같이 파일의 확장자를 명시해줍니다.
그런데 왜 .js 일까요? 그 이유는 컴파일 결과물 때문입니다. 만약 확장자를 .ts 로 해버리면 어떻게 될까요?
// dist/index.jsexport*from"./common-utils.js";// 이 경우에는 제대로 유틸리티 함수를 가져옵니다.// dist/index.d.ts// d.ts 파일은 TSC에 의해 확장자 변경이 이루어지지 않습니다.// 결국, 존재하지 않는 ts 파일을 가져오려고 합니다.export*from"./common-utils.ts";
dist/index.js 와 dist/index.d.ts 둘 다 제대로 동작하게끔 하기 위해 .js 확장자를 사용한 것 입니다.
Typescript 설정
이제 TS 환경을 위해 typescript 를 개발 의존성으로 설치한 후, tsconfig.json 파일을 만들어줍니다.
$ npm install -D typescript
{// 컴파일 과정과 그 결과물에 대한 설정들입니다."compilerOptions":{"target":"ESNext",// 결과물의 JS 버전을 최신 버전으로 지정합니다."module":"ESNext",// 결과물의 모듈 시스템을 ESM로 지정합니다."moduleResolution":"node10",// 컴파일 시, 모듈 해석 방식을 지정합니다."esModuleInterop":true,// CJS 모듈을 ESM 방식으로 import 할 수 있도록 돕습니다."forceConsistentCasingInFileNames":true,"strict":true,// 엄격한 타입 체크"skipLibCheck":true,// 라이브러리의 타입 체크를 건너뜁니다."declaration":true,// .d.ts 타입 정의 파일을 생성합니다."outDir":"./dist",// 빌드 결과물이 저장될 디렉토리를 지정합니다."rootDir":"./src"},"include":["src/**/*.ts"// src 폴더 내의 모든 .ts 파일을 컴파일 대상에 포함합니다.],"exclude":["node_modules","dist"// dist 폴더는 컴파일 대상에서 제외합니다.]}
저는 패키지를 ESM로 지정하고 싶어서 module 속성은 ESNext 로 설정하고 moduleResolution 속성은 node10 으로 설정했습니다.