[번역] 최신 npm 패키지를 만들기 위한 모범 사례

Sonny·2022년 9월 27일
36

Article

목록 보기
3/27
post-thumbnail

원문: https://snyk.io/blog/best-practices-create-modern-npm-package/

기술은 항상 변화하고 있고 여러분의 프로세스와 관행은 이러한 변화를 따라잡아야 합니다. npm이 출시된 지 12년이 되었지만, npm 패키지 생성에 대한 당신의 관행은 훨씬 더 현대적이기를 바랍니다. 여러분들의 관행이 약간 구식일 수 있다는 느낌이 든다면 계속 읽어주세요.

이 튜토리얼에서는 최신 모범 사례(2022년 기준)를 사용하여 npm 패키지를 만드는 과정을 단계별로 살펴보겠습니다. 제일 먼저 npm 패키지를 만드는 방법에 대해 배우며 패키지를 빌드하고 npm 레지스트리(registry)에 게시하는 방법에 익숙해질 수 있습니다. 이후 테스트 프레임워크와 지속적인 통합 및 배포 파이프라인, 보안 검사 그리고 릴리스를 위한 자동화된 시맨틱 버전 관리를 설정하여 보다 강력하고 프로덕션에서 바로 사용할 수 있는 npm 패키지를 만드는 것과 관련된 사항을 배우게 됩니다. 이 튜토리얼이 끝나면 현대적이고 지속 가능한 npm 패키지를 생산할 수 있다는 자신감을 갖게 될 것입니다. 시작하겠습니다!

전제 조건

  1. Node.js, 자바스크립트, 깃허브 및 깃허브 액션에 대한 지식
  2. npm 패키지 생성을 지원하는 개발 도구

간단한 예제 npm 패키지

먼저 간단한 예제를 사용하여 npm 패키지를 만들고 게시하는 프로세스에 대해 알아보겠습니다. 이미 이 프로세스에 익숙하다면 더 고급 주제를 다루는 npm 패키지 프로덕션 준비섹션으로 건너뛸 수 있습니다.

프로젝트 설정

시작하기 위해 깃허브 프로젝트가 필요하므로 다음 단계를 따라 프로젝트를 시작하세요. 이미 사용할 프로젝트가 있는 경우, 다음 섹션으로 건너뛸 수 있지만 패키지 이름과 관련하여 이 섹션의 5단계를 다시 확인하세요.

  1. 깃허브 리퍼지토리를 생성합니다.

    https://github.com/new

  2. 리퍼지토리를 로컬로 복제합니다.

    예시:
    git clone https://github.com/snyk-labs/simple-npm-package.git

  3. 터미널을 열고 디렉토리를 복제된 프로젝트의 폴더로 변경합니다.

    예시: cd simple-npm-package

  4. npm init -y를 실행하여 package.json 파일을 생성합니다. 참고: 예제 리퍼지토리를 복제한 경우, 이 단계를 수행할 필요가 없습니다.

  5. package.json 파일의 name 프로퍼티를 범위가 지정된 이름으로 수정해야 합니다.

    예시: @snyk-labs/simple-npm-package. @snyk-labs 대신 사용자명 또는 단체명을 사용하세요.

  6. 패키지에 대한 코드를 작성하세요 (또는 index.js의 hello world 예제를 사용하세요).

프로젝트가 생성되면 npm 계정 생성으로 넘어갈 수 있습니다. 이 튜토리얼의 나머지 부분을 통해 리퍼지토리의 로컬 복제본(clarkio/simple-npm-package)에서 작업하고 있음을 알 수 있습니다.

npm 계정 설정

npm 패키지를 다른 사람이 사용할 수 있도록 하려면 npm 계정이 필요합니다. 다음 단계에서는 아직 계정이 없는 경우, 자신의 계정을 만들고 2단계 인증(2FA)을 활성화하여 계정 보안을 강화하고 계정을 로컬 컴퓨터에 연결하는 과정을 안내합니다.

  1. https://www.npmjs.com/signup에서 npm에 가입하세요.

  2. 더 나은 보안을 위해, npm 계정에서 2FA를 활성화하세요.

    https://docs.npmjs.com/configuring-two-factor-authentication

  3. npm login 커맨드를 사용하여 터미널에서 npm 계정으로 로그인하고 화면 지침을 따릅니다.

> npm login
npm notice Log in on https://registry.npmjs.org/
Username: clarkio
Password:
Email: (this IS public) <email address>
npm notice Please use the one-time password (OTP) from your authenticator application
Enter one-time password from our authenticator app: <OTP>
Logged in as clarkio on https://registry.npmjs.org/.

npm 패키지를 게시하는 방법

npm 프로젝트와 npm 계정이 있으면 다른 사람들이 사용할 수 있도록 npm 패키지를 공개된 공식적인 npmjs 리퍼지토리에 게시할 준비가 된 것입니다. 다음 단계는 이를 실행한 이후, 실제 게시 프로세스를 실행하기 전에 게시할 내용을 확인하기 위해 따라야 하는 단계입니다.

  1. 터미널에서 npx npm-packlist 명령어를 실행하여 게시된 패키지 버전에 포함될 내용을 확인합니다.

    이렇게 하면 패키지가 제대로 작동하기 위해 필요한 소스 코드 파일이 누락되지 않습니다. 또한 데이터베이스 자격 증명 또는 API 키가 있는 로컬 구성 파일과 같은 민감한 정보를 실수로 대중에게 유출하지 않도록 하는 것도 좋은 방법입니다.

    > npx npm-packlist
    LICENSE
    index.js
    package.json
    README.md
  2. 터미널에서 npm publish --dry-run 명령어를 실행하여 실제로 명령어를 실행시킬 때 수행되는 작업을 확인합니다.

    > npm publish --dry-run
    npm notice
    npm notice 📦@clarkio/simple-npm-package@0.0.1
    npm notice === Tarball Contents ===
    npm notice 1.1kB LICENSE
    npm notice 1.2kB README.md
    npm notice 95B index.js
    npm notice 690B package.json
    npm notice === Tarball Details===
    npm notice name: @clarkio/simple-npm-package
    npm notice version: 0.0.1
    npm notice filename:@clarkio/simple-npm-package-0.0.1.tgz
    npm notice package size:1.7 kB
    npm notice unpacked size: 3.1 kB
    npm notice shasum:40ede3ed630fa8857c0c9b8d4c81664374aa811c
    npm notice integrity:sha512-QZCyWZTspkcUXL... ]L60ZKBOOBRLTg==
    npm notice total files:4
    npm notice
    + @clarkio/simple-npm-package@0.0.1
  3. 터미널에서 npm publish --access=public 명령어를 실행하여 실제로 npm에 패키지를 게시합니다.

    참고: 범위가 지정된 패키지(@clarkio/modern-npm-package)는 기본적으로 비공개이기 때문에 --access=public 명령어가 필요합니다. 범위가 지정되지 않고 비공개 필드가 없다면 package.json 파일에서 true로 설정하여도 공개적이게 됩니다.

    > npm publish --access=public
    npm notice
    npm notice 📦@clarkio/simple-npm-package@0.0.1
    npm notice === Tarball Contents ===
    npm notice 1.1kB LICENSE
    npm notice 1.2kB README.md
    npm notice 95B index.js
    npm notice 690B package.json
    npm notice === Tarball Details===
    npm notice name: @clarkio/simple-npm-package
    npm notice version: 0.0.1
    npm notice filename:@clarkio/simple-npm-package-0.0.1.tgz
    npm notice package size:2.1 kB
    npm notice unpacked size: 4.1 kB
    npm notice shasum:6f335d6254ebb77a5a24ee729650052a69994594
    npm notice integrity:sha512-VZ1K1eMFOKeJW[...]7ZjKFVAxLcpdQ==
    npm notice total files:4
    npm notice
    This operation requires a one-time password.
    Enter OTP: <OTP>
    + @clarkio/simple-npm-package@0.0.1

고유한 npm 패키지 빌드 및 배포를 완료했습니다! 다음으로 프로덕션 환경에 사용할 준비가 되어 있고 더 광범위하게 사용할 수 있는 더 강력한 패키지를 만드는 방법을 배우겠습니다.

프로덕션 준비가 된 npm 패키지

이전 예제 패키지는 프로덕션에서 잠재적으로 사용될 수 있지만 시간이 지남에 따라 유지 보수를 하기 위해 수동적인 작업이 필요합니다. 적절한 테스트 및 보안 검사와 함께 도구 및 자동화를 사용하면 패키지를 원활하게 실행하기 위한 노력을 최소화하는 데 도움이 됩니다. 그 내용이 무엇인지 자세히 알아보도록 하겠습니다.

아래의 섹션에서는 다음 내용을 다룹니다.

  1. modern-npm-package 프로젝트 설정
  2. CommonJS(CJS) 및 ECMA Script(ESM) 모듈 형식 모두를 위한 빌드
  3. 단위 테스트 설정 및 작성
  4. 보안 검사 구현
  5. 버전 관리 및 게시 자동화

이 문서를 따라 하는 동안 사용할 자체 프로젝트가 없는 경우, 다음 예제 프로젝트를 참조로 사용할 수 있습니다. 참고: https://github.com/snyk-labs

프로젝트 설정

시작하기 위해 깃허브 프로젝트가 필요하므로 다음 단계에 따라 프로젝트를 시작하세요. 이미 사용할 프로젝트가 있는 경우, 다음 섹션으로 건너뛸 수 있지만 패키지 이름과 관련하여 이 섹션의 5단계를 다시 확인하세요.

  1. 깃허브 리퍼지토리를 생성합니다.

    https://github.com/new

  2. 리퍼지토리를 로컬로 복제합니다.

    예시:
    git clone https://github.com/snyk-labs/simple-npm-package.git

  3. 터미널을 열고 디렉토리를 복제된 프로젝트의 폴더로 변경합니다.

    예시: cd modern-npm-package

  4. npm init -y를 실행하여 package.json 파일을 생성합니다. 참고: 예제 리퍼지토리를 복제한 경우, 이 단계를 수행할 필요가 없습니다.

  5. package.json 파일의 name 프로퍼티를 범위가 지정된 이름으로 수정해야 합니다.

    예시: @snyk-labs/simple-npm-package. @snyk-labs 대신 사용자명 또는 단체명을 사용하세요.

  6. 패키지에 대한 코드를 작성하세요 (또는 index.js의 hello world 예제를 사용하세요).

프로젝트가 생성되면 npm 계정 생성으로 넘어갈 수 있습니다. 이 튜토리얼의 나머지 부분을 통해 리퍼지토리의 로컬 복제본(clarkio/modern-npm-package)에서 작업하고 있음을 알 수 있습니다.

CommonJS 및 ECMAScript 모듈 형식 모두를 위한 빌드

ECMAScript 모듈 형식은 이제 버전 12+부터 Node.js에서 기본적으로 지원되지만 아직 커뮤니티에서 널리 채택되지는 않았습니다. 미래를 대비하고 두 형식을 모두 지원하기 위한 일환으로 타입스크립트를 사용하여 npm 패키지를 준비하는 방법을 살펴보겠습니다.

  1. 먼저 파일명이 tsconfig.base.json인 타입스크립트 기본 구성 파일을 생성합니다. 이 파일은 대상으로 하는 모든 모듈 형식에 관계없이 사용할 수 있는 일반적인 컴파일 설정을 위한 것입니다. 프로젝트에 필요한 대로 자유롭게 조정할 수 있으며 제공된 예제를 사용하지 않는 경우, 특히 files 프로퍼티를 프로젝트 구조에 맞게 조정하고 싶으실 겁니다.

    {
      "compilerOptions": {
        "strict": true,
        "esModuleInterop": true,
        "forceConsistentCasingInFileNames": true,
        "skipLibCheck": true,
        "checkJs": true,
        "allowJs": true,
        "declaration": true,
        "declarationMap": true,
        "allowSyntheticDefaultImports": true
      },
      "files": ["../src/index.ts"]
    }
  2. 그런 다음 CommonJS 형식에 대한 타입스크립트 구성 파일을 만들고 파일명을 tsconfig.cjs.json으로 설정합니다.

  • lib 프로퍼티는 프로젝트 코드를 작성하는 동안 도움이 되도록 참조해야 하는 유형을 타입스크립트에게 알려줍니다.

  • target 프로퍼티는 프로젝트 코드를 컴파일할 자바스크립트 버전을 타입스크립트에 나타냅니다.

  • module 프로퍼티는 프로젝트 코드를 컴파일할 때 사용하는 자바스크립트 모듈 형식을 타입스크립트에 나타냅니다.

  • moduleResolution 프로퍼티는 타입스크립트가 "import"문을 참조하는 방법을 파악하는 데 도움이 됩니다.

  • outDirdeclarationDir 프로퍼티는 코드를 컴파일하고 코드 내에서 사용되는 타입을 정의한 결과를 배치할 위치를 타입스크립트에 나타냅니다.

    {
      "extends": "./tsconfig.base.json",
      "compilerOptions": {
        "lib": ["ES6", "DOM"],
        "target": "ES6",
        "module": "CommonJS",
        "moduleResolution": "Node",
        "outDir": "../lib/cjs",
        "declarationDir": "../lib/cjs/types"
      }
    }
  1. 그런 다음 ECMAScript 형식에 대한 타입스크립트 구성 파일을 만들고 파일명을 tsconfig.esm.json으로 설정합니다. 이 파일에 있는 프로퍼티들은 CommonJS 구성에서 본 것과 동일하지만 이제 최신 ECMAScript 모듈 형식 출력을 대상으로 합니다.

    {
      "extends": "./tsconfig.base.json",
      "compilerOptions": {
        "lib": ["ES2022", "DOM"],
        "target": "ES2022",
        "module": "ESNext",
        "moduleResolution": "NodeNext",
        "outDir": "../lib/esm",
        "declarationDir": "../lib/esm/types"
      }
    }
  2. package.json 파일을 패키지 빌드된 타입스크립트 결과를 담은 lib폴더를 가리키고 있는 files 필드로 수정하세요.

  3. 사용 중인 모듈 로더(CJS vs ESM)를 기반으로 소스 파일을 찾는 방법을 정의하려면 package.json 파일의 exports 필드 수정하세요. Node.js 문서에서 이 exports 필드 지원 정보에 대해 자세히 읽을 수 있습니다.

    "exports": {
        ".": {
          "import": {
            "types": "./lib/esm/types/index.d.ts",
            "default": "./lib/esm/index.mjs"
          },
          "require": {
            "types": "./lib/cjs/types/index.d.ts",
            "default": "./lib/cjs/index.js"
          }
        }
      },
  4. 패키지의 CJS 버전을 가리키도록 package.json 파일의 main 그리고 types 필드를 수정하세요. 이것은 기본, 대체, 옵션으로 작동합니다.

    “types": "./lib/cjs/types/index.d.ts",
    "main": "./lib/cjs/index.js",
  5. package.json 파일에 files 필드를 추가하여 npm이 게시를 위해 코드를 패키지화할 때 포함해야 하는 파일을 나타냅니다.

    "files": [
       "lib/**/*"
    ],
  6. package.jsonscripts 필드를 통해 tsc를 사용하고 패키지의 CJS 및 ESM 형식을 모두 컴파일하는 명령어를 작성하세요. 그러면 lib 폴더에 대한 소스 파일이 생성됩니다.

  • clean 스크립트는 과거 빌드의 출력을 삭제하고 모두 제거된 초기 상태에서 시작하는 데 사용됩니다.

  • build:esm 스크립트 끝에 있는 mv lib/esm/index.js lib/esm/index.mjs는 Node.js 모듈 로더가 ESM 모듈임을 알 수 있도록 파일 확장자의 이름을 바꿉니다.

  • prepack 스크립트는 레지스트리에 게시하기 위해 npm 패키지를 패키징 하기 전에 npm에서 사용됩니다.

    "clean": "rm -rf ./lib",
    "build": "npm run clean && npm run build:esm && npm run build:cjs",
    "build:esm": "tsc -p ./configs/tsconfig.esm.json && mv lib/esm/index.js lib/esm/index.mjs",
    "build:cjs": "tsc -p ./configs/tsconfig.cjs.json",
    "prepack": "npm run build"
  1. 이제 사용 및 게시 준비를 위해, 터미널에서 npm run build 명령어를 실행하여 타입스크립트가 프로젝트를 빌드하도록 할 수 있습니다.

이것이 CommonJS 및 ECMAScript 모듈 형식을 모두 지원하는 npm 패키지를 빌드하기 위한 타입스크립트의 모든 설정입니다. 다음으로 npm 패키지 코드에 대해 테스트를 설정하고 실행하여 예상한 결과를 생성하는지 확인하는 방법을 배웁니다.

테스트 설정 및 추가

코드의 동작과 결과에 대한 확신을 가지려면 테스트 프로세스를 구현해야 합니다. 테스트는 코드를 처음 생성할 때 일반적이고 행복한 경로를 벗어나 다른 방식으로 코드의 기능에 대해 생각하도록 합니다. 예를 들어 함수를 중단하여 오류를 발생시키거나 의도하지 않은 결과를 생성하는 방법을 생각할 수 있습니다. 이는 애플리케이션을 더 탄력 있고 지속 가능하게 만들 뿐만 아니라 새로운 기능이 추가될 때도 정상 동작을 보장해줍니다.

테스트에 대해 자세히 살펴보고 모범 사례에 대해 배우고 싶다면 Yoni Goldberg의 자바스크립트 모범 사례 리퍼지토리를 읽어보세요.

단위 테스트

패키지가 원하는 방식으로 작동하는지 확인하려면 코드에 대한 테스트를 작성해야 합니다. 단위 테스트를 실행하고 결과를 표시하도록 하려면 프로젝트를 설정하는 데 도움이 되는 몇 가지 도구인 Mocha.js, Chai.js 그리고 ts-node가 필요합니다. Mocha.js는 테스트 러너이고 Chai.js는 코드에서 예상한 결과를 얻고 있는지 확인하는 데 도움이 되는 어설션(assertion) 라이브러리이며 ts-node는 타입스크립트 프로젝트에서 이러한 도구를 사용하는 데 도움이 됩니다. 아래 단계에 따라 npm 패키지에 대한 테스트를 설정하고 실행하세요.

  1. 터미널에서 다음 명령을 사용하여 개발 종속성(developer dependencies)을 설치합니다.

    npm i -D mocha @type/mocha chai @types/chai ts-node

  2. 아래의 내용으로 프로젝트의 루트 디렉토리에 .mocharc.json이라는 파일명의 파일을 생성합니다.

    {
         "extension": ["ts"],
         "spec": "./**/*.spec.ts",
         "require": "ts-node/register"
    }
  3. 프로젝트 루트 디렉토리에 tests 폴더를 생성합니다.

  4. tests 폴더에 index.spec.ts 파일을 생성합니다.

  5. index.spec.ts 파일에 단위 테스트를 작성하여 index.ts의 코드를 테스트합니다.

    참고: 예제 npm 패키지 저장소에서 예시를 참고할 수 있습니다. https://github.com/snyk-labs/modern-npm-package/blob/main/tests/index.spec.ts

  6. package.json 파일의 scripts 섹션에 test 프로퍼티를 추가하고 값을 mocha로 지정합니다.

    "scripts": {
        "clean": "rm -rf ./lib",
        "build": "npm run clean && npm run build:esm && npm run build:cjs",
        "build:esm": "tsc -p ./configs/tsconfig.esm.json && mv lib/esm/index.js lib/esm/index.mjs",
        "build:cjs": "tsc -p ./configs/tsconfig.cjs.json",
        "prepack": "npm run build",
        "test": "mocha"
    },
  7. 프로젝트의 루트 폴더에서 터미널의 npm test 명령어를 실행하여 테스트를 실행하고 결과를 확인합니다.

    bc@mbp-snyk modern-npm-package % npm test
    > @clarkio/modern-npm-package@0.0.0-development test
    > mocha
      NPM Package
        ✔️ should be an object
        ✔️ should have a helloworld property
      Hello World Function
        ✔️  should be a function
        ✔️ should return the hello world message
    4 passing (22ms)

파이프라인에서 테스트

이제 코드 동작을 검증하는 테스트가 있으므로 파이프라인에서 사용할 수 있습니다. 이것은 리퍼지토리에 도입된 변경 사항이 코드 동작을 손상시키지 않도록 하는 데 도움이 됩니다. 프로젝트 파이프라인의 일부로 테스트 워크플로를 만들려면 다음 단계를 따르세요.

  1. 리퍼지토리에 대한 새 깃허브 액션을 생성합니다.

    https://github.com/<your-account-or-organization>/<your-repo-name>/actions/new

  2. 워크플로의 이름을 tests.yml로 바꿉니다.

  3. 워크플로 파일에 아래의 Snyk Action 스크립트를 삽입합니다.

    name: Tests
    on:
      push:
        branches: [ main ]
      pull_request:
        branches: [ main ]
    jobs:
      build:
        runs-on: ubuntu-latest
        strategy:
          matrix:
            node-version: [12.x, 14.x, 16.x, 18.x]
        steps:
          - uses: actions/checkout@v3
          - name: Use Node.js ${{ matrix.node-version }}
            uses: actions/setup-node@v3
            with:
              node-version: ${{ matrix.node-version }}
          - run: npm ci
          - run: npm test

이 YAML 스크립트는 최신 코드를 확인하고 종속성을 설치하며 npm test 명령어를 실행하여 테스트를 실행합니다. node-version 필드에 나열된 Node.js의 모든 버전에 대해 이 작업을 수행하므로 각 런타임에서 코드가 예상대로 작동하는지 확인할 수 있습니다.

이제 npm 패키지의 코드에 대해 테스트를 실행하고 평가하기 위한 프로젝트 설정을 완료했습니다. 그러나 "다른 프로젝트에서 내 npm 패키지를 사용하여 테스트하는 방법은 무엇인가요?"라고 생각할 수 있습니다. 다음으로 이 부분을 설정하는 방법을 살펴보겠습니다.

패키지 테스트

단위 테스트를 통해 npm 패키지의 코드에 대한 확신을 갖는 것과 전체 npm 패키지를 사용하는 경험을 보장하는 것은 별개입니다. 이 작업에는 npm 패키지를 다른 프로젝트에 대한 종속성으로 가져와서 사용이 예상대로 원활하게 진행되는지 확인하는 작업이 포함됩니다. 이를 테스트할 수 있는 다섯 가지 방법은 다음과 같습니다.

  1. npm pack 출력을 통해 설치
  2. 상대 경로를 통해 설치
  3. npm link를 통해 설치
  4. 레지스트리를 통해 설치 (예시: npmjs.com의 npm 공개 레지스트리)
  5. Verdaccio(npm 사설의 npm 레지스트리 프로젝트 오픈 소스)를 사용하여 종단 간 패키지(end-to-end package)를 실행하고 CI의 일부로 단계를 설치합니다.

npm pack

이 접근 방식은 npm pack 명령어를 활용하여 npm 패키지를 단일 파일(<package-name>.tgz)로 패키지화하고 압축합니다. 그런 다음 패키지를 사용하려는 프로젝트로 이동하여 이 파일을 통해 설치할 수 있습니다. 이를 수행하는 단계는 다음과 같습니다.

  1. npm 패키지 디렉토리 내에서 터미널에서 npm pack 명령어를 실행하고 생성하는 .tgz 파일과 그 위치를 기록해 두세요.

  2. 디렉토리를 npm 패키지로 사용하려는 프로젝트 디렉토리로 변경합니다.

    예시: cd /path/to/project

  3. 클라이언트 프로젝트 디렉토리 내에서 npm install /path/to/package.tgz를 실행하되 1단계의 .tgz 파일 위치에 대한 적절한 경로로 대체합니다.

  4. 이후 해당 클라이언트 프로젝트의 패키지를 사용하여 테스트할 수 있습니다.

이렇게 하면 npm 패키지를 사용하여 프로덕션 환경에 가장 가까운 경험을 제공할 수 있습니다.

이 접근 방식은 npm link명령어를 활용하여 클라이언트 프로젝트에 패키지를 설치하려고 할 때 패키지 디렉토리를 가리킵니다. 이를 수행하는 단계는 다음과 같습니다.

  1. npm 패키지 디렉토리 내 터미널에서 npm link명령어를 실행

  2. 디렉토리를 npm 패키지를 사용하려는 프로젝트 디렉토리로 변경합니다.

    예시: cd /path/to/project

  3. 클라이언트 프로젝트 디렉토리 내에서 npm link <name-of-your-package> 명령어를 실행합니다.

이렇게 하면 코드에서 사용할 패키지를 참조할 때 클라이언트 프로젝트가 npm 패키지 디렉토리를 가리킵니다. 이것은 패키지 사용에 대한 완전한 프로덕션과 같은 경험을 제공하지 않지만 기능이 예상대로 작동하는지 확인할 수 있습니다.

상대 경로

이 접근 방식은 npm install 명령어에 대한 기존 지식을 활용합니다. link와 같은 새로운 명령어를 몰라도 npm link와 비슷합니다.

  1. 클라이언트 프로젝트 디렉토리 내 터미널에서 npm install /path/to/your/package 명령어를 실행합니다.

npm link 접근 방식과 유사하게 이를 통해 클라이언트 프로젝트 내에서 패키지 기능을 빠르게 테스트할 수 있지만 완전한 프로덕션과 같은 경험을 제공하지는 못합니다. 이는 npm 레지스트리에서 찾을 수 있는 빌드 된 버전의 패키지가 아니라 전체 패키지 소스 코드 디렉토리를 가리키기 때문입니다.

npm 레지스트리

이 접근 방식은 npm 패키지에 대한 공개(또는 자체) 레지스트리 사용을 활용합니다. 여기에는 다른 npm 패키지에 대해 일반적으로 하는 것처럼 패키지를 게시하고 설치하는 작업이 포함됩니다.

  1. npm publish명령어를 통해 이 문서의 앞부분에 설명된 단계를 사용하여 npm 패키지를 게시합니다.

  2. 디렉토리를 npm 패키지를 사용하려는 프로젝트 디렉토리로 변경합니다.

    예시: cd /path/to/project

  3. 클라이언트 프로젝트 디렉토리 내에서 npm install <name-of-your-package> 명령어를 실행합니다.

실시간 스트리밍 중 이에 대한 우리의 학습을 요약한 Twitter 스레드를 만든 Mirco Kraenz(@MKraenz)에게 감사의 인사를 전하세요!

이제 최신 모듈 형식을 지원하도록 패키지를 빌드했으며 단위 테스트 및 패키징 테스트를 통해 예상대로 작동하는지 확인했습니다. 다음으로 보안 문제가 없는지 확인하고 npm 패키지에 새로운 문제가 발생하지 않도록 해야 합니다.

보안 검사 구현

자신의 프로젝트에서 보안 취약성을 원하지 않는 것과 마찬가지로 다른 사람의 프로젝트에도 취약성을 도입하고 싶지 않습니다. 다른 많은 프로젝트에서 사용될 것으로 예상되는 npm 패키지를 빌드 하면 보안을 유지해야 하는 책임이 커집니다. 취약점을 모니터링하고 경고하며 지원을 제공하는 데 도움이 되는 보안 검사를 마련해야 합니다. Snyk와 같은 도구를 통해 이러한 요구 사항을 달성하는 데 필요한 작업을 단순화할 수 있습니다.

이 예제 npm 패키지의 경우 깃허브를 소스 제어 관리 도구로 사용하고 있으므로 깃허브 작업 기능을 활용하여 워크플로에 Snyk를 통합합니다. Snyk에는 이 작업을 바로 시작하는 데 도움이 되는 GitHub Actions 참조 프로젝트가 있으며 프로젝트에 사용할 수 있는 다른 프로그래밍 언어 및 도구에 대한 예제를 제공합니다.

  1. Snyk는 무료이므로 가입하고 Snyk API 토큰을 받으세요.

  2. 깃허브에서 Snyk API 토큰을 리퍼지토리 암호로 추가하세요.

    https://github.com/<your-account-or-organization>/<your-repo-name>/settings/secrets/actions/new

  3. 리퍼지토리에 대한 새로운 깃허브 액션을 생성하세요.

    https://github.com/<your-account-or-organization>/<your-repo-name>/actions/new

  4. 워크플로의 이름을 snyk.yml로 바꿉니다.

  5. 워크플로 파일에 아래의 Snyk Action 스크립트를 삽입합니다.

    name: Snyk Security Check
    on: [push,pull_request]
    jobs:
      security:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@main
          - name: Run Snyk to check for vulnerabilities
            uses: snyk/actions/node@master
            env:
              SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
  6. 변경 사항을 커밋 합니다.

  7. 작업이 성공적으로 실행되었는지 확인합니다.

    https://github.com/<your-account-or-organization>/<your-repo-name>/actions

이제 이것을 설정하면 누구든지 저장소에 푸시 하거나 그에 대한 pull request를 열 때마다 보안 검사가 실행되어 패키지에 취약점이 발생하지 않도록 합니다. 문제가 발견되면 작업이 실패하고 발견된 보안 문제에 대한 세부 정보를 알려줍니다. 다음으로 npm 패키지의 버전 관리 및 게시와 관련된 프로세스를 자동화합니다.

현재 설정에 대해 주의할 점은 Snyk 코드 (SAST)가 아닌 Snyk 오픈 소스 (SCA) 제품만 활용한다는 것입니다. Snyk 코드는 당사의 코드 보안 제품이며, 먼저 Snyk 계정을 통해 이를 활성화(무료) 한 다음 여기에서 워크플로 스크립트에 추가하여 최대한 활용해야 합니다. 파이프라인에서 Snyk 코드를 사용하는 방법에 대해 자세히 알아보려면 깃허브 액션으로 보안 파이프라인 구축에 대한 이 문서를 읽으십시오. (Java 및 Maven을 사용하지만 Node.js 및 npm으로 대체할 수 있습니다.)

버전 관리 및 게시 자동화

메인 브랜치에서 변경 사항을 병합할 때마다 npm 패키지 버전을 수동으로 업데이트하고 매번 게시하는 것 대신 이 프로세스를 자동화하기를 원할 것입니다. 이 게시물 앞부분의 간단한 npm 패키지 예제를 기억한다면 다음 명령어를 사용하여 npm 패키지의 버전을 업데이트한 다음 게시했습니다.

npm version <major|minor|patch>
npm publish

또한 패키지 소비자가 레지스트리에 게시하는 다양한 버전 변경 사항에 어떤 의미가 있는지 이해할 수 있도록 시맨틱 버전 관리의 업계 표준을 따르기를 원합니다.

시맨틱 버전 관리란 무엇인가요?

시맨틱 버전 관리는 버전에 3개의 자리 표시자로 번호가 매겨지도록 규정합니다. 첫 번째는 주 버전, 두 번째는 부 버전, 마지막은 패치 버전입니다. 시맨틱 버전 관리, 버전 관리 및 lock 파일에 대해 자세히 알아보려면 Package Lock JSON 이란 무엇이며 Lock 파일이 Yarn 및 NPM 패키지에서 작동하는 방식을 읽어보세요.

이 모든 작업을 수동으로 건너뛰는 대신 npm 패키지 게시를 처리하는 깃허브 액션으로 자동화된 워크플로를 설정할 수 있다면 어떨까요? 운이 좋게도 깃허브 액션과 통합되는 시맨틱 릴리스(Semantic Release)라는 도구가 있기 때문에 할 수 있습니다. 이 프로세스를 자동화하는 데 도움이 되는 핵심은 프로젝트에 변경 사항을 커밋하는 동안 컨벤셔널 커밋(conventional commits)이라고 하는 것을 사용하는 것입니다. 이를 통해 자동화는 그에 따라 모든 것을 업데이트하고 프로젝트의 다음 릴리스를 준비하는 방법을 알 수 있습니다.

아래의 단계에서는 최신 npm 패키지에 대해 이를 설정하는 과정을 안내합니다.

  1. 터미널에서 npm i -D semantic-release 명령어를 실행합니다.

  2. 터미널에서 npx semantic-release-cli setup 명령어를 실행합니다.

  3. 터미널 프롬프트에 따라 필요한 토큰을 제공합니다.

  • 깃허브의 개인 액세스 토큰이 필요합니다. 생성하기 위해 해당 리퍼지토리 세부 정보로 변경해서 https://github.com/<your-name-or-github-organization>/<your-repo-name>/settings/secrets/actions/new로 이동하세요.
  • 이 토큰을 생성하는 동안 다음 범위를 사용하세요.
    new token image
  1. 또한 계정의 2FA를 해결할 수 있도록 CI 환경에서만 사용할 npm의 자동화 타입(Automation-type) 액세스 토큰이 필요합니다. 생성하기 위해 https://www.npmjs.com/settings/<your-npm-account>/tokens로 이동하세요. CI/CD 워크플로에서 사용되므로 "자동화" 유형을 선택해야 합니다.

    new access token image

    bc@mbp-snyk modern-npm-package % npx semantic-release-cli setup
    ? What is your npm registry? https://registry.npmjs.org/
    ? What is vour nom username? clarkio
    ? What is your pm password? [hidden]
    ? What is your NPM two-factor authentication code? <2FA code>
    Provide a GitHub Personal Access Token (create a token at https://github.com/settings/tokens/new?scopes=repo
    <token>
    ? What CI are you using? Github Actions
    bc@mbp-snyk modern-npm-package %
  2. https://github.com/<your-name-or-organization/<your-repository>/settings/secrets/actions/new에서 npm 토큰을 깃허브 리퍼지토리에 리퍼지토리 암호로 추가하세요. 이전 단계에서 검색한 값을 사용하여 암호의 이름을 NPM_TOKEN으로 설정합니다.

  3. 프로젝트로 돌아가서 package.json 파일로 이동하여 아래와 같이 릴리스 키를 추가하세요. 리퍼지토리의 기본 브랜치가 여전히 master이고 main이 아닌 경우 위의 branches를 적절하게 수정하세요.

    "release": {
        "branches": ["main"]
      }
  4. 아래와 같이 package.json 파일에 publishConfig 키도 추가하세요.

    "publishConfig": {
        "access": "public"
     }
    
  5. semantic-release npm 스크립트를 사용하여 테스트를 실행하여 모든 것을 테스트합니다. 다음 명령어를 실행하고 NPM_TOKEN= 그리고 GH_TOKEN= 값을 각각의 토큰 값을 사용하도록 설정합니다. 그런 다음 터미널에서 전체 명령어를 복사하고 실행하여 모든 것이 올바르게 실행되는지 확인합니다. 터미널의 출력에 기록된 프로세스를 볼 수 있습니다. 문제가 발생하면 여기에 표시되고 문제 해결을 위한 세부 정보를 제공합니다.

  6. 테스트 실행이 성공적으로 완료되었는지 확인한 후 게시 프로세스를 처리할 새 깃허브 액션으로 깃허브 리퍼지토리를 설정할 수 있습니다. 깃허브의 리퍼지토리로 이동하여 "Actions"를 클릭하세요.

  7. 새로운 워크플로 옵션을 클릭합니다.

  8. 워크플로의 이름을 release.yml로 변경합니다.

  9. 새 워크플로 파일에 아래 YAML 스크립트를 추가합니다. 이 스크립트는 기본적으로 Snyk Security Check 작업이 성공적으로 완료되면 릴리스 작업을 실행한다고 말합니다. 릴리스 작업은 코드를 확인하고 Node.js 환경을 설정하고 종속성을 설치한 다음 깃허브 및 npm 토큰을 사용하여 의미론적 릴리스를 실행합니다.

    name: Release
    on:
      workflow_run:
        workflows: ['Snyk Security Check', 'Tests']
        branches: [main]
        types:
          - completed
    jobs:
      release:
        name: Release
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v2
            with:
              fetch-depth: 0
          - name: Setup Node.js
            uses: actions/setup-node@v2
            with:
              node-version: 'lts/*'
          - name: Install dependencies
            run: npm ci
          - name: Release
            env:
              GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
              NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
            run: npx semantic-release
  10. 로컬 변경 사항을 커밋하고 깃허브 리퍼지토리에 푸시 합니다.

  • 터미널에서 git commit -am '<your commit message>' 명령어를 실행한 다음 git push를 실행하면 됩니다.
  • 버전 제어 기능을 통해 VS Code에서 이 작업을 수행할 수도 있습니다.
  1. 모든 설정이 완료되면 컨벤셔널 커밋을 사용하여 변경 사항을 메인 브랜치에 푸시 또는 pull request를 병합할 수 있고 Snyk 보안 검사 이후 릴리스 워크플로가 실행됩니다. modern-npm-package 리퍼지토리 워크플로 예제에서 해당 인스턴스를 볼 수 있습니다.

깃허브를 통한 Snyk로 지속적인 보안 모니터링

코드를 커밋 하는 프로세스에서 직접 보안 검사를 수행하는 것이 좋지만 커밋 사이에 발생하는 취약점을 놓칠 가능성이 있습니다. 예를 들어, 몇 달 동안 리퍼지토리에 코드를 푸시 하지 않았다면 그 당시 발견된 새로운 취약점에 대해 알지 못할 것입니다. 이때, Snyk가 더 많은 도움을 줄 수 있습니다! 깃허브 리퍼지토리를 Snyk에 연결하면 프로젝트에서 코딩하는 빈도에 관계없이 새로운 취약점을 자동으로 모니터링하고 경고합니다. 그 외에도 보안 문제를 해결하기 위해 자동화된 pull request를 제공합니다.

Snyk에는 npm 패키지 코드 및 해당 종속성의 보안을 보장하는 데 특히 유용한 두 가지 제품이 있습니다. Snyk Code는 패키지 코드의 보안을 지원하고 Snyk Open Source는 취약점에 대한 오픈 소스 종속성을 모니터링합니다.

무료 Snyk 계정을 최대한 활용하려면 아래 단계를 따라 하세요.

  1. 무료 Snyk 계정에 로그인

  2. 프로젝트 추가를 선택한 다음 깃허브를 선택합니다.

    add project image

  3. 프로젝트의 저장소를 이름으로 검색하고 옆에 있는 체크박스를 선택합니다.

    select checkbox image

  4. 리퍼지토리를 Snyk로 성공적으로 가져왔는지 확인합니다.

    check repository image

최신 npm 패키지 만들기 시작

이 글에서 배운 모든 내용을 요약해 보겠습니다. 먼저 간단한 npm 패키지를 설정, 생성 및 배포하는 방법을 알게 되었습니다. 이 방식은 처음으로 npm 패키지를 게시하는 데 필요한 사항에 익숙해지는 데에 좋습니다. 하지만 프로덕션 사용을 위해 npm 패키지를 만들려는 경우, 이 방식으로 진행하는 것은 상당히 수동적이고 지속 불가능합니다.

프로덕션 준비 패키지를 만들기 위해 CommonJS(CJS) 및 ECMAScript(ESM) 모듈 형식 모두에 대해 빌드하고, 단위 테스트를 설정 및 작성하고, 보안 검사를 구현하고, 버전 관리 및 게시를 자동화하는 방법을 배웠습니다. 이 지식을 통해 이제 커뮤니티나 회사에서 쉽게 사용할 수 있는 더 많은 npm 패키지를 만들 준비가 되었습니다.

profile
FrontEnd Developer

1개의 댓글

comment-user-thumbnail
2023년 5월 3일

This information is really great ful for me. ForemostPayOnline

답글 달기