오늘 한 일

  • 현재 회사의 웹과 앱에 적용된 기능의 범위에 약간 차이가 있어서, 오늘은 그 차이의 간극을 메우는 작업을 했다. 앱에는 이미 있는 기능이지만 웹에서는 아직 구현하지 않은, 예를 들면 댓글 관련 기능 같은 것들을 붙여 보았다.
  • 앱에서 돌아가게 하느라 api는 이미 완성되어 있는 상황이라 나는 말 그대로 거기에 맞춰 구현하기만 하면 되는 거였다. (+ 디자인)
  • 기획안과 디자인에 따르면, 댓글을 작성할 수 있는 페이지에 처음 진입하면 댓글 입력란만 보이고 등록 버튼은 보이지 않는데 입력란을 클릭해서 커서를 띄우는 순간 한쪽에 등록 버튼이 생긴다. 다시 외부 요소를 클릭해 커서를 없애면 등록 버튼도 없어져 원래의 레이아웃으로 돌아간다.

오늘 배운 것

  • 해당 input 태그에 포커스가 맞춰져 있을 때 실행하는 함수는 onfocus 이벤트로 넣어준다. html이나 자바스크립트에서는 onfocus로 쓰지만, 리액트에서는 camel case로 onFocus라고 쓴다.
 

onfocus Event

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

  • onblur는 워낙 자주 썼는데도, onfocus의 반대의 경우를 생각하려고 하니 오히려 생각이 잘 안 났다. 그러다 위 링크 Definition and Usage 부분 3번째 줄에 적혀 있는 걸 보고서야 아차 싶었다. onfocus의 반대의 경우, 그러니까 포커스를 잃었을 때의 이벤트는 onblur로 넣는다. 리액트에서는 역시 onBlur.
The onfocus event is the opposite of the onblur event.
  • input 태그에 들어가는 커서를 cursor라고 하는 게 맞는지, CSS에서 쓰는 것처럼 caret이라고 하는 게 맞는지 확인해보려다 찾은 내용이다. caret-color는 그 커서의 색깔을 지정하는 CSS 속성인데, 아래 링크에 따르면 'insertion caret 또는 text input cursor라고도 하는 것의 색깔...'이라고 되어 있다.
 

caret-color - CSS: Cascading Style Sheets | MDN

The caret-color CSS property sets the color of the insertion caret, the visible marker where the next character typed will be inserted. This is sometimes referred to as the text input cursor. The caret appears in elements such as <input> or those with the

developer.mozilla.org

 

오늘 한 일

  • 2022년 새해가 밝았으니 새로운 마음으로 TIL을 적어본다. 느낌상 내일부터 또 다시 업무가 바빠질 것만 같지만, 일단은 그렇지 않을 것처럼 쓰겠다. 희망사항
  • 오늘은 새해 첫 출근이었던 만큼 물론 해야 할 일은 산처럼 쌓여 있지만 급히 작업에 착수하기보다는 지금까지 지난 3개월 간 작업해 둔 코드들을 돌아볼 수 있는 시간을 가졌다. 하지만 실제로 코드들을 처음부터 차근차근 뜯어볼 수 있었던 건 아니었다. 어쩌다 보니 존재조차 몰랐던 오류를 찾아버렸기 때문이었다!
  • 한 가지 기능을 아주 약간 개선해보려다 줄줄이 소세지마냥 이어지는 오류들 때문에 시간을 잡아먹었다. 아직 개선된 버전을 배포하지는 않았으므로 순식간에 배포해버릴 깡도 없고.. 완전히 처리한 건 아니지만 잠시나마 꼬리에 꼬리를 물고 나타나던 여러 오류들을 잡아놔서 마음이 조금은 편해졌다.

오늘 배운 것

  • 오늘은 가지고 있는 링크들 중 가벼운 걸로 풀어보겠다. 항상 이렇게 시작하곤 했지만 기분 탓이라고 하고 싶다. flex-wrap 속성은 display: flex 속성을 가진 부모 요소 안에 자식 요소들이 나열되어 있을 때 넓이와 상관없이 한 줄에 모두 보여줄 것인지, 나열된 자식 요소들의 총 넓이가 부모의 넓이를 초과할 때 초과한 자식 요소들을 다음 줄로 넘겨서 보여줄 것인지를 결정한다.
  • nowrap이면 한 줄에 모두 보여주고, wrap이면 다음 줄로 넘기고, wrap-reverse면 다음 줄로 넘기되 순서를 거꾸로 뒤집는 것이다.
 

flex-wrap - CSS: Cascading Style Sheets | MDN

The flex-wrap CSS property sets whether flex items are forced onto one line or can wrap onto multiple lines. If wrapping is allowed, it sets the direction that lines are stacked.

developer.mozilla.org

  • 정석은 물론 MDN 버전이겠지만, 한글로 된 설명은 이 블로그를 참고하면 좋을 것 같다.
 

CSS flex > flex-wrap 속성

flex-wrap 속성은 나열 된 (정렬 된) 요소들의 총 넓이가 부모 넓이 보다 클 때, 이 요소들을 다음 줄에 이...

blog.naver.com

오늘까지 한 일

  • 점점 TIL 쓰는 간격이 길어진다..ㅠㅠ연말 업데이트를 앞두고 퇴근 시간이 점점 늦어지는 와중에 체력이 받쳐주지 못하는 관계로 TIL 쓰는 걸 자꾸 미루다 보니 이렇게 되기에 이르렀다. 일하면서 찾아놓은 귀중한 링크들만 쌓여가고 풀지를 못하고 있다.. 그러니까 저질체력을 벗어나게 운동을 하자
  • 12월 업데이트를 제때 하기 위해 매일같이 야근을 하면서, 최근에는 기본 시스템 팝업창을 쓰지 않기 위한 커스텀 모달창을 제작했다. 모달을 띄워야 하는 페이지라면 어디에서든지 사용해야 하는 컴포넌트가 되므로, 그때그때 다른 속성들을 넘기기 위해 이런저런 props를 미리 정의해보았다. 그러는 과정에서 다른 모달 제작 사례들을 찾아봤고, props의 타입을 체크하는 방법을 리액트 공식문서를 통해 알게 되었다...! 공식문서 절대 놓지 말자
  • props의 타입을 미리 정해놓고 유효성 검사를 할 수 있게 되는데, 그렇게 하면 모달 컴포넌트에 props를 넘길 때 마치 외부 패키지를 갖다 쓰는 것처럼 vscode에서 알아서 미리 정의된 타입을 알려주는 툴팁을 띄운다. 와 뭐야 감동

오늘 그때 배운 것

  • 역시 공식문서! 두 번 보고 세 번 봅시다ㅠㅠ
 

Typechecking With PropTypes – React

A JavaScript library for building user interfaces

reactjs.org

  • 원리는 공식문서를 참고하되 이제는 내장함수가 아닌 패키지로 옮겨졌다고 하니 npm 링크도 함께 첨부합니다.
 

prop-types

Runtime type checking for React props and similar objects.

www.npmjs.com

오늘까지 한 일

  • 일단 우여곡절 끝에 1차 배포를 한 후, 열흘쯤 전에 회사에 보다 더 가까운 곳으로 이사를 했다. 이사 후 뒷정리는 해도 해도 끝이 없어서 본의 아니게 이사 후 일주일은 아주 칼퇴를 해버렸다.
  • 그러고 나서 주말에 좀 쉴까 했더니 우리집 고양이(라고 쓰고 읽을 땐 주인님)가 이사 후유증 때문인지 병을 얻으셔서 신경 쓰느라 주말도 순삭. 아니 다시 월요일이잖아!?
  • TIL 쓰는 건 고사하고, 일하면서 찾아낸 고귀한 링크들을 북마크만 해놓고 제대로 읽어보지도 못했다. 간단한 것이더라도 하나하나 차근차근 다시 풀어갈 생각이다.
  • 회사에서는 2차 배포를 준비하고 있다. 사실 지난 주에도 쉬어가는 느낌으로 중간 배포를 한번 했어야 했는데 어쩌다 보니 작업이 계속 완결되지가 않아서 흐지부지 되고 말았다. 이번주는 좀 더 치열하게 해보자, 하고 시작했는데 그것도 참 마음대로 되지 않는다. 시도 때도 없이 맞닥뜨리게 되는 이 에러들을 능숙하게 핸들링할 그날이 언젠가는 올까..?

오늘 이전에 배운 것

  • 오늘은 기억에 남아 있으면서 간단한 것부터 적겠다. 방법이야 정하기 나름이겠지만 클릭 같은 이벤트를 발생시키면 특정 텍스트를 클립보드에 복사하는 코드가 필요한 적이 있었다. 정확히 말하자면 내가 복사할 데이터는 브라우저 주소창에 들어가 있는 현재 페이지의 URL이었다. 페이지에 실제로 보여주지는 않을 가짜 input을 만들고 거기에 복사할 데이터를 넣은 다음, 그 데이터를 선택해서 복사한 후 만들었던 가짜 input은 바로 없애버리는 식으로 작동시키는 방법이다. 이 코드를 실행하고 나면 어디에 붙여넣기를 해도 내가 코드로 복사한 텍스트가 나온다.
 

Copy current URL to clipboard – JavaScript

Not sure why this has been so difficult for me today, but for some reason I cannot seem to get it to copy the current URL to the clipboard. Overall, I’m looking for a way to do it without needing to create some hidden text elements. This is what I’m tr

javascript.tutorialink.com

  • 근데 이걸 vscode에 입력하고 나면 자꾸만 경고창이 뜬다. Document.execCommand()가 존재하지 않는다고 했었나, 아무튼 쓸 수 없다는 것이다. 그래도 일단 작동은 하는데, MDN에 따르면 이미 적용되지 않는 브라우저가 있다고 한다. MDN의 Browser compatibility를 참고하면 클립보드로 복사하는 데 사용하는 copy command 정도는 아직 브라우저 상관없이 지원된다. 하지만 어쨌든 deprecated라는 것... 조만간 사용할 수 없게 되지 않을까 싶다.
 

Document.execCommand() - Web APIs | MDN

When an HTML document has been switched to designMode, its document object exposes an execCommand method to run commands that manipulate the current editable region, such as form inputs or contentEditable elements.

developer.mozilla.org

  • 그리고 MDN에서도 설명하듯이, execCommand 대신 Clipboard API를 사용하라고 한다. 아래 링크에서는 자바스크립트에서 제공하는 Clipboard API를 이용하는 방법을 설명한다. 하지만 이건 또 새롭게 등장한 방법이므로 역시 지원되지 않는 브라우저가 있고, 구버전은 당연히 지원하지 않는다. 현재로서는 execCommand와 Clipboard API를 병용하는 게 나을 것 같다.
 

Copy Text to Clipboard in JavaScript

In this article, we will introduce how to copy text to the clipboard in JavaScript.

www.delftstack.com

오늘 한 일

  • 아직도 오픈 못했다...dev 환경 배포 후 stage 환경 배포까지는 마쳤지만 production 배포를 못했다ㅠㅠ 이번 주 초반까지만 해도 별 어려움 없이 진행되지 않을까 싶었는데 꼬리에 꼬리를 무는 온갖 오류 덕분에 금요일까지 밀려버리고 말았다.
  • 각 환경마다 연결되어 있는 서버도 달라서 환경별로 서버 url도 달라지고, 실서비스에서는 보여주지 않아야 할 부분이나 작동하지 않아야 할 함수 같은 것들을 각각 분기할 필요가 있다.
  • 건드리는 게 금기시 된다고 아무도 얘기한 적 없는데 나만 그렇게 생각한 프로젝트 내 package.json 파일을 직접 건드려서 스크립트 명령어를 고치면 손쉽게 환경변수를 분기할 수 있다. 물론 환경변수만 분기했다고 끝나는 건 아니고, 그것이 각각 다르게 작동해야 할 파일들에는 직접 조건문을 사용하든지 해서 적용을 해줘야 한다.
  • 프로젝트 내부 어느 위치에서든지 process.env.NODE_ENV를 찍어보면 development나 production이 나오는데, 이건 디폴트가 development이고 내가 어떤 환경으로 의도했건 빌드 후 배포를 하면 production이 되는 것 같다.
  • 하지만 기능 테스트를 하기 위해 개발서버에 배포하고 싶을 수도 있고, production 직전에 동일한 환경을 만들어 최종 테스트를 하기 위해 개발환경도, 운영환경도 아닌 그 중간 어디쯤의 테스트 환경으로 배포하고 싶을 수도 있다. 하지만 배포하면 process.env.NODE_ENV는 production이 된다.
  • 환경을 내 마음대로 분기하기 위해서는 package.json에 'env': 'process.env.REACT_APP_<CUSTOM>=<SOMETHING> react-script start' 같은 형식으로 스크립트 명령어를 적어두고, 키보드가 닳을 정도로 입력하던 yarn start 대신 내가 만든 명령어를 넣어서 yarn env를 입력하면 REACT_APP_<CUSTOM>이 <SOMETHING> 모드로 실행된다. App.jsx에 현재 실행되고 있는 환경을 확인할 수 있는 로그를 찍는 함수를 넣어놓으면 좋다.
  • 아냐 이것보다 더 중요한 건 오늘 항해 4기분들 멘토링(내가 뭐라고 멘토링을...ㅠㅠ)이 있었다는 것이다! 배포 프로세스 밟다가 삐걱거려서 30분이나 지각한 데다 말주변도 없어서 이 말 저 말 다 주워 섬기는 내가 너무 민망할 정도로 많은 분들이 계셨다. 근데 그 분들이 리액트 거의 전체 인원이라는 게 함정...
  • 아무튼 내가 오늘 한 말들이 얼마나 실제로 도움이 되어 드릴 수 있는지는 모르겠지만 예전의 내 모습을 보는 것 같아 한편으로는 짠하고 한편으로는 기특(?)했다. 코딩에 한창 재미 느껴가며 스스로의 부족함도 깨달아가며 채찍질도 하고 모든 시간을 공부에 투자할 수 있다는 게 얼마나 좋았는지. 당시에는 잘 될 거다, 하면 된다, 어렵지 않다 같은 말들 코웃음 치며 한 귀로 듣고 한 귀로 흘렸는데 지금 생각해보면 그게 다 맞는 말이라는 것도 신기하다. 꼭 4기 분들도 나와 같은 기분을 느낄 수 있었으면 좋겠다. 아니 근데 벌써 4기라니 내 시간 다 어디 갔어

오늘 배운 것

  • 환경변수 분기에 대해 자세히 설명한 링크. 다만 나는 이 분이 사용하신 모듈 없이 package.json 명령어만 수정했다. 그걸로도 충분하다고 생각한다. 아직은
 

CRA 환경에서 배포 시 .env 분기하기 (feat. env-cmd)

배포환경이 dev 서버와 실서버가 구분되어 있을 때, 사용 하는 환경변수들을 다르게 설정해야 되는 경우가 있다.예를 들어 Api url 이 prodution 서버는 example.co.kr 이고, dev 서버는 dev.example.co.kr 일 수

velog.io

  • 이건 위 링크에 비하면 기본적인 내용이고 5년 전 게시글이지만 중요하다고 생각해서 가져왔다. package.json에 명령어 추가하고 사용하는 방법에 대한 짧은 스택오버플로우의 질답이다.
 

How do I add a custom script to my package.json file that runs a javascript file?

I want to be able to execute the command script1 in a project directory that will run node script1.js. script1.js is a file in the same directory. The command needs to be specific to the project

stackoverflow.com

오늘 한 일

  • 우와 저는 이 함수를 찾기 전까지는 페이지 내의 특정 요소로의 스무스한 스크롤은 모듈을 통해서만 되는 줄 알았답니다!? 어제처럼 역시 우연한 기회에 찾은 자료 덕에 새 세상을 보았습니다. 역시 무한 구글링을 하자
  • element.scrollIntoView({behavior: 'smooth'}) 하나면 해결된다. 감동적이다.
  • 한 가지 단점이 있다면 너무나 간결한 나머지 여기에 대한 구구절절한 내용을 쓸 수가 없다는 것?ㅋㅋ너무 좋아
  • 브라우저마다 smooth 옵션이 안 먹힌다거나 하는 차이점이 조금씩 있는 것 같지만 그건 적당히 알아서들 하시고 아무튼 이걸 찾아낸 것이 요 근래 가장 속 시원한 일이다.

오늘 배운 것

  • 어쩌면 이렇게 각 스크롤 관련 함수들을 기깔나게 정리했을까. 예시도 적절하다. npm에 들어가면 모듈을 깔라고 하는 것 같은데, 워낙 오래 전에 올라온 거기도 하고 일단 MDN에도 있고 모듈 건드리지 않아도 기본적으로 작동하는 걸 보니 그냥 쓸 수 있는 듯하다.
 

Smooth Scroll behavior polyfill

The Scroll Behavior specification has been introduced as an extension of the Window interface to allow for the developer to opt in to native smooth scrolling. Check the repository on GitHub or download the polyfill as an npm module.

iamdustan.com

  • 아직은 거의 모든 브라우저에서 작동하는 것 같다.
 

Element.scrollIntoView() - Web APIs | MDN

The Element interface's scrollIntoView() method scrolls the element's parent container such that the element on which scrollIntoView() is called is visible to the user.

developer.mozilla.org

오늘 한 일

  • 평소 '모듈 갖다 쓰는 건 꼭 필요할 때만 하자' 주의인데 react-youtube는 못 참지.
  • 유튜브 영상 url는 그냥 video 태그에 못 넣고 iframe 태그를 써야 한다고 해서, 직접 iframe 태그에 CSS 먹이고 유튜브 API 문서 찾아보며 안 그래도 최근에 좀 알게 된 이벤트 리스너 붙여보고 근데 왜 함수 콜을 못하니! 몇 시간을 아주 끙끙 앓았다. 그러다 우연한 구글링 기회에 react-youtube라는 모듈을 알게 되었다. 써보고 별로면 지우자, 하며 설치했는데 아주 특별한 기능이 있는 건 아니지만 내가 일일이 코딩해야 하는 번거로움을 줄여주는 고마운 친구였다. 하지만 여전히 CSS 적용이 좀 구려
  • 이 모듈이 유튜브에서 제공하는 API를 갖다 쓰는 과정을 조금 더 짧게 줄여주는 역할을 한다는 같은 맥락에서, 결국은 유튜브 공식 문서를 참고해가며 사용해야 한다. 나는 공식 문서와 react-youtube 리드미와 얕게나마 공부한 타입스크립트를 활용해서 모듈의 index 파일을 뜯어가며 살펴보았다. 내가 원하는 기능을 붙이는 건 문제가 없었다.
  • 딱 한 가지 걸리는 건 CSS였다. react-youtube가 제공하는 YouTube 태그도 결과적으로는 iframe 태그인데, CSS를 커스텀하게 적용하는 게 까다로웠다. opts라는 옵션값으로 height나 width는 줄 수 있게 해놨는데 딱 그뿐이다. 나는 min-width를 쓰고 싶었다. YouTube를 새로운 div로 감싸고 그 div에 스타일 속성을 줘봐도 뭔가 애매하고 부족했다. 삽질 끝에 택한 방법은, YouTube를 감싼 div를 styled-component로 정의하고 일단 그 div의 하위 구조를 크롬 개발자 도구로 파악한 뒤, 직접 CSS를 적용해야 하는 iframe이나 하위 요소들에 대한 CSS 코드를 div 안에 네스팅했다. 내가 바라던 것이 실제로 구현됐을 때의 즐거움이란! :)

오늘 배운 것

  • 유튜브 영상에는 video 말고 iframe을 쓰거라 하시는 스택오버플로우.
 

HTML video tag display Youtube video

I got some youtube urls, such as https://www.youtube.com/embed/LaXGkW_-Nvc?list=RDTDDDvaoGiDg. When I put it to html video tag, it said "Invalid source". How to solve this problem? When I used if...

stackoverflow.com

  • 음... 그건 알겠는데 iframe이 뭐죠? 할 때 볼 만한 자료. 다른 웹페이지를 임베드할 때 쓴다.
 

HTML iframe tag

W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.

www.w3schools.com

  • npm의 react-youtube 페이지. 리드미가 좀 더 길고 친절했다면 어땠을까 싶다가도 결국 유튜브 문서로 회귀하려나 싶기도 하다.
 

react-youtube

React.js powered YouTube player component

www.npmjs.com

  • 유튜브의 iframe player API 문서. 모듈을 쓰더라도 함수나 이벤트 같은 것들은 아무래도 이쪽을 많이 보게 된다.
 

iframe 삽입에 대한 YouTube Player API 참조 문서  |  YouTube IFrame Player API

Embed a YouTube player in your application.

developers.google.com

오늘 한 일

  • 딱 이 날이다, 하고 정해진 건 없지만 초읽기 중인 웹 1차 오픈을 앞두고 마무리 작업이 한창이다.
  • 유튜브 스트리밍 영상이 시작하기 10분 전부터 메인 페이지에 해당 영상을 띄우는데, 그러려면 영상 시작 시간과 현재 시간을 비교해서 얼마큼의 차이가 있는지를 확인해야 한다. 백 서버에서 보내주신 시작 시간을 받아보니 5분 뒤인 오후 1시경인데, 나는 같은 포맷으로 현재 시간을 찍어보니 자꾸만 그리니치 평균시(나는 이걸 '영국시간'이라고 하는 게 입에 붙어버렸다...)가 나왔다. 그러니 결과적으로 비교하고자 하는 시간 자체에 9시간의 차이가 있는 것이었다.
  • 나는 아무 생각 없이, 내가 맞춰야 된다는 생각으로 내가 찍은 시간에다 9시간을 더했다. 그렇게 하면 당연히 넘겨받은 시작 시간과 시간대가 일치하는 것 같이 보이므로 계산하기가 수월했다.
  • 하지만 이사님이 제기하신, 여기서 문제: 그렇다면 만약 내가 한국에서 접속하지 않았다면? 하와이에서 접속했다면? 나는 한국이 아닌 다른 곳에 있는데도 불구하고, 내가 아니라 '한국'이 영국과 시차가 9시간 난다는 이유만으로 9시간을 더해서 계산하게 되는 것이다. 당연하게도 '한국'이 아니라 사용자인 '나'의 시간이 우선되어야 한다.
  • 그러므로 다른 것들도 마찬가지고 서버와 클라이언트가 통신할 때에는 착오가 없도록 반드시 그리니치 평균시를 기준으로 시간을 주고받아야 한다. 각 브라우저는 이걸 그리니치 평균시로 받더라도 알아서 현지의 시간대에 맞춰 보기 좋게 보여준다. 그러니 보여지는 시간과 실제 그것이 의미하는 시간의 차이를 아는 것이 중요하다. 오늘 오후 1시로 보여진다고 해서 실제로 그것이 그리니치 평균시로 오늘 오후 1시를 의미하는 것이 아니기 때문이다.

오늘 배운 것

 

그리니치 평균시 - 위키백과, 우리 모두의 백과사전

 

ko.wikipedia.org

  • 보다 널리 쓰이는 건 GMT보다는 UTC(협정 세계시)라고 한다. 근데 사실 개발하다 보면 둘 다 보게 되는 것 같다.
 

협정 세계시 - 위키백과, 우리 모두의 백과사전

협정 세계시 위키백과, 우리 모두의 백과사전.

ko.wikipedia.org

 

+ Recent posts