폴더 안에 [id].js 로 작성한다.
예시 post/[id].js
컴포넌트 안에서는 router.query 안에 id를 받고
context 객체 안에서는 context.params 안에서 조회할 수 있다.
넥스트의 서버사이드 랜더링 지원 함수.
컴포넌트가 랜더링 되기전에 먼저 데이터를 가져와서
컴포넌트에 채워서 랜더링하고
리덕스 스토어의 state를 채워준다.
이 과정을 HYDRATION이라고 한다.
주의할 점은 HYDRATION시 getServerSideProps로 바뀐 state를 제외하고
나머지 state들은 초기 state로 덮어씌워진다. (넥스트랑 리덕스는 궁합이 별로란 결론...)
넥스트 빌드 때 미리 데이터를 가져와서 정적인 html로 변환한 다음 매 요청 때마다 랜더링한다.
데이터가 바뀔 일 없는 페이지만 사용한다.
다이나믹 라우팅할 때
getStaticProps 만으로는 당연히 랜더링 할 수 없다.
그래서 특정 다이나믹 값들에 대해서 static 랜더링할 수 있게 만들어주는 지원해준다.
(static 관련 메서드는 쓸 일이 없을 듯하다.)
ssr시 쿠키가 전송이 안돼서 로그인 정보를 못 받는데 그 이유는 다음과 같다.
컴포넌트 함수 호출은 브라우저, 프론트 서버에서 실행되기 때문에
브라우저가 알아서 header에 cookie값을 넣어주는 반면,
getServerSideProps함수는 프론트 서버에서만 실행되기 때문에 쿠키를 직접 넣어야한다.
이 때 서버에 다른 유저의 쿠키가 공유되지 않도록
context객체에 쿠키가 없다면 지워야한다.
axios.default.headers.Cookie = context.req && context.req.headers.cookie
? context.req.headers.cookie
: '';
_app.js 상위의 존재.
_app.js가 랜더링 될 때 _document.js로 감싸진다.
_app.js와 _document.js에서만 사용하는 서버사이드 랜더링 메서드
babel-plugin-styled-components 를 설치한다.
styled-component를 ssr하기 위한 플러그인이다.
styled-component는 동적으로 스타일을 생성하기 때문에
ssr이 먹히질 않는다.
이 때 이 플러그인을 설치하고
// .babelsrc
{
"presets": ["next/babel"],
"plugins": [
[
"babel-plugin-styled-components",
{
"ssr": true,
"displayName": true
}
]
]
}
// _document.js
import React from 'react';
import Document, { Head, Html, Main, NextScript } from 'next/document';
import { ServerStyleSheet } from 'styled-components';
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheet();
const originalRenderPage = ctx.renderPage;
try {
ctx.renderPage = () => originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
};
} catch (error) {
console.log(error);
} finally {
sheet.seal();
}
}
render() {
return (
<Html>
<Head />
<body>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default%2Ces2015%2Ces2016%2Ces2017%2Ces2018%2Ces2019" />
<Main />
<NextScript />
</body>
</Html>
);
}
}
이렇게 설정하면 된다.
html, css, js 파일을 gzip으로 압축해주는 플러그인.
next에서는 기본 내장이라 next.config.js에서 compress옵션을 true
로 주면 된다.
js파일 분석 모듈.
빌드하고나서 어떤 파일이 용량을 많이 차지하는지 캔버스를 이용해 보여준다.
웹팩 설정 바꿀 때 작성.
next의 기본 웹팩 설정이 있기 때문에
이 파일을 이용해서 바꾼다.
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
module.exports = withBundleAnalyzer({
compress: true,
webpack(config, { webpack }) {
const prod = process.env.NODE_ENV === 'production';
const plugins = [
...config.plugins,
new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /^\.\/ko$/),
];
return {
...config,
mode: prod ? 'production' : 'development',
devtool: prod ? 'hidden-source-map' : 'eval', // 소스를 보여줄지 말지
plugins,
};
},
});
이런 식으로 작성한다.
운영체제별로 동작하거나 동작하지 않는 명령이 있는데
그 명령들을 호환해주는 모듈
ex)
npx ANALYZE=true NODE_ENV=production next build
윈도우에서 동작을 안 한다.
cross-env ANALYZE=true NODE_ENV=production next build
cross-env를 넣어주면 윈도우에서도 동작한다.
import produce, { enableES5 } from 'immer';
export default (...args) => {
enableES5();
return produce(...args);
};
immer 저자의 추천 방법이다.
produce
함수를 한 번 감싸서 호출하기 전에 enableES5
를 호출해준다.