First Contribution

  • 캬캬캬컄
  • 첫 번째? 기여
  • npm으로 다운받아지는 모듈에 내가…

tsc 문제

  • 타입스크립트로 프론트 프레임워크 없이 바닐라? 웹 프로젝트를 했다
  • vscode live server로 개발하고 있었다
  • import/export 구문을 사용하고 싶어서 tsconfig에서 module옵션을 commonjs가 아닌 es2020으로 사용했다
  • 그런데 한 가지 문제가 있었다
  • 아래 tsc의 결과로 트랜스파일 된 js들이 있다
main.ts
1
import tmp from './tmp';
main.js
1
2
3
import tmp from './tmp'; // tsc 결과

import tmp from './tmp.js'; // 내 기대값
  • tsc 이후에 확장자가 달리지 않는 문제?가 있었다
  • 이러면 live server는 localhost:5500/js/tmp를 못 찾는다
  • localhost:5500/js/tmp.js 확장자까지 모두 있어야 파일을 찾아 로드할 수 있었다
  • 이거에 대해 구글링을 해보니까
  • .ts 파일에서 작업할 때 .js 확장자를 붙이는 방법이 있었다
1
2
3
4
5
6
7
// src-ts/tmp.ts
const tmp = 'chinsung';
export default tmp;

// src-ts/main.ts
import tmp from './tmp.js';
console.log(tmp);
  • 근데 이건 에디터에서는 잘 알아듣게 할 수 있지만
  • 코드를 봐서도 아름답지 못한 느낌이 팍 들었다
  • 다른 방법으로는 서버에서 파일을 찾을 때
  • 확장자가 생략이 되어도 그에 맞는 파일을 서빙하도록 설정하는 방법이 있었다
  • 먼저 live server에서 라우터나 서빙 관련 뭔가 설정 가능한 게 있는지 살펴봤는데 없었다
  • express 서버를 만들고 해당 기능을 추가하기에는 auto refresh 기능을 포기하고 싶지 않았다

tsc-es2020-fix 발견

tsc-es2020-fix 문제 발견

  • 잘 쓰고 있다가 한 가지 문제점을 발견했다
main.ts
1
2
3
import tmp from './tmp';
// ->
import tmp from './tmp.js';
  • 같은 레벨의 파일 참조는 잘 변환이 되는데
main.ts
1
2
3
import tmp from '../tmp';
// ->
import tmp from '../tmp'; // 확장자가 붙지 않는다..!
  • 상위 디렉터리를 거치는 경우에 기대한 대로 동작하지 않았다
  • node_modules에서 tsc-es2020-fix를 이리저리 둘러보다가
  • 변환이 이뤄지는 로직을 찾았다
fix.js
1
2
3
4
5
contents.replace(
/(\sfrom |\simport\()(["'])(\.\/[^"']+)(["'])/g,
(matched, control, q1, from, q2) =>
`${control}${q1}${resolveDependency(filename, from, filenames)}${q2}`
);
  • 정규식으로 import / export 구문을 찾고 확장자를 붙여주는 것이었다
  • 나는 여기서 정규식을 수정하면 될 것 같았다

  • 간단하게 위 경우도 찾을 수 있게 수정했다
fix.js
1
2
3
4
5
contents.replace(
/(\sfrom |\simport\()(["'])(\.{0,2}\/{0,1}[^"']+)(["'])/g,
(matched, control, q1, from, q2) =>
`${control}${q1}${resolveDependency(filename, from, filenames)}${q2}`
);
  • 그러자 내가 기대하는 대로 동작하기 시작했다
  • 이때 너무 기분이 좋아서 원본 레포에 가서 fork하고 자신감 넘치게 PR를 했다

첫 기여

  • PR을 보내고 얼마 지나지 않아 답변이 왔다
  • 테스트를 추가해 달라였는데, 나는 엄청 당황했다 ㅋㅋㅋ
  • 테스트 케이스인 파일을 추가하고 jest -u를 돌려달라는데
  • jest부터 몰라서 jest 공부도 하고..
  • 프로젝트 구조도 잘 모르는데, 어찌어찌 내가 생각하는 대로 파일 추가하고 테스트 한 다음에
  • 내 PR을 적용하기 전과 후 결과를 스샷 찍어서 답글을 달았다

  • 괜찮아 보인다며 내 PR이 병합됐다!!
  • 내 변경사항으로 모듈이 업데이트되고, 뭔가 기분이 좋았다

후기

  • 처음 모르는 레포에 가서 PR을 했다
  • PR하고 피드백받고, 테스트 코드 추가하면서 엄청 떨렸다
  • 그러면서 기여를 어떻게 해야하는지 찾아보고
  • https://github.com/sindresorhus/.github/blob/main/contributing.md
  • 엄청난 오픈소스 개발자 깃허브도 찾고,,
  • 기여를 어떻게 해야 하는지에 대한 문서에
  • fork 한 다음에 master 브랜치 작업하고 PR를 보내지 마라라는 항목이 있어서 부끄러워졌다..

참고

aws lambda에서 git쓰기

arn:aws:lambda:us-east-1:553035198032:layer:git-lambda2:8

상황

  • 람다에서 git 명령을 사용하고 싶다

레이어 추가

1
2
3
4
5
6
7
8
9
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs14.x
Layers:
- 'arn:aws:lambda:us-east-1:553035198032:layer:git-lambda2:8' # 여기를 추가!!
  • sam template.yaml에서는 위와 같이 추가한다
  • 또는 aws console로 직접 해당 람다에 가서 추가해 줄 수 있다

람다에서 깃 쓸 때 고려사항

  • 람다에서는 가급적 가벼운 일을 해야 한다
  • git clone 한다면 /tmp 디렉터리에서 한다 (clone 옵션을 살펴서 최대한 필요한 것만 가져오자)
  • 인증은 Personal access tokens을 사용했다
    • 토큰이 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 이렇게 있을 때,
    • https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@github.com/{레포 오너}/{레포 명}.git
    • 이렇게 사용할 수 있다

참고

git submodule 중첩된 깃 사용하기

  • 깃 아래 깃..!

상황

1
2
3
4
5
super
├── client
│ └── 1
└── server
└── 1
  • 이런 구조의 프로젝트가 있다
  • super에서 git init 하여 프로젝트를 관리하다 보면
  • 깃 히스토리가 client 내용, server 내용이 합쳐져 있다
  • 구분하기 위해 커밋 메시지를 적을 때도 어떻게 적어야 할지 망설이게 된다
  • 그래서 super, client, server에 모두 git init하고
  • super에서는 client와 server를 gitignore에 추가하고 사용해봤는데,
  • 이것도 좋은 방법은 아닌 것 같았다
  • 그래서 nested git repository 라는 키워드로 검색했고 submodule 이라는 것을 사용하면 된다는 것을 알게 되었다
  • submodule을 사용하면 super 디렉터리에서 명령어 하나로 하위의 서브모듈 깃 프로젝트를 업데이트(pull) 할 수 있다

공부

  • 생활코딩님의 강의를 보고 공부했다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 전제조건
// 명령어를 실행하는 위치는 super 디렉터리이다
// submodule로 추가할 프로젝트(client, server)는 모두 git init으로 초기화된 깃 프로젝트이며 원격 저장소에 올라가 있어야 한다

// submodule 추가 // 처음 super에 서브모듈을 추가하는 과정이다
git submodule add {repo url} 디렉터리명

// 이후 다른 컴퓨터에서 super를 클론하는 경우
git clone {super-repo-url} // git clone https://github.com/chinsun9/super.git

// 하위 서브 모듈은 클론되지 않는다
// 서브 모듈도 가져오기
git submodule init
git submodule update

// 위 명령은 하위 모든 서브 모듈을 가져온다
// 특정 서브 모듈만 가져오고 싶다면
git submodule init {submodule명}
  • super에서는 하위 서브모듈의 변경을 감지하고,
  • 하위 모듈의 해시(특정 버전을 가리키는)를 기억하는 방식으로 관리된다
  • git submodule update 명령을 사용하여 super에서 저장하고 있는 특정 버전의 하위 모듈로 업데이트한다
  • git submodule update --remote 명령을 사용하여 각 하위 모듈을 최신 상태로 업데이트할 수 있다
  • 여러 컴퓨터에서 작업할 때 super를 클론하고 git pull && git submodule update 명령으로 한 번에 가져올 수 있겠다!

발생한 문제

1
2
3
4
5
6
git submodule update --remote

fatal: Needed a single revision
Unable to find current https://github.com/chinsun9/my-submodule/master revision in submodule path 'lib'
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
  • git submodule update --remote 명령을 실행하니 이런 에러가 발생했다
  • 나는 submodule을 알기 전에 그냥 하위에 또 다른 깃 디렉터리를 사용하고 있었는데,
  • 그 상태 그대로 submodule add하고 사용했더니 위 에러가 발생했다
  • 해결방법은 기존 하위 레포를 삭제하고 다시 git submodule update --remote를 실행한다
1
2
rm -rf lib/
git submodule update --remote
  • 혹시 특정 브랜치에 대해 가져오고 싶으면 .gitmodules 파일을 열고 branch 값을 명시해준다
1
2
3
4
5
6
7
8
9
10
// 수정 전
[submodule "client"]
path = client
url = https://github.com/chinsun9/my-submodule

// 수정 후
[submodule "client"]
path = client
branch = mybranchname // 추가됨!
url = https://github.com/chinsun9/my-submodule

참고

비공개로 작업하던 레포 공개로 전환하기 위해 스크릿 파일 삭제하기

상황

  • 리액트 스터디가 끝났다..!
  • 스터디하면서 github에 비공개 레포로 진행했었는데
  • 스터디를 끝내면서 공개로 전환하기로 했다
  • 하지만 공개로 전환하기 전에 aws를 사용하면서 저장해둔 rds 접속 정보 등 시크릿 파일을 제거해야 한다
  • 히스토리에서도 완전히 삭제하는 것을 목표로 한다

시도1 ; git filter-branch

1
git filter-branch --index-filter 'git rm --cached --ignore-unmatch utils\rdsSecret.ts' HEAD
  • 명령을 실행하니까 filter-repo를 사용하라고 했다

시도2 ; git filter-repo

  • 나는 윈도우를 쓰고 있는데, 윈도우에서 인스톨할 때 주의사항이 있었다
  • scoop을 통해 설치하면 문제없다 하여 scoop을 설치한다

scoop 설치 및 filter-repo 설치

  • https://scoop.sh/
  • scoop은 윈도우용 커맨드 라인 인스톨러라고 한다
  • 설치를 위해 파워쉘을 관리자 권한으로 실행하고 다음을 실행한다
1
2
3
4
5
6
# scoop 설치
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')

# filter-repo 설치
scoop install git-filter-repo

filter-repo로 git history 속 민감한 정보 삭제하기

1
2
3
4
5
git filter-repo --invert-paths --path utils/rdsSecret.ts
//...
git filter-repo --invert-paths --path secret1
git filter-repo --invert-paths --path secret2
git filter-repo --invert-paths --path secret3
  • README.md에 민감한 정보가 있는 경우, 기존 내용을 복사했다가
  • 명령어로 히스토리에서 제거하고,
  • 다시 파일을 생성하고 민감한 정보를 없애고 새로 커밋을 해주었다
  • 이 작업을 진행하면 리모트 주소가 삭제되는데,
  • git remote add {레포 주소} 한다

주의사항

  • 작업을 진행하기 전에 백업 레포를 하나 생성하자
  • --path 경로 작성할 때, \로 작성하면 안 되고 /로 작성해야 한다
  • 제거하고자 하는 파일을 이름을 변경한 적이 있던가,
  • 폴더를 이동했었으면 이전의 내역까지 완전히 사라지지 않는다
  • 그래서 수동으로 하나씩 찾아서 해줘야 한다
  • sourcetree에서 히스토리 검색을 통해서 꼼꼼히 체크하여 삭제를 진행한다

참고

git alias로 명령어 줄이기

1
git config --global alias.rc 'rm -r --cached .'
  • windows의 경우 git bash를 열어서 위 명령을 실핸한다
  • 이미 원격 저장소에 올린 파일을 gitignore 할 때 쓰는 명령어인데
  • 항상 외우지 않고 복붙 했었는데,
  • 그것도 귀찮아서 이참에 git rc로 줄여버렸다

git 명령어 줄이기

1
2
3
git config --global alias.r '! r() { git reset --soft HEAD~"$1" ; } ; r'

git config --global alias.r1 '! r1() { git reset --soft HEAD~1 ; } ; r1'
  • git reset --soft HEAD~1 마지막 커밋 하나를 취소하는 명령어이다
  • 나는 보통 여러 컴퓨터에서 작업할 때, 일단 작업 중을 내용을 임시적으로 커밋 푸쉬해서 깃허브에 업로드한다
  • 다른 컴퓨터에서 풀로 받아오고, 이 임시적인 커밋을 취소할 때 명령어를 길게 쓰는 게 귀찮아서 alias로 짧게 줄여보았다
  • git r 2 ; 숫자만큼 커밋 취소하기
  • git r1 ; 마지막 커밋 취소하기

참고

git commit push 명령 합치기

  • git commit 이랑 git push 명령을 합치고 싶은 욕구가 생겼다
1
git config --global alias.acp '! acp() { git commit -a -m "$1" && git push ; } ; acp'
  • git bash를 열고 위 명령을 수행한다
  • acp란 이름으로 git alias를 추가한다
  • --global옵션을 줘서 어디서든 실행될 수 있도록 한다
  • --global옵션을 주지 않으면 현재 깃 디렉터리에만 적용이 된다
1
git acp "커밋 메시지"
  • 이런 식으로 사용한다

참고

github api로 유명한 레포 첫 커밋 메시지 확인하기

  • 엄청큰 오픈소스 저장소를 보면 커밋 개수가 어마어마하다
  • 첫 커밋을 확인하려고, 브라우저에서 커밋 목록으로 들어가서 한페이지 한페이지씩 넘겨가면서 찾을 수 없을 것이다

  • vscode의 첫번째 커밋은 어떤 커밋일까?

Hello Code

github api로 첫 커밋 확인하기

  • 약간 수동적인 방법이다

https://api.github.com/repos/microsoft/vscode/commits?page=73698&per_page=1

  • 브라우저로 vscode 레포에 접속해서 총 커밋 개수를 확인한다
  • github api 중에 커밋 목록을 보여주는 api가 있다
  • 파라미터로 page에 커밋 개수를, per_page는 1로 설정해주면 첫번째 커밋을 가져올 수 있다
  • 그리고 시간이 지남에 따라 새로운 커밋이 생기고, 커밋 개수가 증가하게 되면서, 나중에 다시 보려면 page 파라미터의 값을 새롭게 설정해줘야 하는 문제가 있다

참고

  • 찾아보니까 스크립트로 여러사람들이 만들어 놓은것을 확인할 수 있었다

shell script

python, js