개발/Chrome Extension 개발기

크롬 익스텐션 개발일지: GPTBottomCopyButton

걍판자 2024. 2. 13. 18:06
반응형

완성된 모습!

크롬 익스텐션 스토어에 신청한 대시보드 모습

기획단계

개발하려고 하는 것

  • chat gpt가 코드를 짜줄 때 copy code 버튼이 아래에도 생기도록 하는 크롬 익스텐션

개발하고자 하는 이유

  •  코드를 생성할 때 위에서부터 아래로 코드를 읽고 이해한 후에 복사해야 하는데, 코드가 길 경우 스크롤을 내려야만 코드 하단에 있는 복사 버튼을 눌러야 하는 불편함이 있다. 이 익스텐션은 이런 불편함을 해소하기 위해 코드 하단에도 복사 버튼을 추가한다.
  • 사실 대부분의 언어는 그렇게 까지 코드가 길지 않다. 그래서 필요성을 잘 느끼지 못했었다. 그런데 flutter은 dart라는 언어로 괄호로 둘러싼 위젯기반 언어여서, 코드 줄 수가 많다. gpt로 flutter로 앱 개발을 하는데 별거 아닌 코드들도 엄청 길어져서 필요성을 느끼게 되었다.

아이디어를 참고할 수 있는 것

  • 크롬 익스텐션 스토어에 비슷한 기능을 하는 다른 프로그램이 있나 찾으려 했으나 찾지 못했다. 그래서 다른 것 참고하지 않고 만들려고 했다.

생산성을 위해 알아두면 좋은것

  • 크롬 익스텐션 간의 상호 작동 원리
  • 개발자 도구를 이용한 디버깅 및 확인 방법

사용언어와 그 이유

  • 자바스크립트: 크롬 익스텐션을 만드려고 하는데, 크롬 익스텐션이 자바스크립트 기반으로 작동해서

사전지식수준

  • 웹 스크래퍼를 엑셀로 불러오는 것을 만들었던 적이 있다. html 코드를 자바스크립트로 불러오는 걸 해봤다.
  • 자바스크립트 테트리스를 만들어 html, css, js 간의 통신에 대해 알고 있다.

예상 MVP 모델 및 아키텍처 구성

구상한 아키텍쳐
구상한 아키텍쳐

개발단계

개발 기간

  • 2024.02.05~2024.02.10

개발 일지

날짜 해낸 것 해결할 것
02.05 크롬 익스텐션에서 일단 해당 코드를 콘솔창에 실행했을때 나오게는 했다. modifyHTML()함수 개발 완료 콘솔창에 코드 삽입 안됨, copy code 버튼 너무 큼, 콘솔창 외 에서의 실행, copy code 우측 정렬, copy code 버튼과 글자사이의 간격, 복사가 때로는 안됨
02.06 popup창 틀 만듬 popup창 다른 파일들과 상호작용 제대로 안되는 문제 해결할 것
02.07 익스텐션에 대한 이해 완료 해서, 팝업창에 따라 하단의 code copy 버튼 생성 및 삭제 기능 구현 완료 copy 버튼이 팝업창을 여러번 누르면 여러개 생긴다. 그리고 현재 활성화 여부가 저장이 안된다. 만약 현재 활성화 되어있다면 실시간으로 생성하는 코드에도 copy 버튼 생성하게 할것
02.08 이미 copy button이 있다면 버튼을 눌러도 중복으로 생기지 않도록 했다. 또한 현재 activate 상태인지 deactive 상태인지 저장하고 팝업창에 반영하였다. activate 상태라면 실시간으로 code 밑에 copy button붙일것
02.09 실시간 반영여부에 따른 copy 버튼 생성, 그 과정에서 생긴 copy button 여러개 생기는 문제 flag 세워도 안되어서 강제로 지워주는 방식으로 해결
- 탭들 간 통신 리팩토링
- copy button 색깔 및 위치 맞추기
- mutation의 추적 대상 줄이기
- response 없앰으로써 그냥 계속 뜨는 Unchecked runtime.lastError: The message port closed before a response was received 에러 해결
- ui디자인 radio에서 버튼식으로 변경
- 권한 최소화 및 background 파일 삭제
- 크롬 익스텐션 파일 부분 완성
- icon 결정 및 편집 완료
popup창 디자인 변경할 것
02.10 팝업창 디자인 변경, 불필요한 권한 삭제  

기획에서 발견된 문제점과 개선방안

popup창의 radio 버튼이 현재 상태를 나타내주어야 하나, 간혹 현재 상태와 다른 곳에 checked 되어 있다.

  • 개발할 때 popup창의 radio 버튼이 사전에 checked 되어 있는 곳이 현재 activate 되어있는지 deactive 되어있는지 여부를 나타내는 일종의 토글 UI처럼 작동하기를 바랐다. 그래서 활성화 여부를 background.js에 저장하고 이를 popup창을 열떄마다 popup.js에서 불러와 현재 상태를 checked로 표시하길 바랬다. 그리고 실제로 이 부분을 구현하는데 많은 시간을 쏟았다. 하지만 기획 자체의 근본적인 문제가 있었다. 크롬 익스텐션에서 background.js 파일은 오랫동안 대기상태로 둘 때 자체적으로 종료된다는 것이다!! 즉 창을 열어두고 5분 정도가 지나면 background.js의 파일에 저장해 둔 현재상태에 대한 변수는 리셋된다.
  • 그래서 현재 상태를 나타내는 radio 버튼을 일반 버튼 2개(활성화시키기, 비활성화시키기)로 바꾸었다.
  • background.js의 역할은 활성화, 비활성화 변수를 주는 역할이었는데 이젠 아무런 쓸모가 없게 되었다. 그래서 파일 자체를 마지막에 삭제했다. 원래는 background.js 에 뭐가 많았는데.. 사실 없어도 되는 파일이었다니 아쉬웠다.

개발 중 발생한 문제점과 개선방안

popup.html에서 CSP 오류 발생

  • 크롬 익스텐션에서는 html안에 직접 스크립트를 입력하는 inline스크립트를 막는다. 그래서 모든 코드를 popup.js로 넘겨서 처리했다.

하단에 새롭게 만든 code copy버튼이 원래 있던 copy 버튼과 디자인이 달라 위화감이 든다.

  • html에서 원래 상단의 code copy 버튼은 중간의 code와는 별도의 div로 되어 있었다. 그런데 내가 새로 만든 하단의 code copy 버튼은 중간의 code 와 같은 /div 안에 있어 생겨난 문제였다. 즉, 중단의 code의 css를 적용받았던 것이다. 그래서 별도의 태그로 분리해 주었다.
  • 그 외에도 code copy 버튼의 정렬, 글자크기, 아이콘 등이 기존 버튼의 html 버튼을 그대로 복사했음에도 달랐다. 따라서 기존 html에서 여러 클래스 중 디자인적으로 불필요한 class와 필요한 class를 구분하여 필요한 것만 적용하였다. 아이콘 같은 경우 불러올 수 있는 것은 아이콘을 쓰고, check표시의 경우 비슷한 모양의 아이콘을 사용했다.

code copy 버튼이 활성화 버튼을 누를 때마다 중복으로 생긴다.

  • modifyHTML()로 code copy 버튼을 하단에 추가할 때마다 고유 class를 추가하였고, 이후 해당 class가 없는 것들에만 하단에 copy 버튼을 추가하도록 하였다.

활성화 상태에서 실시간으로 만들어지는 코드에 code copy 버튼이 중복으로 생긴다.

  • 코드를 수정해 주는 modifyHTML() 함수가 실행 중 또 호출스택에 올라가 중복으로 실행되어 발생하는 문제라고 생각했다. 그래서 전역변수를 flag 변수로 사용해보기도 하고, setTimeout() 함수로 시간을 조정해보기도 했다. 하지만 그래도 해결되지 않아서 일단 중복으로 code copy 버튼이 생길 때 지워주는 코드를 넣어주었다. 효율적인 해결책은 아니었다. 그런데 이런 문제가 왜 생기는지는 아직까지도 모르겠다. 지금은 네트워크 상태에 따라 생기는 문제 같다고 추측하고 있다.

개발 외에 해야 할 일들

  • 크롬 익스텐션 개발자 등록하기: 해외 결제가 가능한 카드로 5달러를 지불해야 한다. 개발자 계정을 등록하는 데 있어서 한국이 없어서 다른 나라로 등록했다.

이후 단계

완성된 화면 구성(캡처)

  • 다음과 같은 팝업창이 나와 활성화, 비활성화 버튼을 누를 수 있다.

퍼즐 모양 버튼을 눌렀을때 나오는 팝업창
퍼즐 모양 버튼을 눌렀을때 나오는 팝업창

활성화 버튼을 누르면 다음 상태에서

비활성화 상태의 모습
비활성화 상태의 모습

다음과 같이 변한다

활성화 상태의 모습
활성화 상태의 모습


하단에 copy code 버튼이 생겼음을 알 수 있다.

코드 복사 버튼을 눌렀을때 모습
코드 복사 버튼을 눌렀을때 모습


새로 생긴 copy code 버튼을 누르면 버튼이 바뀌는 피드백이 있으며 제대로 복사되어어 잘 작동한다.

아키텍처 구성(그림)

  • background.js를 빼자 불필요한 통신도 줄고 아키텍처도 간단해졌다.

실제 개발한 아키텍쳐
실제 개발한 아키텍쳐

개제된 사이트

크롬 확장 프로그램 링크

https://chromewebstore.google.com/detail/gptbottomcopybutton/onepocigimnaipfleflfbfoiekjgojoh?hl=ko&authuser=0

 

깃허브 링크

https://github.com/SKKUKang/gpt-code-copy-button-below

 

GitHub - SKKUKang/gpt-code-copy-button-below: Added a Code Copy button below the code in ChatGPT.

Added a Code Copy button below the code in ChatGPT. - SKKUKang/gpt-code-copy-button-below

github.com

 

 

개발과정에서 배운 것

  • 원래 웹에서 개발자도구를 통한 디버깅이 익숙하지 않았다. 개발자도구로 볼 수 없는 내부파일의 로그나 변수가 왜 안 나오지? 하기도 했다. 이젠 개발자도구를 통한 웹 디버깅이 익숙해졌다. 단순히 로그만 보는 게 아니라 개발자도구의 콘솔창에 함수 자체를 입력하여 제대로 작동하고 있는지 확인할 수 있었다.
  • 크롬 익스텐션에서 뜨는 에러코드가 새로고침 하면 과거의 에러 알림은 사라지고 현재의 에러 알림으로 바뀌는 줄 알았다. 아니었다. 기존 에러를 지워주어야 현재 발생한 오류가 무엇인지 정확히 알 수 있었다.
  • 깃 사용방법에 대해 좀 더 알게 되었다. 원래 깃은 단순히 협업툴이 아닌가? 하면서 프로젝트를 할 때 잘 사용하지 않았는데, vscode에서 깃을 스테이징 하고 커밋하는 게 수정하고 되돌리는 게 훨씬 편하다는 것을 깨달았다.
  • 크롬 익스텐션의 상호 통신 구조에 대해 배웠다. 크롬 익스텐션을 처음으로 만들어보는 것이라 어떤 방식으로 아키텍처가 작동하는지 몰랐다. 개발과정에서 파일들 간 message를 보내고 받는 방식으로 통신하는 걸 알게 되었다. 이를 잘 몰라 처음에는 변수를 export 해야 되나 싶었고, 파일들 간 life cycle도 착각해 혼란을 얻기도 했다. popup.js와 background.js의 생애주기를 오해해서 메시지를 주는 쪽만 있고 받는 쪽은 없다는 에러도 많이 마주했다.
  • 코딩애플의 자바스크립트 자료를 보고 아키텍처에 대해 착각했던 부분이 뚫렸다. 혼자 끙끙되지 말고 그전에 기초지식이 부족한 것은 아닌지 잘 생각해 보자. 지엽적인 부분에서 막히면 전체적인 해당 언어에 대한 자료를 보면서 하자.

완성 후 회고

  • 한번 제출했다가 불필요한 권한 요청으로 반려되었다. 사실 알고 보니 tabs 권한도 필요 없던 것이다. 그래서 권한 삭제 후 다시 제출했다. 권한 요청은 언제나 제대로 확인하고 하자. 가장 보안에 있어 민감한 부분이니까
  • 아키텍처를 이해하고 주어진 아키텍처에 맞게 프로그램을 만들어 게시하는 건 처음해보는 일이었다. 직접 프로그램을 규격에 맞게 짜고, 공식 스토어에 올리는 일이 내가 생각해낸 아이디어를 인정받는 기분이라서 흥분되었다.
  • 아키텍쳐에 대한 이해 없이는 전체적인 프로그램을 구성할 수 없다. 파일들끼리도 어떻게 통신하고 협동하는지 제대로 된 이해가 바탕이 되어야 한다.
  • 프로그램을 만드는데 필요한 지엽적인 지식도 좋지만, 지엽적인 지식만으로는 개발하다 막힐 때가 많다. 더 포괄적이고 기본적인 이해가 있어야 프로그램을 만들어 낼 수 있다.

과도한 권한으로 반려되어 다시 신청하였다
과도한 권한으로 반려되어 다시 신청하였다

 

 

이후 성과에 대해 알고 싶다면...

 

Chrome extension 출시 후 한 달 간의 후기!

크롬 익스텐션을 만들고 배포한 지 한 달이 넘었다. 그동안의 성과 지표에 알아보자. 크롬 익스텐션 개발일지: GPTBottomCopyButton 완성된 모습! 기획단계 개발하려고 하는 것 chat gpt가 코드를 짜줄

juneforpay.tistory.com

 

반응형