All Articles

Next.js 초기세팅 삽질기. 정답이 아닙니다. 삽질기입니다

image.png

주의사항 이 포스팅은 정답이 아닌 삽질기이고, 앞으로도 이 여정은 계속될 예정입니다.

이아저씨 포스팅 보고 약간 따라함.

시작

지난번 포스팅과 동일

Express

yarn add express 명령어로 설치 고고!
express를 하냐 안 하냐의 차이는.. 잘은 모르지만 custom API routes를 다룰때 좋다 함!
이어서…

server.js를 파일을 만드는데, 꼭 package.json과 동일한 위치에 놔야함

//server.js
const express = require('express');
const next = require('next');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
  const server = express();
  server.get('*', (req, res) => handle(req, res));
  server.listen(port, (err) => {
    if (err) throw err;
    // console.log(`🤘 on http://localhost:${port}`);
  });
});

console 찍히는 부분은 Eslint 때문인지 뭔지 자꾸 귀찮게 Problem이 떠서 주석처리했다
여튼 처음에 경로가 중요하다고 써놨는데… 경로설정을 제대로 하지 않으면

image.png

MoDULE_NOT_FOUND라는 error 발생! 그럴땐, 두 가지를 확인해야 한다.

  1. node_modules 유무
  2. 경로확인

나는 일단 rm -rf node_modules 명령어로 node_modules를 삭제해주고
npm isntall로 다시 깔아주었다.
하지만 yarn start를 하는 순간 결과는 똑같은 MNF(Module not found의 줄임말쓰~)
그래서 다른분께 여쭤봤더니 경로가 잘못된것 같다고 하셔서.. server.js 파일 경로를 보니 pages 안에 들어있었다!!!! 그래서 이걸 다시 밖으로 뺌 ㄱㄱ

그랬더니 에러는 빠염~

Eslint 깔기

CRA의 방식과 약간 다른것 같음

yarn add -D babel-eslint eslint eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-babel eslint-plugin-import

이 명령어로 시작! 난 수도 없으면 안돼~ 그리고 .eslintrc.js라는 파일 생성

//eslintrc.js file
module.exports = {
 extends: ['airbnb'],
 env: {
  browser: true,
 },
 parser: 'babel-eslint',
 rules: {
  indent: 0,
  'no-tabs': 0,
  'eol-last': ['error', 'always'],
  'no-underscore-dangle': 0,
  'react/jsx-indent': 0,
  'react/jsx-indent-props': 0,
  'react/jsx-filename-extension': 0,
  'react/forbid-prop-types': 0,
  'react/require-default-props': 0,
 },
};

혹시나 prettier를 안 깐 분들은 vscode 스토어?에서 설치고고
그다음에 명령어 입력 고고 yarn add -D prettier

그담엔 settings에 들어가서 json파일에 이걸 추가해준다.

{
  "editor.formatOnSave": true,
  "prettier.eslintIntegration": true
}

그러면 빨간줄이 뙇!! 행복쓰~

Eslint rules off

.eslintrc.js 파일을 보면 객체안에 rules라는 값들이 있는데..
0은 off 1은 on이다. true/false 값을 이용해서 그렇게 한듯..?! 똑똑해~

 rules: {
    indent: 0,
    "no-tabs": 0,
    "eol-last": ["error", "always"],
    "no-console": 0,
    "no-underscore-dangle": 0,
    "react/jsx-indent": 0,
    "react/jsx-indent-props": 0,
    "react/jsx-filename-extension": 0,
    "react/react-in-jsx-scope": 0,
    "react/forbid-prop-types": 0,
    "react/require-default-props": 0
  }

위에서 Eslint가 잘 구동되서 빨간줄 나와서 행복했던 것도 잠시…
빨간줄 땜에 넘나 스트레스를 받아서 구글링 해본 결과물로 off 효과주기!
검색하면 굉장히 항목이 많다.. 난 일단 이정도로만 설정해놓았다

폴더구조 확인

image.png

일단은 이렇게 세팅해놓은 상태이다.
화면에 구현되어야 하는 모든 기능과 페이지들은 pages 디렉토리 안에 들어가야 한다.
하나씩 찬찬히 살펴보자

  • index.js : /로 시작하는 루트 디렉토리! 걍 메인이라고 보면 된다.
  • _app.js : 공통레이웃을 위한 공간이라는데.. 난 Layout.js를 따로 만들어놨는데 이거랑 같이 써야하나?
  • _document.js : index.html과 같은 역할. 온갖 script tag와 기타등등은 다 여기다가 저장쓰!
  • _error.js : 에러가 났을때 나오는 화면
  • next.config.js : path 설정 및 기타 등등 설정

난 material-ui와 Next.js를 함께 쓴 예시를 클론받아서 거기를 통해 _app.js와 _document.js 양식을 채워나갔다 ㅋㅋ src 디렉토리의 Link, theme,ProTip도 무슨 기능을 하는진 모르겠으나 일단 추가해보았다. 그래야 에러가 안 날거같아ㅓ ㅋㅋㅋ

static 폴더의 위치

와… 엄청난 통수를 맞았던 static 폴더.
모든 게 다 pages 안에 들어가있어야 할 것 같아서 당연히 pages에 넣었는데
아무리 노력을 해봐도 이미지가 안 뜨는 것…

열심히 구글구글링을 해본 결과…
static 폴더는 root 경로에 있어야 한다고… pages와 동일 선상에..! 소오름
옮기니까 사진 바로 왕 크게 뜬다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 오예

Next.js에서 SASS 사용하기

yarn add @zeit/next-sass node-sass 설치는 이렇게
근데 설치한다고 다가 아니다.. 또 뭔갈 해줘야지 에러가 안난다.

const withSass = require('@zeit/next-sass');

const commonsChunkConfig = (config, test = /\.css$/) => {
  config.plugins = config.plugins.map((plugin) => {
    if (
      plugin.constructor.name === 'CommonsChunkPlugin'
      // disable filenameTemplate checks here because they never match
      // (plugin.filenameTemplate === 'commons.js' ||
      //     plugin.filenameTemplate === 'main.js')
      // do check for minChunks though, because this has to (should?) exist
      && plugin.minChunks != null
    ) {
      const defaultMinChunks = plugin.minChunks;
      plugin.minChunks = (module, count) => {
        if (module.resource && module.resource.match(test)) {
          return true;
        }
        return defaultMinChunks(module, count);
      };
    }
    return plugin;
  });
  return config;
};

module.exports = withSass({
  cssModules: true,
  webpack: (config) => {
    config = commonsChunkConfig(config, /\.(sass|scss|css)$/);
    return config;
  },
});

위의 폴더구조에서 살펴보았던 next.config.js 파일에 이걸 추가해준다.
추가해주지 않으면 CSSLoader 어쩌구 하면서 에러가 난다.
구글링의 힘이 정말 대단하다.. 다들 똑같은 데서 에러가 발생하는구나 정말ㅋㅋ

Layout 활용

사실 이 레이아웃 컴포넌트를 _app.js에 넣는게 맞는지, index.js에 넣는게 맞는지 모른다. 근데 일단 index.js에 넣어보았다.

import React from 'react';
import Container from '@material-ui/core/Container';
import Typography from '@material-ui/core/Typography';
import Box from '@material-ui/core/Box';
import MuiLink from '@material-ui/core/Link';
import ProTip from './src/ProTip';
import Link from './src/Link';
import Layout from './global/Layout';

function Copyright() {
  return (
    <Typography variant="body2" color="textSecondary" align="center">
      Copyright ©
      <MuiLink color="inherit" href="https://material-ui.com/">
        Your Website
      </MuiLink>
      {new Date().getFullYear()}
    </Typography>
  );
}

export default function Index() {
  return (
    <Layout>
      <Container maxWidth="sm">
        <Box my={4}>
          {/* variant가 화면에 보이는 실제 글씨 크기 */}
          <Typography variant="h4" component="h1" gutterBottom>
            Next.js example
          </Typography>
          <Link href="/about" color="secondary">
            Go to the about page
          </Link>
          <ProTip />
          <Copyright />
        </Box>
      </Container>
    </Layout>
  );
}

내가 실습을 나가있던 기업의 경우, material-ui를 사용하기 때문에
material-ui와 Next.js를 함께 쓴 예시를 깃허브를 통해 클론했다.
아마여기 였을듯

여튼.. Layout 파일에는

import Navbar from './Navbar';
import Footer from './Footer';
import './Footer.scss';

const Layout = (props) => (
  <>
    <Navbar />
    {props.children}
    <Footer />
  </>
);

export default Layout;

이렇게 해주면 신기하게 이 안에 요소들이 다 들어간다!

라잌 디스

image.png

넘나 신기한것ㅋㅋ

음… 뭔가 굉장히 많이 설치했던것 같은데 글로 써보니 얼마 없네..?
중간에 써놨던 글이 임시저장 실패해서 좀 날라간거 같기도 하고..?

bootstrap & material icon 사용

sudo yarn add bootstrap-material-design-icons 이걸 깔아봐도 아이콘이 안뜨고..

방법은 구글에 있었다. 이 문서에 나온대로 sudo yarn add material-design-icons 궈궈 _document.js 파일에 link tag도 넣어주고 <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />

그러나 에러가 발생…

image.png

바로 구글링 궈궈!
다양한 답변들이 있었지만 나는 이 방법을 택했다..

sudo yarn cache clean
sudo yarn install --network-concurrency 1

그랬더니 웬걸… 이제 된다 된다!??’

근데 아이콘은 잠시 보류.. 내가 원하는 아이콘이 아니였음..

SASS 적용 다시!

열심히 구글링 해서 config 파일을 다시 바꿈

const withSass = require('@zeit/next-sass');
const withCSS = require('@zeit/next-css');

module.exports = withCSS(
  withSass({
    webpack(config) {
      config.module.rules.push({
        test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 100000,
          },
        },
      });

      return config;
    },
  }),
);

드디어 SASS가 먹혀벌임!

bootstrap 적용

Layout에 이거 추가 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" />

진짜 진짜 이상한 에러

image.png

npm i -g npm@latest로 해결하긴 했는데 찝찝쓰~

아직도 어색한 Next.js… 언제쯤 친해질련지 이 글은 지속적으로 수정할 예정이다

다시한번 말하지만 이 글은 정답지가 아닌 삽질기!!