일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- custom printing
- rolldown
- augmentedDevice
- npm package
- camera access
- silent printing
- vercel git lfs
- Failed to compiled
- dvh
- Recoil
- html
- animation
- Each child in a list should have a unique "key" prop.
- ffi-napi
- react-native
- github 100mb
- Git
- github lfs
- react-native-dotenv
- nextjs
- github pdf
- 이미지 데이터 타입
- 티스토리 성능
- electron-packager
- ELECTRON
- adb connect
- device in use
- camera permission
- adb pair
- Can't resolve
- Today
- Total
Bleeding edge
⛏️백준 애드온 리액트 리팩토링 리뷰 본문
리팩토링 기간
2022.10.31 - 2022.11.13
리팩토링을 시작하게 된 계기
얼마 전에 완성한 플로팅 브라우저와 백준의 폴더구조를 비교하였다. 플로팅 브라우저는 기능 별로 파일을 분리하였지만, 백준의 폴더구조는 main.js 단 한개의 파일로 자바스크립트를 가지고 있기 때문에 파일을 수정하기 힘들었다. 그래서 깃허브에서 스타가 많은 크롬 익스텐션을 검색하여 파일을 어떻게 관리하는지 검색하였다.
크롬 익스텐션의 파일 관리
다른 크롬 익스텐션에서는 필요한 manifest.json, styles.css, main.js가 root 폴더에 있는 것이 아니라 src를 기준으로 웹팩 번들링을 하였다. 그리고 필요한 파일을 컴포넌트 별로 분리하여 관리하였다.
리팩토링 목표 및 계획
- 리액트를 이용하여 컴포넌트 단위로 분리하여 개발
- 웹팩을 이용하여 번들링을 하고, 배포 폴더와 개발 폴더를 구분
- 파일에 필요한 툴체인은 직접 구현
문제점 그리고 해결책
툴체인
CRA(Create React App)는 내가 사용하지 않는 기능도 사용하기 때문에 모듈이 무겁기 때문에 직접 툴체인을 구현하기로 하였다.
- 웹팩 추가
필요한 로더를 추가하기 이전에 로더에 필요한 것들이 무엇이 있는지 고민하였다. 백준 애드온 같은 경우에는 이미지를 사용하지 않기 때문에 svgr나 이미지 minify에 관련된 것들은 필요 없었다.
- scripts
지난번 처럼 main.js로 파일을 관리하지 않고 webpack을 이용하기 때문에 웹팩을 저장할 때마다 실행을 해야 결과를 볼 수 있었다. 처음에 한두번 npm start를 치다가, package.json script에 —watch 옵션을 새로 추가하였다.
- ts-loader
타입 스크립트를 처음에 사용할 수도 있어서 ts-loader를 사용했다. 결국 ts를 사용하지 않았고, 웹팩을 실행할 때마다 시간이 많이 소모된 것을 보니, esbuild를 이용하는 것이 맞다고 생각했다.
monaco editor
툴체인을 만든 후에 코드를 위치에 맞개 배치를 했더니 다음과 같은 에러 메시지가 등장했다.
메러 에세지 만으로는 무슨 에러인지 알 수 없었기 때문에 검색을 통하여 무슨 에러인지 파악하였다. 이 에러는 monaco editor가 처음에 monaco editor를 생성할 때 worker을 설정할 수 없을 때 생기는 에러였다. 이 에러를 파악하는데 오래걸렸던 이유는 warning 메시지를 무시했다고 생각한다. 평소에 에러메시지만 필터해서 읽고 있었는데, 이 에러메시지를 검색하고 이리저리 console 창을 보면서 느꼈다
- monaco editor가 worker을 생성하는 방법
- window.MonacoEnvironment의 getWorker 혹은 getWorkerURL을 이용하여 생성한다.
일반적인 웹을 만드는 경우에는 상당히 간단하다. 바로 본인의 경로에 파일 위치를 설정하면 된다. 문제는 지금 만들고 있는 백준 에드온 같은 경우에는 본인의 파일이 아니기 때문에 get error가 발생한다.
- chrome.runtime.getURL
chrome.extension으 경로에 직접 접속하여 파일에 접촉하였더니, 다음과 같은 에러가 발생했다.
다음 에러를 보고 나서 Worker에 대한 파일을 읽어보았다. Worker라는 개념이 monaco editor에서만 사용하는 개념이라 생각하고 좌절하고 있었는데, Worker에 대해 검색해보니 Worker는 web API였다.
(참고 :https://developer.mozilla.org/ko/docs/Web/API/Worker)
Worker에 대한 간단한 글을 읽어보고, Worker는 주어진 URL 스크립트를 읽고 Worker를 생성한다는 것을 알게되었고, 이에 맞는 해결책을 검색하였다.
cross origin worker
나만 겪은 문제가 아니었는지, npm 에도 관련된 모듈을 찾을 수 있었다. https://www.npmjs.com/package/cross-domain-worker-url 하지만, 라이브러리는 최소한으로 사용하고 싶었기 때문에 worker의 url을 외부로 돌리는 다른 방법이 있나 고민하였다.
getWorkerUrl: function (workerId, label) {
return `data:text/javascript;charset=utf-8,${encodeURIComponent(`
self.MonacoEnvironment = {
baseUrl: '<https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.21.2/min/>'
};
importScripts('<https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.21.2/min/vs/base/worker/workerMain.js>');`)}`;
},
worker 에 대한 것을 검색하다 보니 importScripts에 대해 알게되었다. importScripts는 worker의 scope를 확장시키는 기능이 있었고, 이를 이용하여 monaco editor에 있는 worker에 대한 초기 설정을 해결하였다.
iframe 최소화 하는 방법
이전에 고민했었던 postMessage를 이용하여 파일을 구성하면 iframe을 최소화 시킬 수 있다는 생각이 들었다.
iframe으로 이벤트를 전송하여 코드를 실행하는 것은 다음과 같이 진행된다
- CodeRunner에서 iframe으로 code를 보낸다.
- code를 보내기 이전에 Message.jsx에서 input과 output 값을 붙인다.
- iframe에서 message를 받는다
- text를 input output에 맞게 실행한다
- iframe에서 console.log를 text로 저장한다
- iframe에서 CodeResult로 Message를 보낸다
- CodeResult에서 결과를 출력한다
처음에는 iframe도 component화 시켜서 진행을 하려고 했지만, iframe.contentWindow와 window.parent 같은 경우 VirtualDom에서 이용할 수 있기 때문에 직접 iframe을 append하고 export하여 Message를 주고 받도록 만들었다.
폴더관리
처음에 모든 컴포넌트를 components에 넣고 관리를 하다보니, depth가 다른 컴포넌트가 같은 폴더에 위치해서 파일 경로를 보는 것이 불편하였다.
컴포넌트를 디테일하게 분류하기 위하여 파일을 컴포넌트 구성대로 그래프를 그렸다. (그래프를 그리면서 컴포넌트에 맞게 이름을 변경도 하였다). TestCase의 Input과 Output 같은 경우에는 컴포넌트의 내용이 많지 않고 반복되었기 때문에 coupound components로 구성하였다. (화살표가 있는 것은 다음 depth에 존재하는 component 화살표가 없는 것은 같은 파일 내에 존재한다) 백준 애드온은 컴포넌트의 갯수나 depth가 깊지 않았기 때문에 그래프에 그려진 구성대로 components 폴더를 구성하기로 하였다.
폴더를 개선한 이후에 파일 관리가 훨씬 쉬워졌다.
개발 후기
이전에 만들었던 리액트 프로젝트 같은 경우 CRA를 이용하여 만들었고 다른 사이드 프로젝트 같은 경우에도 툴 체인을 이용하여 만들었기 때문에 툴체인의 중요성에 대해 잘모르고 있었다. 툴체인을 공부하고 적용을 하다보니 프로젝트의 work flow를 부드럽게 개선할 수 있었다. 그리고 웹팩, 바벨, 배포 폴더 관리에 대해서 이건 왜 사용해야할까? 에 대한 궁금증에 대해서도 풀 수 있어서 좋았다. 단지 생각보다 웹팩의 로더 설정을 잘 못해서 웹팩에 시간을 많이썼다. 리팩토링을 하면서 전보다 파일 정리나, 코드를 사용하는 것이 조금 더 나아진 것 같아서 좋았다.
'Side Project' 카테고리의 다른 글
Notion prettier 개발기 (2) | 2023.01.16 |
---|---|
BOJ-ADDON 1.0.7 (0) | 2023.01.15 |
💭Floating Browser 개발기 (0) | 2022.10.30 |
⚡코딩테스트를 준비하는 프론트엔드 개발자를 위한 크롬 익스텐션 개발기 (0) | 2022.10.29 |
이름 미정 - web Ar을 이용한 사이드 프로젝트 (0) | 2022.06.22 |