
폴더 안에 [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를 호출해준다.