프로젝트 하위의 특정 디렉토리를 루트로 npm 배포하기

hyeonQyu·2022년 7월 22일
4
post-thumbnail

npm 패키지를 직접 개발해서 배포하던 도중 스스로 원하는 요구사항이 생겼습니다.

package.json이 있는 프로젝트 디렉토리 루트 전체가 아닌 특정 하위 디렉토리만 배포하고 싶다!

요구사항

먼저 프로젝트 디렉토리가 아래와 같이 구성되어 있었습니다.
📂project
   📂src
   🗒️package.json
   🗒️.gitignore
   🗒️.npmignore
   🗒️README.md
     ...

그럼 패키지를 배포했을 때 📂project가 루트가 되어 패키지가 되는 것이 아닌 하위 폴더, 이를테면..
📂project
   📂dist
   📂src
   🗒️package.json
   🗒️.gitignore
   🗒️.npmignore
   🗒️README.md
     ...

📂dist 폴더가 루트가 되어 📂dist 폴더 안에 있는 파일로만 구성된 패키지를 추출해 배포하고 싶었던 것이죠.

왜?

근데 저는 왜 그런 생각을 하게 된걸까요?

  • 내가 배포할 패키지는 타 애플리케이션 개발 시 스크립트단에서 사용되는 라이브러리가 아니었다. 하나의 프로그램 자체였다.
  • 그리고 나는 이를 typescript를 사용해서 개발했다.

위의 이유로 typescipt 코드가 패키지에 굳이 포함될 필요가 없었던 것이죠. 배포한 프로그램을 실행시킬 수 있는 javascript 코드만 있으면 됐으니까요.

다시 프로젝트 구조로 돌아와서 더 자세하게 그림을 그리면 아래와 같습니다.
배포하고자 하는 파일 및 폴더는 굵게 표시했습니다.
📂project
   📂dist
       📂bin
           🗒️cli.js
       📂lib
           🗒️index.js
             ...
   📂src
       📂bin
           🗒️cli.ts
       📂lib
           🗒️index.ts
             ...
   🗒️package.json
   🗒️.gitignore
   🗒️.npmignore
   🗒️README.md
     ...

제가 직접 작성하게 되는 것은 🗒️cli.ts🗒️index.ts 등과 같은 typescript 코드입니다.
개발을 완료한 후 이 typescipt로 작성된 스크립트를 컴파일하면 javascript 파일이 생성되고 이들을 📂dist 폴더에 넣었습니다.
그리고 이 📂dist 폴더는 git repository에는 올라갈 필요가 없으므로 .gitignore에 추가했습니다.
그럼 저는 개발한 애플리케이션이 실제로 돌아가기 위한 코드인 📂dist 폴더 안에 있는 javascript 녀석들만 배포하면 되는 것이죠!

📂src 폴더를 .npmignore에 넣기 (👎)

열심히 구글링하며 방법을 강구했지만 package.json에 특정 하위 디렉토리를 루트로 배포할 수 있는 설정은 따로 없는 것 같았습니다..ㅠ

그래서 먼저 실행에 옮긴 방법은 📂src 폴더를 .npmignore에 넣는 것이었습니다.
그러나 이 방법은 조금 멋이 없었죠..

일단 내가 패키지를 배포했을 때 원했던 모습은 이랬습니다.
📂my-package
   📂bin
       🗒️cli.js
   📂lib
       🗒️index.js
         ...
     ...

루트 바로 하위에 📂bin, 📂lib 폴더가 위치하는 모습이죠.
그럼 위와 같은 모습으로 패키지가 구성되도록 하기 위해서는 빌드된 javascript를 📂dist 폴더에 넣는 것이 아니라 📂project 루트 바로 하위에 넣어야 했습니다.
아래처럼 말이죠.
📂project
   📂bin
       🗒️cli.js
   📂lib
       🗒️index.js
         ...
   📂src
       📂bin
           🗒️cli.ts
       📂lib
           🗒️index.ts
             ...
   🗒️package.json
   🗒️.gitignore
   🗒️.npmignore
   🗒️README.md
     ...

그리고 아까 .gitigonre에 작성해주었던 📂dist 폴더를 지우고 📂bin📂lib를 추가해주었습니다.

그럼 원하는 모양으로 패키지 배포가 가능합니다. 그러나 📂project 폴더 바로 아래에 뭔가가 많아졌네요.
만약 📂bin, 📂lib 뿐 아니라 더 많은 폴더나 파일이 패키지에 포함된다면 더더욱 많아질 것이고 관리하기 복잡하다고 느낄 수 있겠죠.
그리고 빌드된 파일은 확실하게 📂dist와 같은 하나의 폴더에 생성되는 것이 깔끔합니다.

📂dist 폴더만 배포하기 (👍)

그렇다면 역시 처음 생각한대로 📂dist폴더를 루트로 배포해야 합니다. 역시 그게 제일 깔끔해요.
근데 package.json에 그렇게 할 수 있는 설정이 없다며???
뭐 그럼 다른 방법이 있지 않겠습니까?ㅎㅎ

역시 있었습니당!ㅋㅋ 아래 링크를 참고했어요.
https://newbedev.com/how-to-npm-publish-specific-folder-but-as-package-root

영문이라 읽기 싫으신 분들이 있을 수 있기에 저 방법을 따라한대로 적어보자면...

먼저 프로젝트 루트 디렉토리에 setupPackage.js를 작성합니다.

const fs = require('fs');

function main() {
    const source = fs.readFileSync(__dirname + '\\package.json').toString('utf-8');
    const sourceObj = JSON.parse(source);
    sourceObj.scripts = {};
    sourceObj.devDependencies = {};
    if (sourceObj.main.startsWith('\\dist\\')) {
        sourceObj.main = sourceObj.main.slice(5);
    }
    fs.writeFileSync(__dirname + '\\dist\\package.json', Buffer.from(JSON.stringify(sourceObj, null, 2), 'utf-8'));
    fs.writeFileSync(__dirname + '\\dist\\version.txt', Buffer.from(sourceObj.version, 'utf-8'));

    fs.copyFileSync(__dirname + '\\.npmignore', __dirname + '\\dist\\.npmignore');
}

main();

필자의 경우 📂dist 폴더를 루트로 배포하고자 하기 때문에 코드에 \\dist\\와 같이 작성하였으나 다른 폴더 이름을 사용하게 된다면 코드에서 수정해주어야 해요.

코드가 수행하는 작업은 📂dist 폴더에 package.json.npmigonre을 복사하는 것입니다. 이때 package.json에서 배포시 불필요한 scriptdevDependencies 속성은 제거하게 되죠.

그리고 package.jsonscripts"build-publish" 명령어를 추가합니다.

"scripts": {
	...
	"build": "tsc -p .",
    "build-publish": "npm run build && node setupPackage.js && cd dist && npm publish"
  },

이후 터미널에

$ npm run build-publish

커맨드를 입력하면 배포에 필요한 package.json.npmigonre 파일이 📂dist 폴더에 복사되고 📂dist 폴더에서 npm-publish가 수행됩니다.

그럼 처음에 원했던대로 📂dist 폴더를 루트로 즉 아래와 같은 모양으로 배포가 성공적으로 된 것을 확인할 수 있습니다!
📂my-package
   📂bin
       🗒️cli.js
   📂lib
       🗒️index.js
         ...
     ...

profile
백엔드가 하고 싶었던 프론트엔드 개발자

0개의 댓글