자바스크립트로 만들어진 해커뉴스 페이지를 타입스크립트로 변환하는 작업을 할 것인데 이런 작업을 포팅이라고 한다.
기존에 해커뉴스 페이지는 html파일(index.html)과 js파일(app.js)로 구성되어 있는데 타입스크립트를 사용하기 위해 app.js파일을 app.ts파일로 변환한다. 그리고 tsconfig.json이라는 파일을 생성한다.
- tsconfig.json
{
"compilerOptions": { // 주로 사용하는 부분
"strict": true, // 타입체크
"target": "ES5", // 변환할버전
"module": "commonJS",
"alwaysStrict": true,
"noImplicitAny": true,
"noImplicitThis": true,
"sourceMap": true, // html과 js, ts 파일 등을 map 형식으로 나타낸다
"downlevelIteration": true
}
}
html은 타입스크립트 파일 자체를 읽어낼 수 없기 때문에 내부적으로 타입스크립트를 자바스크립트로 변환하는 작업이 필요하다. 여기서 config 파일이 그 작업을 도와주고 또 다른 세부 설정도 할 수 있다. parcel 번들러를 실행하고 나면 작업 폴더 내 dist폴더 안에 또 다른 html파일과 js파일이 있는데 형식이 조금 다른 파일이 생성된다. (트랜스파일링이 된 것)
먼저 기존 newsFeed는 getData()를 통해 newsFeed를 호출 할 때마다 ajax로 데이터를 불러 들였기 때문에 공공으로 사용하는 store객체에 feeds라는 배열을 추가하여 store의 안에 있는 feeds 배열로 사용한다. ajax로 불러온 데이터를 store에 저장했기 때문에 전역적으로 데이터를 관리할 수 있으며 데이터의 API 형태나 필요한 데이터 구조를 추가할 수 있다. 데이터 읽음 처리를 위해 makeFeed() 함수를 통해 read라는 boolean값 데이터를 추가하여 글을 조회하지 않았을 시엔 false, 조회 하였을 땐 true 값으로 구분한다.
지금까지 만들어진 해커뉴스의 디자인적인 부분은 tailwindCss를 가지고 작업을 할것이다. 그렇게 하기 전에 기존에 있는 해커뉴스의 코드는 template을 가지고 구조적인 부분을 수정했지만 아직도 문제가 있다.
template의 <ul>, <li> 태그들은 아직도 반복문을 따로 사용해서 작업하는 부분이나 template의 동적인 데이터를 추가해야 하는 부분은 데이터의 변경이 있을때마다 replace함수를 써 줘야하기 때문에 여러가지 기능들이 추가되면 replace 함수를 그만큼 추가로 사용해야 하는 문제점이 있다. 따라서 템플릿엔진(ejs, pug, nunjucks, handlebars 등)을 사용할 것이다.
(확연히 기존 template 변수에 사용된 html 태그보다 스타일링을 통해 내용이 길어짐)
각 목록 화면과 내용 화면에 UI 부분을 tailwindCss를 사용해서 디자인을 수정했다. html 태그의 클래스를 보게되면 css의 속성(display: flex -> flex, justify-content: space-between -> justify-between 등)을 tailwindCss만의 방식으로 클래스명을 사용하여 스타일링한 것을 알 수 있다.
해커뉴스의 내용엔 comment 데이터가 있는데 comment안에 comment가 있는 형식으로 단계가 정해져 있지 않은 구조이다. comment 부분은 makeComment() 함수를 통해 배열 안의 배열을 재귀 호출을 통해서 조회한다. comment배열 안의 comment가 있는지 조건문으로 처리하고 comment안의 배열이 없을 때 해당하는 값을 return 한다.
UI를 변경하기 전에 기존 DOM API를 사용했을 때보다 훨씬 더 보기 직관적이고 개발자도구의 Element와 구조가 비슷한 형태로 어느 부분에 어떤 데이터가 들어갈지 보다 잘 확인할 수 있는 구조가 되었다. 또한 변경이 필요한 부분이라면 어느 부분에서 변경이 일어나는지 한 눈으로 알 수있고 그것이 데이터이던지 화면을 구성하는 코드이던지 변경에 용이하다.
tailwind css는 CSS 프레임워크의 일종으로 부트스트랩과 비슷하지만 다소 차이가 있는것 같다. 사용법은 mt-1, ml-6 등 tailwind css 사이트에 있는 컴포넌트나 레이아웃 등을 참고하며 사용할 수 있다. 부트스트랩과 같은 다른 프레임워크들에 비해 기본 스타일 값을 사용하고 필요하다면 디테일하게 커스텀이 가능하다. 부트스트랩의 경우는 완성된 디자인의 컴포넌트를 갖다 쓰는 느낌이지만 tailwind css는 기본 스타일 값을 수정하고 수정하고 나서도 디자인의 일관성을 망치지 않을 수 있다. css-in-js 와는 컨셉이 확연히 다르다. 하지만 단점으로는 html 태그의 class가 하염없이 길어질 수도 있으며 css-in-js의 장점인 어떤 변수에따라 다른 값을 줄 수 있는 스타일링 등은 하기 힘들다.
페이징 처리를 하기 위해서 전체적으로 공용으로 사용할 store라는 객체에 currentPage 값을 추가했다. 이 store 객체는 hacknews 페이지의 전역객체로 사용될 것이다. 리액트를 사용하면 상위 컴포넌트에서 하위 컴포넌트로 props를 통해 데이터를 전달하는데 리덕스를 사용하면 컴포넌트를 전역적으로 설정하고 다른 여러 컴포넌트에서 사용할 수 있다. 현재 만든 웹앱 구조의 store 객체의 컨셉은 리덕스처럼 사용될 것 같다. 지금은 단순 리터럴로 사용된 전역 객체지만 앞으로 약간의 변화를 통해 다른 객체들에서 전역적으로 작용할 객체가 될 것이다.
또한 페이징 처리를 할 url과 목록을 조회하는 url을 분리 시켰기 때문에 라우팅 처리를 해줘야하는 router 함수를 수정했다. hashchange 이벤트 리스너를 통해서 변화된 path에 따라 보여지는 화면이 newsFeed와 newsDetail로 나눠진다.
기존의 코드에서 DOM API 방식을 전부 문자열 HTML 형식으로 수정했고 반복되고 재사용되는 코드들을 함수화했다. 기존에 목록 화면과 내용 화면이 공존하거나 내용 화면이 계속 추가되는 상태였는데, 함수화 작업을 통해 목록 화면 부분과 내용 화면 부분을 나눴고 router라는 함수를 통해 hashchange 이벤트 처리 시 목록 화면을 내보낼지 내용 화면을 내보낼지 중계 해주는 작업을 추가했다.
기존의 구조를 변경했다. ajax를 통해서 해커뉴스 서버의 데이터를 받아오는 방식을 특정한 곳에서나 여러번 사용 가능하도록 함수로 바꿨다. ajax나 fetch, axios 등의 서버에서 데이터를 가져오는 기능은 이벤트리스너 함수처럼 비동기로 처리해야 하지만 현재는 강의의 진행에따라 동기적인 방식으로 처리한다.