원문: https://snyk.io/blog/best-practices-create-modern-npm-package/
기술은 항상 변화하고 있고 여러분의 프로세스와 관행은 이러한 변화를 따라잡아야 합니다. npm이 출시된 지 12년이 되었지만, npm 패키지 생성에 대한 당신의 관행은 훨씬 더 현대적이기를 바랍니다. 여러분들의 관행이 약간 구식일 수 있다는 느낌이 든다면 계속 읽어주세요.
이 튜토리얼에서는 최신 모범 사례(2022년 기준)를 사용하여 npm 패키지를 만드는 과정을 단계별로 살펴보겠습니다. 제일 먼저 npm 패키지를 만드는 방법에 대해 배우며 패키지를 빌드하고 npm 레지스트리(registry)에 게시하는 방법에 익숙해질 수 있습니다. 이후 테스트 프레임워크와 지속적인 통합 및 배포 파이프라인, 보안 검사 그리고 릴리스를 위한 자동화된 시맨틱 버전 관리를 설정하여 보다 강력하고 프로덕션에서 바로 사용할 수 있는 npm 패키지를 만드는 것과 관련된 사항을 배우게 됩니다. 이 튜토리얼이 끝나면 현대적이고 지속 가능한 npm 패키지를 생산할 수 있다는 자신감을 갖게 될 것입니다. 시작하겠습니다!
먼저 간단한 예제를 사용하여 npm 패키지를 만들고 게시하는 프로세스에 대해 알아보겠습니다. 이미 이 프로세스에 익숙하다면 더 고급 주제를 다루는 npm 패키지 프로덕션 준비섹션으로 건너뛸 수 있습니다.
시작하기 위해 깃허브 프로젝트가 필요하므로 다음 단계를 따라 프로젝트를 시작하세요. 이미 사용할 프로젝트가 있는 경우, 다음 섹션으로 건너뛸 수 있지만 패키지 이름과 관련하여 이 섹션의 5단계를 다시 확인하세요.
깃허브 리퍼지토리를 생성합니다.
https://github.com/new
리퍼지토리를 로컬로 복제합니다.
예시:
git clone https://github.com/snyk-labs/simple-npm-package.git
터미널을 열고 디렉토리를 복제된 프로젝트의 폴더로 변경합니다.
예시: cd simple-npm-package
npm init -y
를 실행하여 package.json
파일을 생성합니다. 참고: 예제 리퍼지토리를 복제한 경우, 이 단계를 수행할 필요가 없습니다.
package.json
파일의 name
프로퍼티를 범위가 지정된 이름으로 수정해야 합니다.
예시: @snyk-labs/simple-npm-package
. @snyk-labs
대신 사용자명 또는 단체명을 사용하세요.
패키지에 대한 코드를 작성하세요 (또는 index.js의 hello world 예제를 사용하세요).
프로젝트가 생성되면 npm 계정 생성으로 넘어갈 수 있습니다. 이 튜토리얼의 나머지 부분을 통해 리퍼지토리의 로컬 복제본(clarkio/simple-npm-package
)에서 작업하고 있음을 알 수 있습니다.
npm 패키지를 다른 사람이 사용할 수 있도록 하려면 npm 계정이 필요합니다. 다음 단계에서는 아직 계정이 없는 경우, 자신의 계정을 만들고 2단계 인증(2FA)을 활성화하여 계정 보안을 강화하고 계정을 로컬 컴퓨터에 연결하는 과정을 안내합니다.
https://www.npmjs.com/signup에서 npm에 가입하세요.
더 나은 보안을 위해, npm 계정에서 2FA를 활성화하세요.
https://docs.npmjs.com/configuring-two-factor-authentication
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 패키지를 공개된 공식적인 npmjs 리퍼지토리에 게시할 준비가 된 것입니다. 다음 단계는 이를 실행한 이후, 실제 게시 프로세스를 실행하기 전에 게시할 내용을 확인하기 위해 따라야 하는 단계입니다.
터미널에서 npx npm-packlist
명령어를 실행하여 게시된 패키지 버전에 포함될 내용을 확인합니다.
이렇게 하면 패키지가 제대로 작동하기 위해 필요한 소스 코드 파일이 누락되지 않습니다. 또한 데이터베이스 자격 증명 또는 API 키가 있는 로컬 구성 파일과 같은 민감한 정보를 실수로 대중에게 유출하지 않도록 하는 것도 좋은 방법입니다.
> npx npm-packlist
LICENSE
index.js
package.json
README.md
터미널에서 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
터미널에서 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 패키지 빌드 및 배포를 완료했습니다! 다음으로 프로덕션 환경에 사용할 준비가 되어 있고 더 광범위하게 사용할 수 있는 더 강력한 패키지를 만드는 방법을 배우겠습니다.
이전 예제 패키지는 프로덕션에서 잠재적으로 사용될 수 있지만 시간이 지남에 따라 유지 보수를 하기 위해 수동적인 작업이 필요합니다. 적절한 테스트 및 보안 검사와 함께 도구 및 자동화를 사용하면 패키지를 원활하게 실행하기 위한 노력을 최소화하는 데 도움이 됩니다. 그 내용이 무엇인지 자세히 알아보도록 하겠습니다.
아래의 섹션에서는 다음 내용을 다룹니다.
modern-npm-package
프로젝트 설정이 문서를 따라 하는 동안 사용할 자체 프로젝트가 없는 경우, 다음 예제 프로젝트를 참조로 사용할 수 있습니다. 참고: https://github.com/snyk-labs
시작하기 위해 깃허브 프로젝트가 필요하므로 다음 단계에 따라 프로젝트를 시작하세요. 이미 사용할 프로젝트가 있는 경우, 다음 섹션으로 건너뛸 수 있지만 패키지 이름과 관련하여 이 섹션의 5단계를 다시 확인하세요.
깃허브 리퍼지토리를 생성합니다.
https://github.com/new
리퍼지토리를 로컬로 복제합니다.
예시:
git clone https://github.com/snyk-labs/simple-npm-package.git
터미널을 열고 디렉토리를 복제된 프로젝트의 폴더로 변경합니다.
예시: cd modern-npm-package
npm init -y
를 실행하여 package.json
파일을 생성합니다. 참고: 예제 리퍼지토리를 복제한 경우, 이 단계를 수행할 필요가 없습니다.
package.json
파일의 name
프로퍼티를 범위가 지정된 이름으로 수정해야 합니다.
예시: @snyk-labs/simple-npm-package
. @snyk-labs
대신 사용자명 또는 단체명을 사용하세요.
패키지에 대한 코드를 작성하세요 (또는 index.js의 hello world 예제를 사용하세요).
프로젝트가 생성되면 npm 계정 생성으로 넘어갈 수 있습니다. 이 튜토리얼의 나머지 부분을 통해 리퍼지토리의 로컬 복제본(clarkio/modern-npm-package
)에서 작업하고 있음을 알 수 있습니다.
ECMAScript 모듈 형식은 이제 버전 12+부터 Node.js에서 기본적으로 지원되지만 아직 커뮤니티에서 널리 채택되지는 않았습니다. 미래를 대비하고 두 형식을 모두 지원하기 위한 일환으로 타입스크립트를 사용하여 npm 패키지를 준비하는 방법을 살펴보겠습니다.
먼저 파일명이 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"]
}
그런 다음 CommonJS 형식에 대한 타입스크립트 구성 파일을 만들고 파일명을 tsconfig.cjs.json
으로 설정합니다.
lib
프로퍼티는 프로젝트 코드를 작성하는 동안 도움이 되도록 참조해야 하는 유형을 타입스크립트에게 알려줍니다.
target
프로퍼티는 프로젝트 코드를 컴파일할 자바스크립트 버전을 타입스크립트에 나타냅니다.
module
프로퍼티는 프로젝트 코드를 컴파일할 때 사용하는 자바스크립트 모듈 형식을 타입스크립트에 나타냅니다.
moduleResolution
프로퍼티는 타입스크립트가 "import"문을 참조하는 방법을 파악하는 데 도움이 됩니다.
outDir
및 declarationDir
프로퍼티는 코드를 컴파일하고 코드 내에서 사용되는 타입을 정의한 결과를 배치할 위치를 타입스크립트에 나타냅니다.
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"lib": ["ES6", "DOM"],
"target": "ES6",
"module": "CommonJS",
"moduleResolution": "Node",
"outDir": "../lib/cjs",
"declarationDir": "../lib/cjs/types"
}
}
그런 다음 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"
}
}
package.json
파일을 패키지 빌드된 타입스크립트 결과를 담은 lib
폴더를 가리키고 있는 files
필드로 수정하세요.
사용 중인 모듈 로더(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"
}
}
},
패키지의 CJS 버전을 가리키도록 package.json
파일의 main
그리고 types
필드를 수정하세요. 이것은 기본, 대체, 옵션으로 작동합니다.
“types": "./lib/cjs/types/index.d.ts",
"main": "./lib/cjs/index.js",
package.json
파일에 files
필드를 추가하여 npm이 게시를 위해 코드를 패키지화할 때 포함해야 하는 파일을 나타냅니다.
"files": [
"lib/**/*"
],
package.json
의 scripts
필드를 통해 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"
npm run build
명령어를 실행하여 타입스크립트가 프로젝트를 빌드하도록 할 수 있습니다.이것이 CommonJS 및 ECMAScript 모듈 형식을 모두 지원하는 npm 패키지를 빌드하기 위한 타입스크립트의 모든 설정입니다. 다음으로 npm 패키지 코드에 대해 테스트를 설정하고 실행하여 예상한 결과를 생성하는지 확인하는 방법을 배웁니다.
코드의 동작과 결과에 대한 확신을 가지려면 테스트 프로세스를 구현해야 합니다. 테스트는 코드를 처음 생성할 때 일반적이고 행복한 경로를 벗어나 다른 방식으로 코드의 기능에 대해 생각하도록 합니다. 예를 들어 함수를 중단하여 오류를 발생시키거나 의도하지 않은 결과를 생성하는 방법을 생각할 수 있습니다. 이는 애플리케이션을 더 탄력 있고 지속 가능하게 만들 뿐만 아니라 새로운 기능이 추가될 때도 정상 동작을 보장해줍니다.
테스트에 대해 자세히 살펴보고 모범 사례에 대해 배우고 싶다면 Yoni Goldberg의 자바스크립트 모범 사례 리퍼지토리를 읽어보세요.
패키지가 원하는 방식으로 작동하는지 확인하려면 코드에 대한 테스트를 작성해야 합니다. 단위 테스트를 실행하고 결과를 표시하도록 하려면 프로젝트를 설정하는 데 도움이 되는 몇 가지 도구인 Mocha.js, Chai.js 그리고 ts-node가 필요합니다. Mocha.js는 테스트 러너이고 Chai.js는 코드에서 예상한 결과를 얻고 있는지 확인하는 데 도움이 되는 어설션(assertion) 라이브러리이며 ts-node는 타입스크립트 프로젝트에서 이러한 도구를 사용하는 데 도움이 됩니다. 아래 단계에 따라 npm 패키지에 대한 테스트를 설정하고 실행하세요.
터미널에서 다음 명령을 사용하여 개발 종속성(developer dependencies)을 설치합니다.
npm i -D mocha @type/mocha chai @types/chai ts-node
아래의 내용으로 프로젝트의 루트 디렉토리에 .mocharc.json
이라는 파일명의 파일을 생성합니다.
{
"extension": ["ts"],
"spec": "./**/*.spec.ts",
"require": "ts-node/register"
}
프로젝트 루트 디렉토리에 tests
폴더를 생성합니다.
tests
폴더에 index.spec.ts
파일을 생성합니다.
index.spec.ts
파일에 단위 테스트를 작성하여 index.ts
의 코드를 테스트합니다.
참고: 예제 npm 패키지 저장소에서 예시를 참고할 수 있습니다. https://github.com/snyk-labs/modern-npm-package/blob/main/tests/index.spec.ts
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"
},
프로젝트의 루트 폴더에서 터미널의 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)
이제 코드 동작을 검증하는 테스트가 있으므로 파이프라인에서 사용할 수 있습니다. 이것은 리퍼지토리에 도입된 변경 사항이 코드 동작을 손상시키지 않도록 하는 데 도움이 됩니다. 프로젝트 파이프라인의 일부로 테스트 워크플로를 만들려면 다음 단계를 따르세요.
리퍼지토리에 대한 새 깃허브 액션을 생성합니다.
https://github.com/<your-account-or-organization>/<your-repo-name>/actions/new
워크플로의 이름을 tests.yml
로 바꿉니다.
워크플로 파일에 아래의 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 패키지를 다른 프로젝트에 대한 종속성으로 가져와서 사용이 예상대로 원활하게 진행되는지 확인하는 작업이 포함됩니다. 이를 테스트할 수 있는 다섯 가지 방법은 다음과 같습니다.
npm pack
출력을 통해 설치npm link
를 통해 설치이 접근 방식은 npm pack
명령어를 활용하여 npm 패키지를 단일 파일(<package-name>.tgz
)로 패키지화하고 압축합니다. 그런 다음 패키지를 사용하려는 프로젝트로 이동하여 이 파일을 통해 설치할 수 있습니다. 이를 수행하는 단계는 다음과 같습니다.
npm 패키지 디렉토리 내에서 터미널에서 npm pack
명령어를 실행하고 생성하는 .tgz
파일과 그 위치를 기록해 두세요.
디렉토리를 npm 패키지로 사용하려는 프로젝트 디렉토리로 변경합니다.
예시: cd /path/to/project
클라이언트 프로젝트 디렉토리 내에서 npm install /path/to/package.tgz
를 실행하되 1단계의 .tgz 파일 위치에 대한 적절한 경로로 대체합니다.
이후 해당 클라이언트 프로젝트의 패키지를 사용하여 테스트할 수 있습니다.
이렇게 하면 npm 패키지를 사용하여 프로덕션 환경에 가장 가까운 경험을 제공할 수 있습니다.
이 접근 방식은 npm link
명령어를 활용하여 클라이언트 프로젝트에 패키지를 설치하려고 할 때 패키지 디렉토리를 가리킵니다. 이를 수행하는 단계는 다음과 같습니다.
npm 패키지 디렉토리 내 터미널에서 npm link
명령어를 실행
디렉토리를 npm 패키지를 사용하려는 프로젝트 디렉토리로 변경합니다.
예시: cd /path/to/project
클라이언트 프로젝트 디렉토리 내에서 npm link <name-of-your-package>
명령어를 실행합니다.
이렇게 하면 코드에서 사용할 패키지를 참조할 때 클라이언트 프로젝트가 npm 패키지 디렉토리를 가리킵니다. 이것은 패키지 사용에 대한 완전한 프로덕션과 같은 경험을 제공하지 않지만 기능이 예상대로 작동하는지 확인할 수 있습니다.
이 접근 방식은 npm install
명령어에 대한 기존 지식을 활용합니다. link
와 같은 새로운 명령어를 몰라도 npm link
와 비슷합니다.
npm install /path/to/your/package
명령어를 실행합니다.npm link
접근 방식과 유사하게 이를 통해 클라이언트 프로젝트 내에서 패키지 기능을 빠르게 테스트할 수 있지만 완전한 프로덕션과 같은 경험을 제공하지는 못합니다. 이는 npm 레지스트리에서 찾을 수 있는 빌드 된 버전의 패키지가 아니라 전체 패키지 소스 코드 디렉토리를 가리키기 때문입니다.
이 접근 방식은 npm 패키지에 대한 공개(또는 자체) 레지스트리 사용을 활용합니다. 여기에는 다른 npm 패키지에 대해 일반적으로 하는 것처럼 패키지를 게시하고 설치하는 작업이 포함됩니다.
npm publish
명령어를 통해 이 문서의 앞부분에 설명된 단계를 사용하여 npm 패키지를 게시합니다.
디렉토리를 npm 패키지를 사용하려는 프로젝트 디렉토리로 변경합니다.
예시: cd /path/to/project
클라이언트 프로젝트 디렉토리 내에서 npm install <name-of-your-package>
명령어를 실행합니다.
실시간 스트리밍 중 이에 대한 우리의 학습을 요약한 Twitter 스레드를 만든 Mirco Kraenz(@MKraenz)에게 감사의 인사를 전하세요!
이제 최신 모듈 형식을 지원하도록 패키지를 빌드했으며 단위 테스트 및 패키징 테스트를 통해 예상대로 작동하는지 확인했습니다. 다음으로 보안 문제가 없는지 확인하고 npm 패키지에 새로운 문제가 발생하지 않도록 해야 합니다.
자신의 프로젝트에서 보안 취약성을 원하지 않는 것과 마찬가지로 다른 사람의 프로젝트에도 취약성을 도입하고 싶지 않습니다. 다른 많은 프로젝트에서 사용될 것으로 예상되는 npm 패키지를 빌드 하면 보안을 유지해야 하는 책임이 커집니다. 취약점을 모니터링하고 경고하며 지원을 제공하는 데 도움이 되는 보안 검사를 마련해야 합니다. Snyk와 같은 도구를 통해 이러한 요구 사항을 달성하는 데 필요한 작업을 단순화할 수 있습니다.
이 예제 npm 패키지의 경우 깃허브를 소스 제어 관리 도구로 사용하고 있으므로 깃허브 작업 기능을 활용하여 워크플로에 Snyk를 통합합니다. Snyk에는 이 작업을 바로 시작하는 데 도움이 되는 GitHub Actions 참조 프로젝트가 있으며 프로젝트에 사용할 수 있는 다른 프로그래밍 언어 및 도구에 대한 예제를 제공합니다.
Snyk는 무료이므로 가입하고 Snyk API 토큰을 받으세요.
깃허브에서 Snyk API 토큰을 리퍼지토리 암호로 추가하세요.
https://github.com/<your-account-or-organization>/<your-repo-name>/settings/secrets/actions/new
리퍼지토리에 대한 새로운 깃허브 액션을 생성하세요.
https://github.com/<your-account-or-organization>/<your-repo-name>/actions/new
워크플로의 이름을 snyk.yml
로 바꿉니다.
워크플로 파일에 아래의 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 }}
변경 사항을 커밋 합니다.
작업이 성공적으로 실행되었는지 확인합니다.
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 패키지에 대해 이를 설정하는 과정을 안내합니다.
터미널에서 npm i -D semantic-release
명령어를 실행합니다.
터미널에서 npx semantic-release-cli setup
명령어를 실행합니다.
터미널 프롬프트에 따라 필요한 토큰을 제공합니다.
https://github.com/<your-name-or-github-organization>/<your-repo-name>/settings/secrets/actions/new
로 이동하세요.또한 계정의 2FA를 해결할 수 있도록 CI 환경에서만 사용할 npm의 자동화 타입(Automation-type) 액세스 토큰이 필요합니다. 생성하기 위해 https://www.npmjs.com/settings/<your-npm-account>/tokens
로 이동하세요. CI/CD 워크플로에서 사용되므로 "자동화" 유형을 선택해야 합니다.
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 %
https://github.com/<your-name-or-organization/<your-repository>/settings/secrets/actions/new
에서 npm 토큰을 깃허브 리퍼지토리에 리퍼지토리 암호로 추가하세요. 이전 단계에서 검색한 값을 사용하여 암호의 이름을 NPM_TOKEN
으로 설정합니다.
프로젝트로 돌아가서 package.json
파일로 이동하여 아래와 같이 릴리스 키를 추가하세요. 리퍼지토리의 기본 브랜치가 여전히 master
이고 main
이 아닌 경우 위의 branches
를 적절하게 수정하세요.
"release": {
"branches": ["main"]
}
아래와 같이 package.json
파일에 publishConfig
키도 추가하세요.
"publishConfig": {
"access": "public"
}
semantic-release
npm 스크립트를 사용하여 테스트를 실행하여 모든 것을 테스트합니다. 다음 명령어를 실행하고 NPM_TOKEN=
그리고 GH_TOKEN=
값을 각각의 토큰 값을 사용하도록 설정합니다. 그런 다음 터미널에서 전체 명령어를 복사하고 실행하여 모든 것이 올바르게 실행되는지 확인합니다. 터미널의 출력에 기록된 프로세스를 볼 수 있습니다. 문제가 발생하면 여기에 표시되고 문제 해결을 위한 세부 정보를 제공합니다.
테스트 실행이 성공적으로 완료되었는지 확인한 후 게시 프로세스를 처리할 새 깃허브 액션으로 깃허브 리퍼지토리를 설정할 수 있습니다. 깃허브의 리퍼지토리로 이동하여 "Actions"를 클릭하세요.
새로운 워크플로 옵션을 클릭합니다.
워크플로의 이름을 release.yml
로 변경합니다.
새 워크플로 파일에 아래 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
로컬 변경 사항을 커밋하고 깃허브 리퍼지토리에 푸시 합니다.
git commit -am '<your commit message>'
명령어를 실행한 다음 git push
를 실행하면 됩니다.코드를 커밋 하는 프로세스에서 직접 보안 검사를 수행하는 것이 좋지만 커밋 사이에 발생하는 취약점을 놓칠 가능성이 있습니다. 예를 들어, 몇 달 동안 리퍼지토리에 코드를 푸시 하지 않았다면 그 당시 발견된 새로운 취약점에 대해 알지 못할 것입니다. 이때, Snyk가 더 많은 도움을 줄 수 있습니다! 깃허브 리퍼지토리를 Snyk에 연결하면 프로젝트에서 코딩하는 빈도에 관계없이 새로운 취약점을 자동으로 모니터링하고 경고합니다. 그 외에도 보안 문제를 해결하기 위해 자동화된 pull request를 제공합니다.
Snyk에는 npm 패키지 코드 및 해당 종속성의 보안을 보장하는 데 특히 유용한 두 가지 제품이 있습니다. Snyk Code는 패키지 코드의 보안을 지원하고 Snyk Open Source는 취약점에 대한 오픈 소스 종속성을 모니터링합니다.
무료 Snyk 계정을 최대한 활용하려면 아래 단계를 따라 하세요.
프로젝트 추가를 선택한 다음 깃허브를 선택합니다.
프로젝트의 저장소를 이름으로 검색하고 옆에 있는 체크박스를 선택합니다.
리퍼지토리를 Snyk로 성공적으로 가져왔는지 확인합니다.
이 글에서 배운 모든 내용을 요약해 보겠습니다. 먼저 간단한 npm 패키지를 설정, 생성 및 배포하는 방법을 알게 되었습니다. 이 방식은 처음으로 npm 패키지를 게시하는 데 필요한 사항에 익숙해지는 데에 좋습니다. 하지만 프로덕션 사용을 위해 npm 패키지를 만들려는 경우, 이 방식으로 진행하는 것은 상당히 수동적이고 지속 불가능합니다.
프로덕션 준비 패키지를 만들기 위해 CommonJS(CJS) 및 ECMAScript(ESM) 모듈 형식 모두에 대해 빌드하고, 단위 테스트를 설정 및 작성하고, 보안 검사를 구현하고, 버전 관리 및 게시를 자동화하는 방법을 배웠습니다. 이 지식을 통해 이제 커뮤니티나 회사에서 쉽게 사용할 수 있는 더 많은 npm 패키지를 만들 준비가 되었습니다.
This information is really great ful for me. ForemostPayOnline