diff --git a/frontend/lecture/src/App.tsx b/frontend/lecture/src/App.tsx index acc63b8..2f9cf67 100644 --- a/frontend/lecture/src/App.tsx +++ b/frontend/lecture/src/App.tsx @@ -3,11 +3,12 @@ import { ChevronLeftIcon, ChevronRightIcon, } from '@radix-ui/react-icons'; -import { useCallback, useEffect, useState } from 'react'; +import { Suspense, useCallback, useEffect, useState } from 'react'; import { Link, Route, Routes, useLocation } from 'react-router-dom'; import { ThemeToggle } from '@/components/ThemeToggle'; import { Separator } from '@/designsystem/ui/separator'; +import { Skeleton } from '@/designsystem/ui/skeleton'; import { Tabs, TabsList, TabsTrigger } from '@/designsystem/ui/tabs'; import { Toaster } from '@/designsystem/ui/toaster'; import { @@ -27,11 +28,13 @@ export const App = () => {
- - {Object.entries(pages).map(([key, { path, element }]) => ( - - ))} - + }> + + {Object.entries(pages).map(([key, { path, element }]) => ( + + ))} + +
diff --git a/frontend/lecture/src/components/StackBadge/index.tsx b/frontend/lecture/src/components/StackBadge/index.tsx index 3dcb9e4..a836762 100644 --- a/frontend/lecture/src/components/StackBadge/index.tsx +++ b/frontend/lecture/src/components/StackBadge/index.tsx @@ -22,7 +22,16 @@ export const StackBadge = ({ | 'CloudFront' | 'Route 53' | 'Azure' - | 'Google Cloud'; + | 'Google Cloud' + | 'Figma' + | 'Zeplin' + | 'CSS Modules' + | 'Next.js' + | 'Vercel' + | 'Turbopack' + | 'Turborepo' + | 'Create React App' + | 'GitHub Copilot'; }) => { const image = { Zustand: @@ -31,7 +40,7 @@ export const StackBadge = ({ Redux: 'https://redux.js.org/img/redux.svg', 'Tanstack Query': 'https://seeklogo.com/images/R/react-query-logo-1340EA4CE9-seeklogo.com.png', - SWR: null, + SWR: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSi42tpID7bbxVYGkhd0BNQzgf1NvcABZZ8KA&s', Recoil: 'https://d2eip9sf3oo6c2.cloudfront.net/tags/images/000/001/298/square_480/recoil.png', MobX: 'https://mobx.js.org/assets/mobx.png', @@ -56,11 +65,28 @@ export const StackBadge = ({ 'https://static-00.iconduck.com/assets.00/google-cloud-icon-2048x1646-7admxejz.png', 'Route 53': 'https://static-00.iconduck.com/assets.00/aws-route53-icon-212x256-16an9num.png', + Figma: + 'https://upload.wikimedia.org/wikipedia/commons/a/ad/Figma-1-logo.png', + Zeplin: + 'https://static-00.iconduck.com/assets.00/apps-zeplin-icon-2048x2048-qh5y1ogk.png', + 'CSS Modules': + 'https://raw.githubusercontent.com/css-modules/logos/master/css-modules-logo.png', + 'Next.js': + 'https://static-00.iconduck.com/assets.00/nextjs-icon-512x512-y563b8iq.png', + Vercel: 'https://www.svgrepo.com/show/327408/logo-vercel.svg', + Turbopack: + 'https://seeklogo.com/images/T/turbopack-icon-logo-77EE129FEC-seeklogo.com.png', + Turborepo: + 'https://seeklogo.com/images/T/turborepo-logo-D9CF2C830E-seeklogo.com.png', + 'Create React App': + 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRf8yndOQhIaFf36hkWn9w6UAff4nmPREbmvQ&s', + 'GitHub Copilot': + 'https://seeklogo.com/images/G/github-copilot-logo-C25AFBDF08-seeklogo.com.png', }[stack]; return ( - {image !== null && } + {stack} ); diff --git a/frontend/lecture/src/lectures/Ecosystem/NextJS-usage.png b/frontend/lecture/src/lectures/Ecosystem/NextJS-usage.png new file mode 100644 index 0000000..1ae2ab7 Binary files /dev/null and b/frontend/lecture/src/lectures/Ecosystem/NextJS-usage.png differ diff --git a/frontend/lecture/src/lectures/Ecosystem/index.tsx b/frontend/lecture/src/lectures/Ecosystem/index.tsx index 0ce09f7..5b99802 100644 --- a/frontend/lecture/src/lectures/Ecosystem/index.tsx +++ b/frontend/lecture/src/lectures/Ecosystem/index.tsx @@ -1,6 +1,11 @@ +import { ExternalLink } from '@/components/ExternalLink'; +import { InlineCode } from '@/components/InlineCode'; import { Slides } from '@/components/Slides'; +import { StackBadge } from '@/components/StackBadge'; import { getLectureItem } from '@/lectures'; +import nextJsUsage from './NextJS-usage.png'; + export const ecosystemLecture = getLectureItem({ title: '프론트엔드 생태계', description: '기술 동향 파악하기, 생태계에 참여하기', @@ -14,7 +19,95 @@ export const ecosystemLecture = getLectureItem({

코드에서 한발짝 벗어난 이야기들

프론트엔드 생태계에 대해 이해한다

-

생태계가 나아가는 방향을 파악할 수 있다

+

+ 생태계가 나아가는 방향을 파악하고, 앞으로 어떤 공부를 어떻게 + 할지 생각해볼 수 있게 된다 +

+
+ ), + }, + { + title: 'React 의 방향성', + content: ( +
+

+ 리액트는 최근에 서버 컴포넌트를 상용화시켰고, 이제{' '} + + 라는 걸 준비하는 중 +

+

+ 개인적으로는 별로 중요한지 모르겠는데.. 뭔가 프레임워크로서 + 특이점에 다다랐다는 느낌 +

+

+ 직접 운영하던 을 버리고 + 프레임워크를 권장하기 시작했음 +

+ +
+ ), + }, + { + title: '프레임워크: Next.js', + content: ( +
+

+ 는 현재 프론트엔드 트렌드를 + 이끌어가는 프레임워크 +

+ Next.js 사용 현황 +

+ react 공식문서에서도 를 권장하는 + 만큼, 앞으로 공부하다 보면 언젠가 분명히 만나게 될 기술 +

+

+ 은 프론트엔드 생태계에 하나의 + 왕국을 건설하고 있다 (,{' '} + , ,{' '} + ,{' '} + ) +

+
+ ), + }, + { + title: 'AI (1) copilot', + content: ( +
+

+ 은 코딩을 도와주는 + 자동완성 도구 +

+

재작년쯤부터는 거의 무조건 써야 하는 필수 도구 수준

+

코파일럿이 얼마나 잘해주는지 같이 봅시다

+
+ ), + }, + { + title: 'AI (2) cursor 등 AI 통합 IDE', + content: ( +
+

+ AI 통합 IDE로, IDE에게{' '} + 기존 코드 이거 이거 참고해서 이렇게 해줘 라고 하면 다 해 + 준다 +

+

얘도 같이 봅시다

+
+ ), + }, + { + title: 'AI (3) v0', + content: ( +
+

+ 는 ui를 만들어주는 AI +

+

얘도 지금 같이 써볼까요?

+
), }, diff --git a/frontend/lecture/src/lectures/Performance/index.tsx b/frontend/lecture/src/lectures/Performance/index.tsx index 2c6d5b2..cb69d4c 100644 --- a/frontend/lecture/src/lectures/Performance/index.tsx +++ b/frontend/lecture/src/lectures/Performance/index.tsx @@ -1,167 +1,16 @@ -import { Callout } from '@/components/Callout'; -import { CodeSnippet } from '@/components/CodeSnippet'; -import { InlineCode } from '@/components/InlineCode'; -import { Slides } from '@/components/Slides'; +import { lazy } from 'react'; + import { getLectureItem } from '@/lectures'; -import lighthouse from './lighthouse.png'; +const PerformanceSlides = lazy(() => + import('@/lectures/Performance/slides').then((r) => ({ + default: r.PerformanceSlides, + })), +); export const performanceLecture = getLectureItem({ title: '성능과 SSR', description: 'Next.js', date: new Date('2024-11-06 20:30:00'), - element: ( - -
    -
  • 프론트엔드에서 무슨 성능을 개선해야 하는지 이해한다
  • -
  • lighthouse 사용법을 익힌다
  • -
  • 우리가 쓰는 CSR 방식이 왜 로딩 성능이 나쁜지 이해한다
  • -
  • SSR이란 게 있더라~ 정도를 인지한다
  • -
  • Next.js 라는 메타프레임워크의 존재를 인지한다
  • -
- - ), - }, - { - title: '성능?', - content: ( -
-

보통 성능이라고 하면 떠올리는 것들

-
    -
  • 시간
  • -
  • 공간 (메모리)
  • -
  • 로딩 속도
  • -
-
- ), - }, - { - title: '시간 복잡도와 렌더링 최적화 (1)', - content: ( -
-

시간 복잡도를 줄여서 연산 시간을 줄이자!

-

하지만 웹은 대부분의 경우 n이 커봐야 1000입니다

- -
- , 등 - 메모이제이션 기법도 있고 합성을 활용한 렌더링 최적화 기법도 - 있는데, 솔직히 4년동안 웹 하면서 최적화가 필요했던 적 딱 한 번 - 밖에 없었습니다. -
-
- 리액트는 대부분의 경우 충분한 성능이 나오게 설계되었기에, - 평범하게 짜면 충분히 빠릅니다. -
-
- 어차피 브라우저가 60fps라서 엄청 빨라봤자 유저는 모릅니다. -
-
- ), - }, - { - title: '시간 복잡도와 렌더링 최적화 (2)', - content: ( -
-

- 관련해서 "불필요한 리렌더를 줄여야 한다" 와 같은 - 주장도 있는데, 딱히 공감하진 않습니다 -

-

- 평범하게 정상적으로 짜면 적당한 리렌더가 발생하고 유저는 - 불편함을 느끼지 못합니다. -

-

- 불필요한 리렌더를 막으려다 필요한 리렌더를 못하거나, 코드 - 유지보수가 어려워지면 그게 진짜 문제입니다 -

- 웬만하면 이거 신경쓸 필요 없다! -
- ), - }, - { - title: '메모리', - content: ( -
-

자바스크립트는 GC가 동작하는 언어

-

웹에서 다루는 메모리가 그리 크지 않음

-

따라서 메모리 누수가 일어나지 않는 한 별 문제 없음

- - 더 이상 필요하지 않은 메모리를 해제하지 않아서 메모리 사용량이 - 계속 증가하는 현상 - - -

- 가아아아아끔 이런 코드를 짜야 할 때가 있는데, 얘만 free 잘 해 - 주면 됩니다 -

- 웬만하면 이거도 신경쓸 필요 없다! -
- ), - }, - { - title: '로딩 속도', - content: ( -
-

그런데 로딩 속도는 문제가 됩니다

-

- 따라서 웹 개발자들은 성능을 개선할 때 로딩 속도를 최적화하는 - 데에 많은 노력을 쏟아야 합니다 -

-
- ), - }, - { title: '왜 로딩 속도는 문제가 될까?', content:
TBD
}, - { - title: '로딩 속도 - lighthouse 점수', - content: ( -
-

- 로딩 속도뿐 아니라 웹 페이지의 품질을 통합적으로 체크해볼 수 - 있는 지표 -

- -

라이브로 한번 봅시다

-
- ), - }, - { - title: '로딩 속도 - lighthouse 실습', - content: ( -
-

- 각 조별로, 만들었던 프로젝트의 lighthouse 점수를 확인하고 - 캡쳐해서 조별 채널에 올려주세요 (제한시간 2분) -

-
- ), - }, - { title: '로딩 속도 개선: 용량 줄이기', content:
TBD
}, - { title: '로딩 속도 개선: 스켈레톤 ui', content:
TBD
}, - { - title: '로딩 속도 개선: SSR (1) CSR 방식에 대한 이해', - content:
TBD
, - }, - { - title: '로딩 속도 개선: SSR (2) SSR?', - content:
TBD
, - }, - { - title: '로딩 속도 개선: SSR (3) 서버 컴포넌트', - content:
TBD
, - }, - { - title: '로딩 속도 개선: SSR (4) 만능일까?', - content:
비용, 서버 리소스 관리, 프레임워크에 결합
, - }, - ]} - /> - ), + element: , }); diff --git a/frontend/lecture/src/lectures/Performance/slides.tsx b/frontend/lecture/src/lectures/Performance/slides.tsx new file mode 100644 index 0000000..f5346de --- /dev/null +++ b/frontend/lecture/src/lectures/Performance/slides.tsx @@ -0,0 +1,165 @@ +import { FC } from 'react'; + +import { Callout } from '@/components/Callout'; +import { CodeSnippet } from '@/components/CodeSnippet'; +import { InlineCode } from '@/components/InlineCode'; +import { Slides } from '@/components/Slides'; + +import lighthouse from './lighthouse.png'; + +export const PerformanceSlides: FC = () => { + return ( + +
    +
  • 프론트엔드에서 무슨 성능을 개선해야 하는지 이해한다
  • +
  • lighthouse 사용법을 익힌다
  • +
  • 우리가 쓰는 CSR 방식이 왜 로딩 성능이 나쁜지 이해한다
  • +
  • SSR이란 게 있더라~ 정도를 인지한다
  • +
  • Next.js 라는 메타프레임워크의 존재를 인지한다
  • +
+ + ), + }, + { + title: '성능?', + content: ( +
+

보통 성능이라고 하면 떠올리는 것들

+
    +
  • 시간
  • +
  • 공간 (메모리)
  • +
  • 로딩 속도
  • +
+
+ ), + }, + { + title: '시간 복잡도와 렌더링 최적화 (1)', + content: ( +
+

시간 복잡도를 줄여서 연산 시간을 줄이자!

+

하지만 웹은 대부분의 경우 n이 커봐야 1000입니다

+ +
+ , 등 + 메모이제이션 기법도 있고 합성을 활용한 렌더링 최적화 기법도 + 있는데, 솔직히 4년동안 웹 하면서 최적화가 필요했던 적 딱 한 번 + 밖에 없었습니다. +
+
+ 리액트는 대부분의 경우 충분한 성능이 나오게 설계되었기에, + 평범하게 짜면 충분히 빠릅니다. +
+
+ 어차피 브라우저가 60fps라서 엄청 빨라봤자 유저는 모릅니다. +
+
+ ), + }, + { + title: '시간 복잡도와 렌더링 최적화 (2)', + content: ( +
+

+ 관련해서 "불필요한 리렌더를 줄여야 한다" 와 같은 + 주장도 있는데, 딱히 공감하진 않습니다 +

+

+ 평범하게 정상적으로 짜면 적당한 리렌더가 발생하고 유저는 + 불편함을 느끼지 못합니다. +

+

+ 불필요한 리렌더를 막으려다 필요한 리렌더를 못하거나, 코드 + 유지보수가 어려워지면 그게 진짜 문제입니다 +

+ 웬만하면 이거 신경쓸 필요 없다! +
+ ), + }, + { + title: '메모리', + content: ( +
+

자바스크립트는 GC가 동작하는 언어

+

웹에서 다루는 메모리가 그리 크지 않음

+

따라서 메모리 누수가 일어나지 않는 한 별 문제 없음

+ + 더 이상 필요하지 않은 메모리를 해제하지 않아서 메모리 사용량이 + 계속 증가하는 현상 + + +

+ 가아아아아끔 이런 코드를 짜야 할 때가 있는데, 얘만 free 잘 해 + 주면 됩니다 +

+ 웬만하면 이거도 신경쓸 필요 없다! +
+ ), + }, + { + title: '로딩 속도', + content: ( +
+

그런데 로딩 속도는 문제가 됩니다

+

+ 따라서 웹 개발자들은 성능을 개선할 때 로딩 속도를 최적화하는 + 데에 많은 노력을 쏟아야 합니다 +

+
+ ), + }, + { title: '왜 로딩 속도는 문제가 될까?', content:
TBD
}, + { + title: '로딩 속도 - lighthouse 점수', + content: ( +
+

+ 로딩 속도뿐 아니라 웹 페이지의 품질을 통합적으로 체크해볼 수 + 있는 지표 +

+ +

라이브로 한번 봅시다

+
+ ), + }, + { + title: '로딩 속도 - lighthouse 실습', + content: ( +
+

+ 각 조별로, 만들었던 프로젝트의 lighthouse 점수를 확인하고 + 캡쳐해서 조별 채널에 올려주세요 (제한시간 2분) +

+
+ ), + }, + { title: '로딩 속도 개선: 용량 줄이기', content:
TBD
}, + { title: '로딩 속도 개선: 스켈레톤 ui', content:
TBD
}, + { + title: '로딩 속도 개선: SSR (1) CSR 방식에 대한 이해', + content:
TBD
, + }, + { + title: '로딩 속도 개선: SSR (2) SSR?', + content:
TBD
, + }, + { + title: '로딩 속도 개선: SSR (3) 서버 컴포넌트', + content:
TBD
, + }, + { + title: '로딩 속도 개선: SSR (4) 만능일까?', + content:
비용, 서버 리소스 관리, 프레임워크에 결합
, + }, + ]} + /> + ); +}; diff --git a/frontend/lecture/src/lectures/Styling/index.tsx b/frontend/lecture/src/lectures/Styling/index.tsx index f33b76d..52cc2b7 100644 --- a/frontend/lecture/src/lectures/Styling/index.tsx +++ b/frontend/lecture/src/lectures/Styling/index.tsx @@ -152,8 +152,8 @@ export const stylingLecture = getLectureItem({ language="css" />

- BEM 방식으로 className을 작성 구조화된 - 이름으로 겹치는 문제는 없어짐 + BEM 방식으로 className을 작성 (아마도) 이름이 + 겹치지는 않을 것

하지만 여전히 연결점이 없으므로 유지보수가 어려움 @@ -199,12 +199,16 @@ export const stylingLecture = getLectureItem({ code={[ `import styled from 'styled-components'`, `// ...`, - `const Logo = styled.div\``, + `const Wrapper = styled.div\``, ` color: red;`, ` margin: 2px 4px;`, `\`;`, `// ...`, - `return `, + `return (`, + ` `, + ` Hello World!`, + ` `, + `)`, ]} language="jsx" /> @@ -227,7 +231,10 @@ export const stylingLecture = getLectureItem({ language="jsx" />

아예 패러다임을 전환하여 utility-first 로 개발
-
스타일 정보를 className에 모두 작성하는 방식
+
+ 자주 사용하는 스타일들에 해당하는 유틸성 className을 미리 + 만들어둔다 +
), }, @@ -259,47 +266,78 @@ export const stylingLecture = getLectureItem({ { title: '번외: CSS Framework', content: ( -
-
- Bootstrap Logo -

Bootstrap

-

옛날에 짱많이쓰던거

- +
+
미리 만들어져있는 이쁜 시스템들이 있습니다
+
+ 디자이너가 디자인해주는 상황이면 필요없지만, 어드민을 구축하거나 + 직접 디자인을 해야 할 경우 아주 편하게 사용 가능
-
- Ant Design Logo -

Ant Design

-

중국꺼

- +
+
+ Bootstrap Logo +

Bootstrap

+

옛날에 짱많이쓰던거

+ +
+
+ Ant Design Logo +

Ant Design

+

중국꺼

+ +
+
+ Material-UI Logo +

Material-UI

+

구글꺼

+ +
+
+ shadcn/ui Logo +

shadcn/ui

+

TMI) 이 강의자료는 shadcn을 썼습니다

+ +
-
- Material-UI Logo -

Material-UI

-

구글꺼

- +
+ ), + }, + { + title: '시안 보고 구현하는 법', + content: ( +
+
+ 디자이너분들은 보통 나{' '} + 등을 이용해서 디자인하고 시안을 + 주십니다 +
+
+ 요즘은 가 대세
-
- shadcn/ui Logo -

shadcn/ui

-

이 강의자료는 shadcn을 썼습니다

- +
+ 위에서 언급한 기술들 중 제일 기본인{' '} + 를 이용해서, SNUTT 모바일 + 로그인화면 라이브코딩 하겠습니다
+
), }, diff --git a/frontend/lecture/src/lectures/WrapUp/index.tsx b/frontend/lecture/src/lectures/WrapUp/index.tsx index c2ffff6..c1a8829 100644 --- a/frontend/lecture/src/lectures/WrapUp/index.tsx +++ b/frontend/lecture/src/lectures/WrapUp/index.tsx @@ -1,9 +1,42 @@ import { Slides } from '@/components/Slides'; +import { StackBadge } from '@/components/StackBadge'; import { getLectureItem } from '@/lectures'; export const wrapupLecture = getLectureItem({ title: '마무리', description: '', date: new Date('2024-11-20 20:30:00'), - element: , + element: ( + TBD
}, + { + title: '그럼 세미나 이후 Next Step 으로 뭘 공부하면 좋을까요?', + content: ( +
+

+ 개인의 목표에 따라 다르겠지만, 여기까지 세미나&과제 진행하셨고 + 이후 토이 프로젝트 진행하신다면 개발을 경험해 봤다 정도는 + 충분히 달성하셨습니다 +

+

+ 사실 개발은 분야가 워낙 넓고, 학문보다는 실무에 가까운 영역이다 + 보니 경험을 통해 배운다 라는 말이 가장 적합한 것 같아요 +

+

+ 이 이후로는 프로젝트 진행하시면서 + 도 도입해 보시고, 도 써 + 보시고, ... 이렇게 하나하나씩 쌓아나가시는 걸 추천드립니다 +

+

+ 그리고 언제나 중요한 기초: 가령 JavaScript 의 실행 컨텍스트나 + 렉시컬스코핑 같은 개념들도 세미나에서 다루기엔 너무 재미없어서 + 건너뛰었을 뿐 실제로는 개발자에게는 매우 중요한 지식이라는 점 +

+
+ ), + }, + ]} + /> + ), });