
이 글은 모던 리액트 Deep Dive를 기반으로 작성되었습니다.
디자이너와 이미지는 뗄 수 없는 관계이다. 아이콘부터 배경, 배너이미지 등 웹사이트를 디자인하는데 많은 이미지들을 사용한다. 실제로 퍼블리싱 외주를 받고 작업을 하다보면, 클라이언트가 쇼핑몰일 경우는 미리 스튜디오에서 찍은 제품 이미지나 디자이너에게는 고화질의 풍경 이미지 등을 전달 받는다.
이런 이미지들은 대게 5~10mb정도의 용량을 차지하고 있으며, 해당 이미지들을 그대로 웹사이트로 가져간다면 아마 사용자의 사이트 이탈률은 100%에 달할 것이다.
실제로 Lighthouse를 실행해보면 퍼포먼스가 보통 이미지로 인해 안좋음을 확인할 수 있다.
따라서, 우리는 작업을 진행할 때 따로 Webp확장자로 변경하여 이미지를 압축하거나 Lazy Loading을 사용하여 최적화를 진행하곤 한다.
하지만, 이미지 양이 많을수록 매번 모든 이미지를 압축할 수 없고 이는 비효율로 이어질 수 있다.
리액트 딥다이브를 공부하며 Git Action인 calibreapp/image-actions를 통해 번거로운 압축작업없이 PR되는 이미지들에게만 압축을 자동화한다면 효율적으로 관리할 수 있지 않을까하는 생각으로 시도해보고자 한다.
더 비효율적이거나 안됨말구~

GitHub Action에 대해 알아보기전에 CI/CD부터 알아보자

CI란 간단하게 어플리케이션의 "빌드/테스트 자동화" 과정이다. 개발자들은 코딩을 이슈별, 기능별 브랜치를 파거나 따로 작업한 후 최종적으로 제일 상단의 마스터 브랜치에 합병을 통해 기능을 통합한다.
이때, 여러 명의 개발자가 동시에 코드 작업을 할 경우에 충돌할 가능성이 있고 이를 방지하기 위해, 자동적으로 빌드 및 테스트되어 통합할 수 있다.
CD란 "배포 자동화" 과정이다. CI를 통해 문제가 없이 통과된다면 자동적으로 배포가 된다.
- 코드 수정
- 각 브랜드치에 코드 push
- git 통합
- 오류 발견 -> 디버깅 -> 반복
- 코드 수정
- 각 브랜드치에 코드 push
- push를 통해 알아서 Build, Test, Lint
- 에러 결과 확인 및 수정 후 git 통합
- CI서버에서 자동 배포
크게 달라진 것이나 필요한가 싶은 생각도 있겠지만, 푸쉬간 컨플릭트나 하나하나 빌드 및 테스트를 해본 개발자라면 CI/CD의 중요성에 대해서 알 것이다.
대표적인 CI/CD 환경 구축을 위해 많이 쓰인 솔루션이지만 문제점이 많았다. 어떤 기능이 있고 어떤 불편함이 있는지는 다루지 않겠다.
그렇다면 Git Action은 무엇인가?
사실 Git Action은 CI/CD를 목적으로 만들어진 것이 아닌, 깃허브 저장소를 기반으로 깃허브에서 발생하는 다양한 이벤트를 트리거 삼아 다양한 작업을 할 수 있게 도와주는 것이다.
이러한 특징은 Git Action을 통해 CI/CD 솔루션을 대체 할 수 있음에 널리 퍼지기 시작했다.
물론 직접 액션을 작성해도 좋지만, 라이브러리와 같이 미리 만들어져있는 액션들을 가져다 쓸 수 있다. 그 중 하나가 이번 글에서 시도하고자하는 calibreapp의 image-actions이다.

초반에 말했듯이 이미지들은 사용자에게 불편함을 주지 않는 선에서 가장 작은 파일로 관리될 필요가 있는데, 이 이미지를 압축해 관리하는 게 여간 귀찮은 일이 아니다. image-actions는 PR로 올라온 이미지를 sharp 패키지를 통해 거의 무손실로 압축하여 커밋해준다.
다음과 같이 프로젝트 파일 안에 꼭 .github/workflows/calibreapp-image-actions.yml이라는 파일을 생성해준다.
Project/
│
├── .github/
│ └── workflows/
│ └── calibreapp-image-actions.yml
├── public/
├── src/
├── .DS_Store
├── .gitignore
├── README.md
├── db.json
├── package-lock.json
└── package.json
그 뒤 아래와 같은 코드를 입력한다.
// calibreapp-image-actions.yml
name: Compress images
on: pull_request
jobs:
build:
name: calibreapp/image-actions
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@master
- name: Compress Images
uses: calibreapp/image-actions@master
with:
githubToken: ${{ secrets.GITHUB_TOKEN }}
on : pull_reqest
PR이 발생하면 액션을 실행시킨다. 만약 push를 입력하면 push시에 acition이 일어난다.
githubToken: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN을 만들고 .env 등에 등록해놔야할 것 같지만, 아무것도 할 것 없다. 자동적으로 레포 생성 시 토큰이 발행된다고 한다.
이후 아무 이름으로 브랜치를 생성한다.
여기서 "아무 이름"이라고 해서 절대 아무 이름으로는 하지말자..
다음과 같이 브랜치 이름에 #을 붙혔다가 2시간동안 작동이 안되어서 고생했다.
로그를 살펴보니 아래와 같은 오류가 떴고, 설마 브랜치를 못찾아서 그런것 같길래 찾아보니.. 브랜치 네이밍시에 #을 넣으면 주석처리로 이해한다고 한다...
HttpError: Reference does not exist
이후에 이미지를 추가한 후에 PR을 날리면 자동으로 압축이 진행된다. 압축을 진행하면 액션봇이 얼마나 줄여졌는지 친절하게 알려준다.

HttpError: Resource not accessible by integration 에러

다양하게 시도해본 결과 압축할 필요가 없는 이미지에 대해서는 압축을 진행하지 않는다. 만약 모든 이미지를 압축하기를 원하거나, 이미지만 압축을 원한다면 yml파일에서 수정하면 된다. 어떻게 수정해야하는지는 공식문서에 잘 나와있다.
실제 이미지가 12.8MB임에도 불구하고 압축없이 해당 이미지를 그대로 홈페이지에 불러왔다. 이후 PR을 날렸을 뿐인데 알아서 1.4MB까지 압축해서 업로드되었다.


기존의 방식이였으면 ILoveIMG같은 곳에서 압축을 진행하고 업로드를 진행했을텐데 정말 편했다. 중간과정이 사라져 버리고 자동화가 되었으니
생각보다 많이 해메이긴했는데 Action 자체에 대한 어려움은 아니라, 되게 쉽다고 볼 수 있을 것 같다. 앞으로는 action을 통해서 이미지를 압축하는 방법을 택할 것 같다.

image-action.. 좋네요