이전 글에서 next.js 프론트엔드 프로젝트에 typescript, recoil, sass 라이브러리를 설치했는데,
거기에 더해 개발 편의성을 위해 몇가지 라이브러리들을 더 설치했다.
{
"name": "nsb-client",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"dependencies": {
"@types/classnames": "^2.2.11",
"@types/remove-markdown": "^0.1.1",
"classnames": "^2.2.6",
"dayjs": "^1.10.4",
"next": "10.0.6",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-markdown": "^5.0.3",
"recoil": "^0.1.2",
"remove-markdown": "^0.3.0",
"sass": "^1.32.5",
"swr": "^0.4.1"
},
"devDependencies": {
"@types/node": "^14.14.22",
"@types/react": "^17.0.0",
"tslint": "^6.1.3",
"tslint-config-airbnb": "^5.11.2",
"typescript": "^4.1.3"
}
}
npm install --save-dev tslint tslint-config-airbnb
tslint는 typescript를 위한 eslint 라이브러리다. typescript 문법에 대한 오류를 잡아주고, 설정한 베스트 프렉티스에 맞춰서 코드를 작성할 수 있도록 가이드해준다.
tslint-config-airbnb는 airbnb에서 사용하는 tslint 설정으로 보편적으로 깔끔한 코드 컨벤션을 제공해준다.
자세한 설정 파일은 nsb-client 깃헙 레포 에서 확인할 수 있다
classnames는 css(scss) module을 좀더 사용하기 쉽게 해주는 라이브러리다.
npm install classnames @types/classnames --save
classnames를 사용하면 scss module을 다음과 같이 작성할 수 있다.
구체적인 classnames의 사용이유는 링크 를 참고하자.
Page.module.scss
.container {
min-height: 100vh;
max-width: 1280px;
padding: 0 0.5rem;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
.content-pane {
width: 768px;
}
.side-pane {
width: 440px;
}
}
index.tsx(page)
// with classnames
import classNames from 'classnames/bind'
import styles from '@/styles/Page.module.scss'
import PostItem from '@/components/post-item'
const cx = classNames.bind(styles)
const Home = () => {
return (
<div className={cx('container')}>
<div className={cx('content-pane')}>
</div>
<div className={cx('side-pane')}>
</div>
</div>
)
}
export default Home
dayjs는 날짜 및 시간 표현에 대한 포맷팅을 쉽게 할 수 있도록 도와주는 라이브러리다. 기존에는 moment.js를 많이 사용해왔으나, 이제 추가적인 업데이트와 지원이 없을 예정이어서, 이번 프로젝트에서는 인터페이스가 거의 유사하고 더 경량화된 dayjs를 사용하기로 한다.
yarn add dayjs
react-markdown은 react에서 markdown 소스를 html로 변환해주고, remove-markdown은 markdown소스에서 markdown문법요소들을 제거하고 텍스트만 추출해준다. strapi에서 기본적으로 제공해주는 에디터가 markdown에디터로 되어있어 markdown 관련 라이브러리를 설치해줬다.
yarn add react-markdown remove-markdown
swr은 vercel에서 만든 data fetching 라이브러리인데, 서버 캐쉬를 활용한 효율적인 data fetching을 지원한다고 한다. 자세한 사항은 공식 홈페이지를 참고하자
yarn add swr
module.exports = {
sassOptions: {
includePaths: ['./components'],
prependData: `@import "@/styles/var.scss";`,
}
}
sass module을 사용하게 되면 sass 변수를 사용하기 위해서는 모든 module.scss 파일에서 선언해둔 scss 변수 파일을 import 해와야 한다.
이 작업이 무척 번거로운 일이여서, sassOptions을 통해 components 폴더 밑에 있는 모든 scss파일에 자동으로 @import "@/styles/var.scss";
라인을 추가해주도록 했다.
코드를 작성할 때, 모든 import를 상대경로로 불러오는 것은 무척 번거로운 일이다.
tsconfig에서 paths를 추가해 설정해두면, 다음과 같이 root path 기반으로 수월하게 import 경로를 설정해둘 수 있다.
tsconfig.json
"compilerOptions": {
...
"paths": {
"@/*": ["./*"]
}
}
import styles from '../../styles/Page.module.scss'
import PostItem from '../../components/post-item'
import { TPost } from '../../types'
// without paths options
import styles from '@/styles/Page.module.scss'
import PostItem from '@/components/post-item'
import { TPost } from '@/types'
// with paths options
프로젝트의 전체적인 구조는 다음과 같다.
components : 컴포넌트들을 모아둔 폴더
config : API_URL 등의 프로젝트 전체적으로 사용하는 설정값들을 모아둔 폴더
layout : 애플리케이션이 공통적으로 사용하는 레이아웃을 모아둔 폴더
pages : next.js를 사용하면 pages내의 파일과 폴더들을 기준으로 자동으로 라우팅이 생성됨 참고
public : 필드 후 제공할 정적 에셋들을 모아놓은 폴더
recoil : 프로젝트에서 글로벌 스토어로 사용할 recoil의 atom, selector 등을 모아놓은 폴더
service : api service route들을 모아놓은 폴더
styles : global.css, reset.css, var.scss 등 글로벌로 관리하는 스타일 및 스타일 변수를 모아놓은 폴더
types : 타입스크립트 사용을 위한 interface등 타입들을 모아놓은 폴더
utils : 유틸리티 함수들을 모아놓은 폴더
구체적인 폴더 별 사용례는 실제 코드를 작성하면서 설명하도록 하겠다.
현재까지 진행된 프로젝트는 깃헙 레포지토리에서 확인할 수 있다.
https://github.com/mopsyshin/nsb-client/tree/nsb-03