오늘 한 일

  • 우와 저는 이 함수를 찾기 전까지는 페이지 내의 특정 요소로의 스무스한 스크롤은 모듈을 통해서만 되는 줄 알았답니다!? 어제처럼 역시 우연한 기회에 찾은 자료 덕에 새 세상을 보았습니다. 역시 무한 구글링을 하자
  • 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

 

오늘 한 일

  • 엊그제 만들어놓은 이벤트리스너가 겉보기엔 문제 없이 잘 동작하는데, 영상 몇 개가 재생되고 난 후 콘솔에 찍히는 로그를 보면 기함하게 된다. 동일한 단 하나의 타겟에 붙인 이벤트리스너가 여러 번 실행되면서 콜백함수에 넣어둔 console.log()가 거듭제곱으로 늘어난다. 소오름
  • 영양가 있는 해결책을 찾았지만 사실 근본적인 문제는 내가 짠 코드의 구조에 있었던 것 같다. 처음에는 once: true 옵션 덕에 해결됐다고 생각했으나, 그와 동시에 함수의 전체적인 구조를 바꾸고 나니 해당 옵션을 제거하고도 같은 개선된 결과가 나왔다.
  • 하지만 개선이라고 해봤자 거듭제곱은 아니더라도 영상 재생 1회당 이벤트리스너가 두 번 실행되는 정도.. 물론 거듭제곱보다야 낫다. 이건 좀 더 공부해봐야 할 것 같다.

오늘 배운 것

  • addEventListener(type, function, {once: true})를 나에게 알려주신 링크님
 

[자바스크립트] 한 번만 실행되는 Event Listener

가끔 onclick, onerror 등의 이벤트가 한 번만 실행돼야 할 때가 있습니다. 가령 이미지에 에러가 있을 때 그 이미지를 다른 이미지로 교체하는 함수를 만들었을 때, 교체된 이미지에도 에러가 있다

marshall-ku.com

  • MDN의 addEventListener()에 대한 설명. 근데 나 이거 분명 꽤 들여다봤는데, 그래서 options의 capture와 passive도 분명 봤는데, 그 둘 사이에 있던 once를 못 봤다고!? 진짜로!?ㅠㅠ
once
A boolean value indicating that the listener should be invoked at most once after being added. If true, the
listener would be automatically removed when invoked.
 

EventTarget.addEventListener() - Web APIs | MDN

The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.

developer.mozilla.org

오늘 하루종일 한 삽질과 함께 오늘 배운 것

  • 간단한 것부터 시작 사파리 브라우저에서 개발자 도구 열기
상단 메뉴바 -> Safari -> 환경설정 -> 고급 -> '메뉴 막대에서 개발자용 메뉴 보기' 체크 -> 상단 메뉴바에 생성된 [개발자용] 메뉴에서 '페이지 소스 보기' 클릭 또는 브라우저에서 마우스 우클릭 후 '페이지 소스 보기'
  • 지난 몇 주에 걸쳐 드문드문 작업한 결과 동영상 인코딩 라이브러리인 ffmpeg을 리액트에 잘 옮겨심었지만, 기본 브라우저로 사용하는 크롬에서만 잘 돌아가고 오늘 테스트 해본 사파리에서는 전혀 작동하지 않았다. 이건 다 사파리가 ffmpeg 작동에 필요한 sharedArrayBuffer를 지원하지 않기 때문이다.
 

Shared Array Buffer | Can I use... Support tables for HTML5, CSS3, etc

Type of ArrayBuffer that can be shared across Workers.

caniuse.com

  • sharedArrayBuffer가 궁금하다면, 솔직히 MDN 설명은 무슨 말인지 하나도 모르겠고, 그 아래 링크는 2017년도 글이지만 이해하기에는 더 좋을 것 같다. arrayBuffer와 sharedArrayBuffer의 느낌 차이를 잘 잡아준다. 사실 이 둘에 관한 설명은 생각날 때마다 구글링해보지만 아직 잘 모르겠다..
 

SharedArrayBuffer - JavaScript | MDN

SharedArrayBuffer 객체는 제네릭, 고정된 길이의 원시 바이너리 데이터 버퍼를 표현하는데 사용됩니다. ArrayBuffer 객체와 유사하지만, 공유된 메모리상의 뷰를 생성하는데 사용될 수 있습니다. Array

developer.mozilla.org

 

만화로 소개하는 ArrayBuffer 와 SharedArrayBuffer ★ Mozilla 웹 기술 블로그

이 글은 3부작 시리즈의 두번째 글입니다. 메모리 특강 만화로 소개하는 ArrayBuffer 와 SharedArrayBuffer Atomics 를 이용해서 SharedArrayBuffer 레이스 컨디션 피하기 지난 글에서는, JavaScript 같은 메모리 자

hacks.mozilla.or.kr

  • ffmpeg 깃허브 저장소를 들어가봐도 sharedArrayBuffer를 지원하는 브라우저에서만 작동한다고 적혀 있다. 지원하는 브라우저에서도 cross-origin isolation이 보장되어야만 정상적으로 기능한다. 
 

GitHub - ffmpegwasm/ffmpeg.wasm: FFmpeg for browser and node, powered by WebAssembly

FFmpeg for browser and node, powered by WebAssembly - GitHub - ffmpegwasm/ffmpeg.wasm: FFmpeg for browser and node, powered by WebAssembly

github.com

 

출처 간 격리를 이용하기 위한 가이드

출처 간 격리를 이용하면 웹 페이지에서 SharedArrayBuffer와 같은 강력한 기능을 사용할 수 있습니다. 이 문서에서는 웹사이트에서 출처 간 격리를 이용하는 방법을 설명합니다.

web.dev

  • cross-origin isolation은 헤더를 통해 설정할 수 있다고 한다. 아래 링크 게시글 작성자 분은 리액트를 nginx로 돌리면서 거기에 헤더를 설정했다.
 

How to fix SharedArrayBuffer is not defined error - TechKBlog

Came across this "SharedArrayBuffer is not defined" error in Firefox browser, while working on a react app of mine. This is how I fixed it.

techkblog.com

  • 난 nginx는 써본 적도 없었고, 인코딩 하나 때문에 그렇게까지 하고 싶지는 않았다. 이사님도 물론 같은 생각이셨고. 그래서 혹시 우리가 프론트 배포에 사용하는 aws s3로는 커스텀 헤더 설정이 가능한지 찾아보았다. 응 안돼
 

Custom headers on Amazon S3

Is it possible to have custom headers on Amazon S3 with arbitrary naming? For example, I am using a CDN pointing to Amazon S3 as the origin server, and in order to enable advanced functionality on ...

stackoverflow.com

  • 구글링하다가 나온 답은 netlify로 배포하는 거였다. netlify로 배포하면 커스텀 헤더 설정이 가능하다고 하며, 실제로 그렇게 사용한 사람들이 있다. netlify 공식문서에도 헤더 설정 방법이 적혀 있다. 희망이 보이는 듯했다.
 

Open Server To Avoid 'SharedArrayBuffer will require cross-origin isolation' - Ffmpegwasm/Ffmpeg.Wasm

Hi, thank you for your library, it's awesome, I want to ask is there any CDN like unpkg or cdn that has a custom header request Cross-Origin-Embedder-Policy: require-corp and Cross-Origin-Opener-Policy: same-origin? Thank you

issueexplorer.com

 

Custom headers

Netlify builds, deploys, and hosts your front end. Learn how to get started, see examples, and view documentation for the modern web platform.

docs.netlify.com

  • netlify로 배포하는 데만도 시간을 엄청나게 썼다. 누가 netlify 배포 쉽고 간단하다고 했어? 컴파일 에러부터 빌드 커맨드 에러, 아주 갖가지 에러를 다 만나고, 심지어 배포 시도하기 전에는 내 개인 저장소가 아니라고 배포 대상 저장소에 뜨지도 않았다. 결국 회사 저장소를 포크해서 내 저장소로 옮겨놓고 거기서부터 시작했다. 저장소가 두 개가 되니 git remote를 끊었다 연결했다 아주 난리도 아니었다ㅋㅋ 우여곡절 끝에 배포하고 나서 헤더 설정은 프로젝트 루트 디렉토리 내 netlify.toml 파일을 만들어서 그 안에 적어놔야 했다. 그런데 이거 프로젝트 루트 디렉토리에 넣어야 한다는 걸 왜 구글링해서 따로 찾아야 하는 거니ㅠㅠ
 

CORS issue with React App

Hi @hrishikesh, You are right to say that it is not in my repo. When building the app, it automatically removed it from the folder. What I did then, is to add it manually to the folder after the build operation. Seeing that it wasn’t working, I deleted i

answers.netlify.com

  • 파이어폭스 테스트 기준, 백엔드 서버에서 API 응답과 함께 내려주는 헤더에는 cross-origin isolation이 들어 있어도 sharedArrayBuffer가 제대로 기능하지 않는다. netlify에 따로 설정한 커스텀 헤더를 통해야만 진정한 isolation이 실현되는 것 같다. 그러나 사파리는 어쨌든 어떤 상황에서든 일관적으로 작동하지 않았다.

오늘 한 일

  • 타입스크립트 공부는 못했다ㅠㅠ
  • 웹페이지 메인에 동영상 띄우는 것과 관련해서 체크하고 넘어가야 할 것들이 꽤 있어서 하루종일 거기에만 시간을 쏟았다. 의외로 허무한 데서 해결되어 버린 게 있어서 시간을 투자한 만큼의 성과가 있었는지는 미지수다.
  • 자동재생으로 띄워놓은 영상이 종료되면 그 다음 영상 목록들을 뒤져서 재생 우선순위에 맞는 것을 찾아야 한다. video 태그에 id를 주고, 그걸 getElementById로 가져와서 변수에 할당한 다음, 거기에 addEventListener('ended', function) 형식으로 함수를 붙인다. 그러면 영상이 종료되는 'ended' 타입의 이벤트를 감지할 수 있다.

오늘 배운 것

  • ISO 8601 형식으로 나타내는 표준시는 아무런 처리를 하지 않는다면 국제표준시 기준으로 나온다. 당연한 건데 이걸 생각 못해서 삽질이 길어졌다...
 

Date.prototype.toISOString() - JavaScript | MDN

The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, as denoted by

developer.mozilla.org

 

오늘 한 일

  • 회사 웹페이지 1차 개편을 위한 막바지 작업을 하고 있다. 아니, 감히 막바지라고 말해도 되는지 잘 모르겠다. 아무튼, 아직은 기능이 별로 없어 환경에 따라 크게 달라지는 점은 없지만 환경별 설정 분기하는 코드도 좀 들여다보고, 기획자 분께 ip 주소 드리고 보여드리는 시늉이라도 조금 해보았다. 테스트를 포함한 모든 본격적인 건 내일부터 시작일 테지...
  • 저녁을 먹고 나서는 어제까지 이론적으로 열심히 공부한 타입스크립트를 기초적이나마 연습해보는 시간을 가졌다. CRA 없이 일단 타입스크립트만 설치해서 어떤 식으로 타입을 명시해줘야 하는지, 에러 로그는 어떻게 찍히는지, 또 그것들을 어떻게 활용할 수 있는지 직접 입력해보며 확인했다. 역시 직접 해보는 게 최고다.

오늘 배운 것

  • 프로젝트 디렉터리 내 package.json에서 환경별로 실행이나 배포 명령어를 따로 설정해놓을 수 있다는 걸 배웠다. 프로덕션 환경으로 진행하고 싶으면 해당 명령어를 입력하고, 그 명령어로 인해 콘솔 로그가 전부 숨겨진다든지 하는... 엄청난... 난 왜 몰랐을까
  • 타입스크립트 연습에 참고한 링크는 '벨로퍼트와 함께하는 모던 리액트'다. 평소에 많이 참고하는 링크지만 여기서 타입스크립트까지도 다루고 있는지 몰랐다.
 

1. 타입스크립트 연습 · GitBook

01. 타입스크립트 연습 타입스크립트에서 가장 기본적인 것들을 연습해보겠습니다. 먼저 새로운 자바스크립트 프로젝트를 생성해보겠습니다. 터미널에서 다음 명령어들을 입력하세요. $ mkdir ts-

react.vlpt.us

타입스크립트 핸드북(한글) 링크

 

타입스크립트 핸드북

 

joshua1988.github.io

주의 깊게, 다시 볼 부분

  • 여러 인터페이스를 상속받는다는데 두 번째 예시에서 왜 Developer는 Person만 extends하는가? -> Drinker가 그냥 빠진 것이었다니!
 

인터페이스 | 타입스크립트 핸드북

인터페이스 인터페이스는 상호 간에 정의한 약속 혹은 규칙을 의미합니다. 타입스크립트에서의 인터페이스는 보통 다음과 같은 범주에 대해 약속을 정의할 수 있습니다. 객체의 스펙(속성과 속

joshua1988.github.io

  • 딱 와닿게 이해되지 않는 제네릭 부분... 두 번 더 봐야겠다.
 

제네릭 | 타입스크립트 핸드북

제네릭(Generics)의 사전적 정의 제네릭은 C#, Java 등의 언어에서 재사용성이 높은 컴포넌트를 만들 때 자주 활용되는 특징입니다. 특히, 한가지 타입보다 여러 가지 타입에서 동작하는 컴포넌트를

joshua1988.github.io

  • 순차적으로 코드를 깔끔하게 정리하는 과정이 너무나 인상깊었다.
 

맵드 타입 | 타입스크립트 핸드북

맵드 타입(Mapped Type)이란? 맵드 타입이란 기존에 정의되어 있는 타입을 새로운 타입으로 변환해 주는 문법을 의미합니다. 마치 자바스크립트 map() API 함수를 타입에 적용한 것과 같은 효과를 가

joshua1988.github.io

  • 모듈 부분은 (연습이든, 아니든) 실제로 프로젝트에 적용할 때 다시 한 번 찾아봐야 할 것 같다.
 

모듈 | 타입스크립트 핸드북

소개 타입스크립트에서 가리키는 모듈이라는 개념은 ES6+의 Modules 개념과 유사합니다. 모듈은 전역 변수와 구분되는 자체 유효 범위를 가지며 export, import와 같은 키워드를 사용하지 않으면 다른

joshua1988.github.io

+ Recent posts