2024. 3. 26. 15:30

일반적인 프로젝트 빌드는 진입점을 기준으로 빌드가 되므로 별다른 설정 없이도 최적화(or 트리 쉐이킹), 빌드, 파일 합치기, 난독화, 최소화 같은 과정들이 이루어 집니다.

 

문제는 진입점이 없는 라이브러리인 경우 여러 가지 제한이 많다는 것입니다.

 

 

0. 타입스크립트 라이브러리의 배포

타입스크립트로 만든 라이브러리를 수동으로 배포하려면 그냥 타입스크립트 채로 배포해도 큰 문제는 없습니다.

배포된 라이브러리를 사용하는 개발자도 타입스크립트를 쓴다면 같이 빌드하면 그만이니까요.

 

타입스크립트를 안 쓰는 경우나 난독화가 필요하거나 일관성 유지를 원한다면 빌드한 다음 배포하는 것이 좋습니다.

 

이 포스팅에서는 빌드 결과물을 출력하고 같이 사용할 설명파일(.d.ts)파일을 같이 생성합니다.

난독화나 미니마이즈 같은 것들은 다른 포스팅에서 다룰 예정입니다.

 

자신의 환경과 상관없이 사용할 수 있도록 가급적 종속성이 적은 방법으로 구성하겠습니다.

 

이 포스팅의 내용

- 타입스크립트 빌드

- 상황에 맞는'tsconfig.json' 파일 선택

- 설명 파일(.d.ts) 생성 및 정리

 

 

1.빌드 구성 설정하기 

패키지 파일은 아래와 같이 설정하였습니다.

 

package.json

{
  "scripts": {
    "clean": "tsc --build --clean",
    "packaging": "tsc --project tsconfig.deploy.json",
  },
  "devDependencies": {
    "glob": "^10.3.10",
    "typescript": "5.4.2"
  }
}

 

4번 줄 : tsconfig.deploy.json은 배포용으로 사용할 타입스크립트 설정 파일로 아래에서 생성할 예정입니다.

원하는 구성이 있다면 각각을 파일로 만들어 이렇게 선택하면 됩니다.

 

7번 줄 : 'glob' 업데이트

glob가 구버전인 경우 아래와 같은 에러가 날 수 있습니다.

node_modules/@types/glob/index.d.ts(29,42): error TS2694: Namespace '"D:/work/project/vs/DotNetTest/TypeScriptReleaseTest1/node_modules/minimatch/dist/cjs/index"' has no exported member 'IOptions'.

 

 

 

2. 배포용 타입스크립트 설정 만들기 

배포용으로 사용할 'tsconfig.json'을 생성합니다.

(참고 : TypeScript Doc - What is a tsconfig.json )

다른 용도의 타입스크립트 설정 파일과 구분하기 위해 이름을 이렇게 지었습니다.

'package.json'에서 경로를 지정해 줘야 합니다.

 

tsconfig.deploy.json

{
  "compilerOptions": {
    "module": "es6",
    "lib": [ "es5", "dom" ],
    "outDir": "./dist/ReleaseClass",
    "rootDir": "./src/ReleaseClass",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strictNullChecks": true,
    "noImplicitAny": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "composite": true,


    "declaration": true,
    "declarationDir": "./dist/ReleaseClass"
  },
  "include": [ "./src/ReleaseClass/**/*.ts" ]
}

 

6번 줄 : 빌드 시 루트로 사용할 경로.

 

16번 줄 : '.d.ts'파일을 생성합니다.

'declarationDir'속성이 없다면 .ts 파일이 있는 폴더에 생성됩니다.

 

17번 줄 : 지정한 폴더에 '.d.ts'파일을 생성합니다.

 

19번 줄 : 빌드할 파일을 지정합니다.

테스트를 위한 진입점이 있는 파일이 같은 프로젝트에 있는 경우 라이브러리 내용이 있는 파일이나 폴더를 지정해야 합니다.

이 경우 여기서 지정합니다.

 

 

3. 테스트용 파일 만들기 

테스트를 위해서 아래와 같은 구성으로 파일을 만들었습니다.

 

빨간 네모 안의 파일이 빌드 타겟이 되는 라이브러리 파일입니다.

진입점은 없고 'ReleaseClass3Test'은 참조도 없습니다.

 

파일의 내용은 깃허브를 참고해 주세요.

github - 

ReleaseClassTest.ts 

ReleaseClass2Test.ts

ReleaseClass3Test.ts

 

 

4. 배포용 빌드 하기 

이제 패키징(packaging)을 실행하면 '/dist/ReleaseClass'폴더에 아래와 같이 출력물이 만들어 집니다.

 

'tsc' 명령이 처음에는 잘된 이후로는 파일이 생성되지 않는 문제가 있는 경우가 있습니다.

이런 경우 '.tsbuildinfo'를 찾아서 지우면 다시 잘 생성되는 것을 알 수 있습니다.

 

이것은 '.tsbuildinfo'파일이 마지막으로 빌드된 정보를 가지고 있어서 변경 사항이 없으면 빌드를 하지 않기 때문입니다.

변경 사항과 관계없이 빌드하고 싶다면 '--clean'을 사용하면 됩니다.

 

그런데.....이유는 모르겠지만 'tsconfig.tsbuildinfo'는 잘만 지워지는데 'tsconfig.deploy.tsbuildinfo'는 지워지질 않습니다.

'rm -f tsconfig.deploy.tsbuildinfo' 도 글자가 깨지면서 동작하지 않는데....이유를 모르겠네요;;;;;

(해결 방법 아시면 댓글 부탁드립니다.)

 

변경 사항이 있으면 빌드가 되니 쓰는 데 문제는 없어 일단을 수동으로 지우는 것을 가정하고 사용하면 됩니다.

 

 

5. 배포 및 테스트 

수동으로 배포한다는 의미는 출력물만 손으로 복사해서 쓰라는 의미입니다.

 

 

새로운 프로젝트를 만들고 적당한 위치에 위에서 출력한 출력물을 복사해서 넣습니다.

(이 포스팅에서는 '/src/Utility/ReleaseClass'에 넣었습니다.)

 

자기가 테스트 편하게 프로젝트를 구성한 후

위에서 복사한 라이브러리를 임포트시킵니다.

 

테스트용 코드는 아래와 같습니다.

index.ts

import ReleaseClassTest from "./Utility/ReleaseClass/ReleaseClassTest";

export default class App
{
	/** 지금 보여주고 있는 페이지에서 사용할 개체 */
	public PageNow: any = null;

	constructor()
	{
		//메뉴 추가
		let divMain = document.getElementById("divMain");
		divMain.innerHTML = "Test";

		let temp: ReleaseClassTest = new ReleaseClassTest();
		console.log(temp.TestString());
	}
}

(window as any).app = new App();

 

 

설명 파일과 같이 배포하였으므로 설명용 주석도 잘 나옵니다.

 

 

이제 실행해 보면 라이브러리도 잘 동작하는 것을 볼 수 있습니다.

 

 

마무리 

테스트 프로젝트 

- 라이브러리 : dang-gun/HtmlJavascriptSamples_sln/tree/main/TypeScriptManualDeploy_Library

- 라이브러 사용 : dang-gun/HtmlJavascriptSamples_sln/tree/main/TypeScriptManualDeploy_Test

 

진입점 없는 라이브러리의 경우 일반 빌드까지는 큰 문제가 아니라고 할 수 있습니다.

파일 합치기가 가장 큰 문제죠 ㅎㅎㅎㅎ