[react-native] 보안과 환경변수에 관하여(2) - 개인모듈 만들어 배포해보기

devAnderson·2023년 6월 12일
0

react-native

목록 보기
6/6

🗿 1. 글머리

Env 관리를 위한 사내 개발용 모듈, env-manage를 만들게 된 계기에 대한 여정은 이 글에서 확인할 수 있습니다.

그래서, Infisical과 react-native에서 설명하는 docs의 내용들을 최대한 참조하여 나왔던 결론은

1. env를 관리하는 서버를 둔다
2. 해당 env를 요청해서 로컬에 저장할 수 있는 모듈을 만든다

였었고, 마무리를 짓고 나서 테스트해보니 필요한 목적에 맞는 구현은 어느정도 한 것 같아 뿌듯하다고 생각하고 있다(헿)

사실, 특별히 엄청난 기능이 들어있는 건 아니고 node.js의 기본적인 기능을 다룰 수 있으면 구현 자체는 어렵지 않았는데, 생각보다 터미널을 건들이는 것들이 생소한 개념들이 많아서 많이 헤맸었던 기억을 잊어먹기 전에 좀 정리해보려고 한다.


🗿 2. 에? 모듈배포요?

사실, 평상시에도 모듈을 직접 개발해보는 것에 대한 목표의식이 엄청 있었던 편이었다.
(뭔가 멋있기에)

결정적인 계기는, 코드스테이츠라는 교육 기관에서 공부를 할 때 테스트 통과를 위한 정답을 script에 다 작성을 하면 command를 입력하여 원격으로 "제출" 을 할 수 있었는데
도대체 원리가 무엇인기 극도로 궁금해지기 시작했던 것이 시발점이라 할 수 있겠다.

그래서 테스트 빨리 끝내고 매번 내부 모듈 소스를 뜯어보고 여러가지 방식으로 커스터마이징해보며 가지고 놀아본 기억이 있다.

나에게 있어서 npm이란, 뭔가 "와 내가 너무 개쩌는 코드를 작성한 것 같은데 이것을 나만 쓰는 게 아니라 다른 사람들도 쓰게 만들고 싶어!" 라는 의지가 모여있는 꿈과 희망의 장소이다.

여튼 테스트 제출 프로그램의 내부를 뜯어본 경험은 양분이 되어 이렇게 직접 사내 환경변수 관리 모듈을 만들고자 마음을 먹었을 때 심리적 장벽을 허물어주는 좋은 트리거가 되었다.


각설하고, 생각보다 모듈의 배포는 어렵지 않다.

  1. npm에 가입한다.
  2. "npm init -y" 등의 과정을 통해 pakage.json이 있는 working directory에서 "npm login"을 터미널에 입력하여 로그인을 진행한다.
  3. package.json을 잘 작성한 뒤, "npm publish"를 통해 배포한다.

엥, 이게 다인가요?

놀랍게도, 이게 끝이다.

물론 더 세부적으로 정교하고 안정적으로 배포하는 커스터마이징이 존재하지만, 단순한 모듈을 개발하여 배포하는 일은 위의 세 과정이 전부이다.

제일 중요한 것은 package.json을 잘 작성해야 한다는 점인데, 이것은 이미 잘 정리가 되어있는 블로그가 있으므로, 이를 참조하면 좋다.

참고로 배포 시, gitignore과 같이 npmignore로 업로드하지 않을 파일들을 추가해줄 수 있지만, gitignore가 존재할 경우 해당 내용으로 갈음하는 것을 확인하였다.

pakcage.json에서 해당 WD가 모듈로서 배포되길 원한다면 가장 중요한 property가 바로 "bin" 속성이다.
위에 보이는 bin 옵션이 해당 작업 내용이 모듈로서 작용할 때, 어떤 이름으로 bin에 등록되며 이 이름으로 접근했을 때 어떤 파일을 실행시킬 것인지에 대해서 나타낸다. 아래에 내용을 보면 이 bin옵션을 통해 만들어지는 파일이 어떤지 볼 수 있다.


🗿 3. 그래서, 모듈은 어떻게 만드나요.

모듈을 만들면서 가장 곤란했던 것은 역시 "path"의 설정들이었다.

현재 모듈을 개발하면서 가장 목표로 되는 사항은 아래와 같았다.

어디까지나 사내 개발자들끼리 env를 쉽게 공유하자는 것이 목표였기에, 큰 기능은 넣지 않으려고 하였다.

가장 핵심적인 기능으로는 개발자들이 DB에서 관리되는 env 데이터를 로컬에서 요청 => 응답받은 데이터를 기반으로 .env를 생성하는 것이었다.

그런데 문제는, 첫 시작부터 발생한다. 그것은 바로

"npx로 명령어 입력을 하면 특정 행동을 하게 만드는 모듈을 만든다"

라는 부분이었다.

정확히 말하면 npx가 동작하는 원리 자체를 모른다는 것이 문제였다.


🗿 4. npx란, 그리고 이로 인한 분기의 시작

"npx create-react-app 어쩌고...." 를 상당히 많이 써왔음에도, 이 원리에 대해서 전혀 모르고 있었다는 것을 반성하며, 다시금 어떤 식으로 동작하는지에 대해 확인해보는 시간을 가졌다.

자세한 설명은 이 글 을 확인하면 좋다.

npxNode Package Executor 의 약자로, Executor(즉 npx의 x) 의 네이밍답게 특정 모듈을 "실행시키는" 것을 목표로 두는 툴이다.

npx의 행동 패턴은 크게 2가지이다.


  • 로컬에 설치되어있지 않는 경우
로컬에 설치되어있지 않다면, npm 저장소에 publish되어있는 모듈을 체크한 후, 해당 모듈이 존재한다면 
이를 ## 1회성으로 ## 설치한 후, 실행시킨 뒤에 삭제한다.

즉, 필요한 모듈을 필요할 때만 설치하여 실행한다는 장점을 가진다.

publish가 되어있는 모듈인지는 간단하게 "npm view env-manage" 를 커맨드에 입력해보면 된다.

위의 이미지에서 볼 수 있듯, npm에 배포가 완료되어있는 모듈은 커맨드 명령어로 그 유무를 확인할 수 있고, 이렇게 배포가 완료되어 있는 모듈은 npx를 이용해서 필요할 때만 설치되어 사용하는 것이 가능하다.

그 이후, package.json의 dependencies에 해당 모듈에 대한 내용을 "기입"만 해두는 것으로, npx 명령어를 이용해서 1회성 사용이 가능해진다.

위에서 보이는 것처럼, env-manage의 위치를 찾아보면 존재하지 않는다고 하지만
npx를 통해 명령어를 실행해보면 해당 script가 실행되는 것을 확인할 수 있다.


  • 로컬에 설치되어있을 경우

사실, 정확하게 말하자면 npx의 행동 패턴은 우선적으로 로컬에 설치되어 있는 상황을 우선시되는 것으로 확인된다.

npx로 특정 스크립트를 실행하려고 하면, 현재 working directory를 시점으로 올라가 bin 혹은 .bin 폴더를 찾은 후 내에서 커맨드와 일치하는 이름의 파일을 찾아 실행시킨다.

global하게 설치했을 때도 동일하다. 로컬에서 찾지 못했다면, 상위 루트로 타고 올라가며 bin 폴더를 찾은 후, 거기에 존재하는 같은 이름의 스크립트를 실행시킨다.

이렇게 타고올라가다가 더 이상 타겟을 찾지 못하게 되면, npm 원격 저장소에 publish되어있는 대상을 찾아 실행시키고, 배포조차 되어있지 않다면 command 실행을 실패한다.

참고로, 매번 개발을 할 때마다 배포를 해서 테스트를 할 수는 없는 노릇이다. 그래서, 내가 만든 모듈을 임시적으로 global하게 설정할 수 있는 방법이 있다. 그것은 바로 "npm link"를 이용하는 방식이다.

위의 이미지처럼, 해당 모듈 폴더에서 link를 걸으면 global하게 해당 모듈을 설치하는 것을 알 수 있다. ( 참고로, 모듈이 배포된 상태에서 npm link 모듈이름 <--- 방식으로 링크를 걸 경우, 배포된 모듈이 글로벌하게 링크되므로 로컬테스트가 목적이면 그냥 npm link만 하도록 하자.)

해당 모듈이 글로벌하게 link되었으므로, 다른 프로젝트 폴더에서는 해당 모듈을 글로벌하게 bin에 접근할 수 있기에 npx 커맨드가 사용이 가능하다.

link를 했을 경우, 로컬 모듈에서 수정된 내용은 바로 즉각적으로 global bin에 있는 내용에 반영되기 때문에, 다른 레파지토리에서 사용해보면 즉각적으로 수정된 사항을 확인할 수 있다.


🗿 5. process란

node.js 환경에 글로벌하게 정의되어 있는 process 내에는 상당히 다양한 내용들이 담겨있다.... 만은 이번 모듈을 만들 때에 딱 필요했던 것은 argv에 관한 것이었다.

위 내용은 cli.js 내부에 정의되어 있는 코드 한줄이다.

cli.js가 node.js에 의해 실행될 때, 터미널에 입력했던 내용들은 저렇게 배열로 담겨서 오게 되는데,

해당 배열의 첫번째는 Node의 위치, 두번째는 해당 모듈의 위치를 나타낸다.

그 이후부터는 "npx 모듈이름 ..." 이후부터의 명렁어 리스트가 배열로 담겨오게 되므로, 위와 같이 slice(2)를 한 내용을 destruction하여 재할당하는 방식으로 깔끔하게 사용이 가능한 것이다.

그 외에도, process 내에는 사용자 입력을 관리하는 인스턴스인 process.stdin과, 입력값의 출력을 관리하는 process.stdout이 존재한다.

위 이미지는 화살표로 선택지 이동을 구현하기 위해서 사용했던 on 이벤트 리스너이다. 위에 보는 것처럼 입력과 관련하여 여러가지 메소드들이 존재하는 것을 알 수 있다.

예를 들어, 터미널은 기본적으로 line모드(터미널 입력 한 줄이 끝나고 엔터를 치면 줄 입력이 완성되는 것으로 간주하는 모드) 이지만,

setRawmode(ture)를 호출하게 되면 원시모드(터미널에서 입력하는 하나 하나를 입력의 끝으로 받아들이고 완성된 것으로 간주하는 모드) 로 전환할 수 있다.

위 옵션은 화살표라는 특수키 입력 하나가 이미 입력의 완료이기 때문에, rawMode를 설정하지 않으면 계속해서 화살표 키 입력에 대한 내용이 들어가게 되므로 설정한 옵션이다.

이런 다양한 터미널 기능들을 통해서 내가 원하는 대로 입력을 컨트롤하고, 이에 해당하는 이벤트를 발생시키는 방향으로 모듈을 구현할 수 있었다.


🗿 6. 맺음글

생각보다 단순한 기능이었음에도 불구하고, 정말 많은 시행착오를 하게 되면서 많은 개념들을 배우고 내 자신을 탄탄하게 다지게 되는 기회가 되었다.

더불어, 이렇게 만들어진 모듈을 통해 개발 팀원들의 환경변수 관리에 대한 고통이 많이 덜어지게 되었다는 사실에 몹시 뿌듯함을 느낀다.

아직 멀었지만, 더 정교하고 예쁘고 안정적인 코드를 작성할 수 있는 좋은 개발자 앤더손씨가 될 수 있도록 더 정진해야겠다.

profile
자라나라 프론트엔드 개발새싹!

0개의 댓글