TIL

241120 TIL

GoJay 2024. 11. 21. 00:14
  • Udemy <Git & Github 실무 활용 완벽 가이드>
    • Git Hash를 사용할 때 앞에 7자리만 사용해도 된다. git log --oneline을 실행하면 축약된 로그를 볼 수 있고, 여기엔 7자리로 축약된 해시가 있다.
    • 일반적으로 Git에서 headbranch를 가리키고, branch는 해당 브랜치의 가장 최신 커밋을 가리킨다. 즉, headbranch는 보통 일치된 상태이다. 하지만, git checkout <이전 커밋 해시>를 통해 이전 커밋으로 이동한다면 headcommit이 분리된 상태가 된다(detached 된 상태가 된다). 이런 상황에서 커밋이나 어떠한 동작을 하려고 하면 Git은 에러를 뱉어준다.
    • 해당 상황에서 head를 다시 가장 최신 커밋이 있는 branch 위치로 이동시키고 싶다면 그냥 git switch <브랜치 이름>을 해주면 된다. 상당히 간단하다.
    • 만약에 뒤로 돌아간 커밋 위치에서 새로운 브랜치를 만들고 싶다면 git branch <브랜치 이름>으로 원래와 같이 브랜치를 새로 만들어주면 된다. 그러면 자연스럽게 head가 새롭게 생성된 branch와 일치되기 때문에 headbranch가 분리된 상태가 해결된다. 해당 상황에서 다시 원래의 기존 브랜치 최신 커밋 위치로 가고 싶으면 git switch <기존 브랜치 이름>을 해주면 된다. 간단하다.
    • 마지막 commit을 한 상태에서 수정을 하다가 마음에 안 들어서 마지막 commit을 한 시점으로 되돌리고 싶으면 git checkout HEAD를 해주면 된다. 만약에 모든 파일이 아니라 특정 파일을 바로 직전 커밋 상태로 되돌리고 싶다면 git checkout HEAD <파일명>을 해주면 된다. 되돌리고 싶은 파일이 전체는 아니지만 두 개 이상이라면 뒤에 파일명을 띄어쓰기로 구분해서 나열해 주자.
    • 동일한 동작을 git restore로도 수행할 수 있다(switch와 비슷하게 새로 나온 명령어이고, 목적에 맞는 기능만 제공해 혼란을 없앨 수 있으니, 가급적 restore를 사용하자). 마지막 커밋 이후 작업을 하다 스테이징을 안 한 상황에서 마지막 커밋 상태로 돌아가고 싶으면 git restore .를 해주면 된다.
    • git restore를 사용해서 원하는 시점의 커밋으로 복구하고 싶다면 git restore --source <커밋 해시> <파일 이름(생략 가능)> 방식으로 하면 된다. 마지막의 '생략 가능' 부분을 생략하면 모든 파일이 복구되고, 파일 이름을 띄어쓰기로 구분해서 나열하면 전달한 파일들만 복구된다.
    • git restore로 복원하면 headbranch가 분리되지 않는다.
    • git restore --stage <파일 이름>를 사용하면 git add로 스테이징 한 내용을 스테이징 취소할 수 있다. <파일 이름> 부분은 생략 가능하며, 생략하면 전체 파일의 스테이징이 취소된다.
    • git reset <커밋 해시>를 하면 headbranch의 가장 최근 커밋 정보가 모두 다 커밋 해시 위치로 돌아간다. 롤백한 커밋 해시 위치 이후의 커밋을 날리는 거다. reset을 소프트한 방식으로 하면 커밋만 취소되고 가장 마지막의 변경돼 있던 워킹 디렉토리의 파일은 이전 버전으로 변경되지 않는다. 이러한 방식은 변경 사항은 남기고 커밋을 날린 후 다른 브랜치로 쪼개서 관리하고 싶을 때 유용하다.
    • gir reset --hard <커밋 해시>를 하면 커밋 기록을 날리고 워킹 디렉토리의 작업 내역도 날려서 복원한 커밋 시점으로 되돌린다.
    • git revert <커밋 해시>git reset과 비슷하게 커밋 해시 위치로 프로젝트들 되돌린다. 하지만, 결정적인 차이가 있다. git revet는 되돌리기를 한 커밋 기록을 남겨둔다. 즉, 원하는 시점의 코드로 되돌린다는 점에서 git reset과 유사하지만, 필요하다면 코드를 원하는 시점으로 되돌리기 전의 커밋 기록을 남겨놓기 때문에 문제가 생길 가능성이 적다.
  • Udemy <한 입 크기로 잘라먹는 리액트>
    • Vite로 빌드한 리액트 프로젝트의 publicassets 둘 다 정적 파일을 저장하는 폴더이다. 하지만, 정적 파일 중 이미 파일은 assets에 저장해야 빌드 시 이미지 최적화가 된다.
    • assets에 저장된 이미지 폴더는 빌드 후 배포했을 때 이미지 데이터의 URI를 활용해 브라우저 메모리에 캐싱한다. 캐싱이 되면 한 번 받아온 이미지를 다시 request로 요청해야 할 때 브라우저 메모리에 캐싱된 이미지 URI를 가져와 사용한다.
    • 하지만, 항상 assets 폴더에 이미지를 넣는 게 맞진 않다. 정말 많은(또는 무거운) 이미지들이 사용되는 웹 애플리케이션인데 한 번 내려받은 이미지가 브라우저 메모리에 캐싱되면 브라우저의 메모리 사용량이 비대해질 것이다. 적은 양의 이미지라면 모르겠지만, 양이 많아지면 이건 브라우저의 원활한 동작에 문제를 발생시킬 수 있다. 이런 경우엔 정적 이미지 파일을 public 폴더에 저장해서 이미지 최적화를 우회하는 게 필요할 수 있다.
    • CSS로 public 폴더에 저장한 폰트를 적용하려면 아래와 같이 @font-face를 사용해서 폰트 스타일을 지정한 다음, font-family에 지정한 이름을 CSS 선택자 요소 내부에서 선언해 주면 된다.
    @font-face {
      font-family: 'NanumPenScript';
      src: url('/NanumPenScript-Regular.ttf');
    }
    
    ...
    body {
      font-family: 'NanumPenScrtip';
    } 
    • CSS에서 vh는 'viewport height'를 의미한다. 사용자의 화면 세로 길이를 의미하며, 100vh라고 설정하면 높이가 뷰포트를 꽉 채우게 된다.
    • CSS에서 white-space: nowrap으로 설정하면 뷰포트 사이즈가 줄어들어도 텍스트가 줄 바꿈 되지 않는다.
    • useNavigate로 생성한 Navigation 함수의 두 번째 인자로 객체를 전달해서 옵션을 설정할 수 있다. { replace: true }로 설정해 주면 라우팅을 하면서 뒤로 가기 적용에서 제외를 시켜준다(뒤로 가기를 해도 이전 페이지로 돌아가지 못하게 한다).
    • Navigation 함수에 인자로 -1을 전달하면 바로 이전 페이지로 이동한다. 아마도 1을 입력하면 앞쪽의 페이지로 이동하게 될 것 같다(history 객체를 사용한 것 같다).
    • Navigation 함수는 페이지에 있는 컴포넌트들이 전부 마운트(렌더링) 된 다음에 사용할 수 있다. 순서에 문제가 있다면 useEffect를 사용해서 마운트 완료 시(의존성 배열로 [] 전달) 동작하도록 수정할 수 있다.
    • 감정 일기 애플리케이션을 강의를 보며 따라 만들면서 몇 가지 든 생각이 있다.
      • Context API는 선언된 위치 하위에서 생성된 Context에 등록된 value에 쉽게 접근해서 쓸 수 있기 때문에 Props Drilling을 방지하고, 상태를 편하게 관리할 수 있는 유용한 도구임에 틀림없다. 하지만, 언제나 모든 상태를 최상위 컴포넌트에서 정의할 순 없고, 컴포넌트의 계층과 상태를 사용하는 곳에 따라 여러 곳에서 여러 상태가 정의될 수 있다. 이런 경우를 Context API만 가지고 관리하려면 여러 컴포넌트 계층에서 별도로 Context를 새롭게 다 정의를 해줘야 하고, 하위 컴포넌들은 필요에 따라 여러 Context들을 구독해야 하는 상황이 생길 것 같다(실제로 해본 건 아니지만 그럴 것 같다). 그런 식으로 여러 Context가 생기고, 한 컴포넌트에서도 다양한 Context를 구독하는 상황이 생기면, 아무래도 어떤 상태가 어떤 Context에서 어떻게 내려오는 건지를 추적하기가 쉽지 않을 것으로 예상된다. 이런 배경에서 상태 관리를 더욱 쉽게 해주는 다양한 툴들이 등장한 게 아닌가 싶다.
      • 컴포넌트들은 자신이 가지고 있는 상태가 변하거나, 또는 상위 부모 컴포넌트가 리렌더링 돼야 하면 함께 리렌더링이 될 수밖에 없다. 즉, 컴포넌트들은 언제나 리렌더링이 될 가능성을 가지고 있다(useMemomemo를 사용하면 얘기가 다르긴 하다). 그리고, 컴포넌트가 리렌더링 된다는 것은 함수인 컴포넌트가 다시 실행된다는 것이고, 내부에 정의된 모든 코드들이 다시 실행된다는 것이다. 이것의 사이드 이펙트를 항상 잘 계산해야겠다. 예를 들어, 어떤 상태 변경과 컴포넌트 리렌더링 상황에서도 절대로 바뀌지 않는 함수가 존재할 수 있다(최초 컴포넌트 마운트 시 정의한 함수를 변경 없기 계속 쓰는 경우). 이런 함수는 컴포넌트 리렌더링에 의해 다시 정의될 때마다 예상치 못한 사이드 이펙트를 발생시킬 수 있다. 이런 경우엔 useCallback을 써주는 것도 방법이고, 아니면 컴포넌트의 외부에 함수를 정의해 주는 것도 방법이 될 수 있다. 아무래도, 컴포넌트 안에 너무 많은 함수가 정의되어 있으면 유지보수나 관리가 어려워질 수 있기 때문에, 적절하게 함수를 컴포넌트 밖으로 빼기 위해 고민을 많이 해야겠다.
      • 이외에도 상태를 어디에서 정의할지, props로 내려줄 때 어떤 데이터 형태로 내려줄지, 로직을 함수로 분리할 것과 분리하지 않은 것을 어떻게 정할지, 어떤 걸 util로 빼서 관리할지 등, 개발하면서 고민해야 할 부분이 정말 많은 것 같다. 결국, 안정적이고 확장성 있는 웹 애플리케이션을 만들기 위해 여러 경험과 고민이 수반되어야 한다. 갈 길이 멀다.

'TIL' 카테고리의 다른 글

241123 TIL  (0) 2024.11.24
241121 TIL  (1) 2024.11.22
241119 TIL  (1) 2024.11.20
241117 TIL  (1) 2024.11.18
241116 TIL  (0) 2024.11.17