React

[JSCODE] React 2회차 심화미션

sangchu 2023. 2. 14. 15:36

미션1 : CRA를 사용하지 않고 리액트 프로젝트를 만들어보세요.

1. Node.js가 있는지 확인

아래 명령어를 통해 Node.js가 있는지 확인한다.

node -v

 

2. package.json 생성

npm init -y

-y는 yes라는 의미다.

처음에 폴더명을 한글로 했더니 에러가 나서 영어로 고쳐줬다. 한글로 작성하면 안되나 보다.

해당 명령어를 입력하면 기본적인 세팅이 되어있는 package.js 파일이 생성된다.

 

3. webpack 설치

npm install --save-dev webpack
npm install --save-dev webpack-cli
npm install --save-dev webpack-dev-server

위 명령어를 입력하면 package.json에 다음과 같은 코드가 생성된다.

그리고 package-lock.json파일과 node_modules 파일이 생성됐다.

 

4. react 설치

npm install react react-dom

위 명령어를 입력하면 package.json에 다음과 같은 코드가 생성된다.

 

5. babel 설치

npm install --save-dev babel-loader @babel/preset-env @babel/core @babel/plugin-transfrom-runtime @babel/preset-react babel-eslint @babel/runtime

위 명령어를 입력하면 package.json에 다음과 같은 코드가 생성된다.

 

6. .babelrc 파일 생성

해당 파일을 생성하고 다음 코드를 넣는다.

{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": ["@babel/plugin-transform-runtime"]
}

 

7. webpack.config.json 파일 생성

해당 파일을 생성하고 다음 코드를 넣는다.

const path = require("path");

module.exports = {
  mode: "development",
  entry: "./index.js",
  output: {
    path: path.resolve(__dirname, "public"),
    filename: "main.js",
  },

  target: "web",
  devServer: {
    port: "3000",
    static: ["./public"],
    open: true,
    hot: true,
    liveReload: true,
  },
  resolve: {
    extensions: [".js", ".jsx", ".json", ".ts"],
  },
  module: {
    rules: [
      {
        test: /\\.(js|jsx)$/,
        exclude: /node_modules/,
        use: "babel-loader",
      },
    ],
  },
};

 

8. package.json에 npm 서버 구동, build하는 scripts 작성하기

 

9. public , src폴더 생성

public 폴더엔 index.html 파일 생성한다.

npm run build 명령어 를 하면 main.js 파일이 생성되므로 html에 넣어준다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React</title>
  </head>
  <body>
    <div id="root"></div>
    <script src="main.js"></script>
  </body>
</html>

 

src 폴더엔 index.js, App.js 파일 생성한다.

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.querySelector("#root"));

폴더 경로를 바꿨으니 package.json와 webpack.config.js에서 entry경로에 맞게 수정해야 한다.

 

10. 미션 코드 작성하기

이번 미션에서는 css를 작성하는데 참고한 자료에서는 css를 사용을 안해서 위 과정에는 css 웹팩 설정이 안되어있다. 그래서 다음과 같은 과정으로 추가했다.

npm i style-loader css-loader -D

위 명령어를 입력 후  webpack.config.js에 아래 코드를 넣었다.

// CSS 파일 로더 설정
      {
        test: /\\.css$/i,
        use: ['style-loader', 'css-loader']
      }

npm start를 하면 위에서 설정을 다 했으므로 서버 구동이 잘 된다.

 

 

 

미션2 : 새로운 css 프레임워크를 도입

styled-components를 이용했다.(이는 emotion 프레임워크와 비슷하다고 하다)

자바스크립트 파일 안에 스타일을 선언하는 방식이다. 그래서 css파일을 따로 만들지 않아도 된다.

스타일링된 엘리먼트를 만들 때는 컴포넌트 파일의 상단에 styled를 import하고 styled.태그명을 사용해서 구현한다.

styled.태그명 뒤에 템플릿 리터럴 문법을 통해 스타일을 넣어주면, 해당 스타일이 적용된 리액트 컴포넌트가 생성된다.

전역 스타일의 경우 createGlobalStyle을 이용해 설정할 수 있다.

 

코드

InputGroup.js

import styled from "styled-components";

const Title = styled.div`
  margin-top: 15px;
`;

const Essential = styled.span`
  margin-left: 5px;
  font-size: 13px;
`;

const Aster = styled.span`
  color: red;
`;

const Input = styled.input`
  padding: 14px 25px;
  border-radius: 5px;
  border: 1px solid lightgray;
  ::-webkit-outer-spin-button,
  ::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
`;

const InputGroup = (props) => {
  const { label, name, type, text, isRequired } = props;
  return (
    <>
      <Title>
        <label for={label}>{name}</label>
        <Essential>
          {isRequired ? (
            <sup>
              필수 <Aster>*</Aster>
            </sup>
          ) : null}
        </Essential>
      </Title>
      <Input
        type={type}
        id={label}
        placeholder={text}
        required={isRequired ? "required" : null}
      />
    </>
  );
};

export default InputGroup;

App.js

import styled from "styled-components";
import InputGroup from "./InputGroup";
import GlobalStyle from "./GlobalStyles";

const Form = styled.form`
  display: flex;
  flex-direction: column;
`;

const Header = styled.h1`
  margin: 10px auto;
`;

const Button = styled.button`
  margin-top: 40px;
  padding: 14px;
  border-radius: 30px;
  border: none;
  background-color: #1889e6;
  color: white;
  font-size: 15px;
  font-weight: bold;
`;

const App = () => {
  return (
    <>
      <GlobalStyle />
      <Form action="#">
        <Header>회원가입</Header>
        <InputGroup
          name="이메일"
          type="email"
          text="이메일을 입력하세요"
          label="email"
          isRequired="true"
        />
        <InputGroup
          name="비밀번호"
          type="password"
          text="비밀번호을 입력하세요"
          label="password"
          isRequired="true"
        />
        <InputGroup
          name="비밀번호 재확인"
          type="password"
          text="비밀번호을 입력하세요"
          label="re-password"
          isRequired="true"
        />
        <InputGroup
          name="이름"
          type="text"
          text="이름을 입력하세요"
          label="name"
          isRequired="true"
        />
        <InputGroup
          name="나이"
          type="number"
          text="나이를 입력하세요"
          label="age"
          isRequired={null}
        />
        <Button>가입하기</Button>
      </Form>
    </>
  );
};

export default App;

GlobalStyles.js

import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`

*{
    margin: 0;
    padding:0;
    box-sizing: border-box;
    }

body {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
}
`;

export default GlobalStyle;

 

마무리

미션1을 통해 package.json, Webpack 등을 직접 설정해보는 과정에서 CRA는 대강 이런식으로 만들어져 있겠구나를 느꼈다. 시간 상 해당 과정에서 코드 각각이 정확히 무슨 역할을 하는지 알아보지 못해서 아쉬웠다. css 웹팩 설정 방법을 찾는 과정에서 좀 더 알고싶어졌다. 시간이 될때 한번 찾아서 정리해봐야겠다.

 

미션2에서는 처음엔 멘토님이 tailwind-css 요즘 많이 쓰인다고 해서 찾아봤는데, 뭔가 스타일이 고정된 느낌을 받았고 추가할 때마다 class가 길어진다는 점에서 너무 어색해서 다른 방법을 찾았다. 부트스트랩이랑 비슷한 것 같은데, 이것도 이전에 잠깐 찍먹했다가 비슷한 이유로 쳐다보지 않았다.. 그래도 다음에 한번 찾아봐야겠다.. 

 

아직까지는 css 프레임워크의 필요성을 못느끼겠다. styled-components가 뭔가 css 문법과 비슷한 것 같아서 사용해봤는데 뭔가 js에 css코드가 있으니 구조화가 안된 느낌을 받았다. 각자의 코드는 각자 파일에 있어야 보기 좋지 않나.. 그래도 좀 더 공부해보면 이유를 아는 순간이 올 것이라 믿는다.

'React' 카테고리의 다른 글

state, setState  (0) 2023.02.18
[JSCODE] React 3회차 미션  (1) 2023.02.17
[JSCODE] React 2회차 미션  (2) 2023.02.14
React의 기본, JSX  (0) 2023.02.11
[JSCODE] React 1회차 미션  (1) 2023.02.10