[React] 웹 게임-2 끝말잇기

ji_silver·2020년 7월 17일
0

[React] 웹 게임

목록 보기
2/8
post-thumbnail

1. 웹팩 설치하기

  • create-react-app으로 자동 설치 가능
  • 터미널 실행 후 npm init: package.json 파일 생성
  • npm i react react-dom: npm이 react, react-dom 설치
  • npm i -D webpack webpack-cli: webpack, webpack-cli 설치
    -D: 개발할 때만 사용한다는 의미. 실제 서비스 할 땐 webpack 필요 x
  • 👉실제 서비스에서는 dependencies 기록
    개발에만 쓰이는 것들은 devDependencies 에 기록

client.jsx

//React, React-dom 불러오기
const React = require('react');
const ReactDom = require('react-dom');

jsx문법 사용 시 웬만하면 파일 확장자를 jsx로 쓰기

index.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>끝말잇기</title>
</head>
<body>
    <div id="root"></div>
    <script src="./dist/app.js"></script>
</body>
</html>

2. 모듈 시스템과 웹팩 설정

WordRelay.jsx

//npm에서 react를 불러오기
const React = require('react');
const { Component } = require('react');

class WordRelay extends Component {
    state = {
        text: 'Hello, webpack'
    };
    render() {
        return <h1>{this.state.text}</h1>;
    }
}
//컴포넌트를 바깥에서도 사용할 수 있는 코드
module.exports = WordRelay;

client.jsx

const React = require('react');
const ReactDom = require('react-dom');

// 필요한 모듈 불러오기
const WordRelay = require('./WordRelay');

ReactDom.render(<WordRelay />, document.querySelector('#root'));

webpack.config.js

//webpack은 webpack.config.js 모든게 돌아감
const path = require('path');

module.exports = {
    name: 'wordrelay-setting',
    mode: 'development', // 실서비스: production
    devtool: 'eval', // 빠르게
    resolve: {
        extensions: ['.js', '.jsx']
    },

    entry: {
        app: ['./client']
    }, // 입력
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'app.js'
    }, // 출력
};
  • path.join: 경로를 함쳐줌
  • __dirname: 현재 폴더 (현재 폴더가 dist라는 것)
    👉 client.jsx 와 WordRelay.jsx를 합쳐 app.js 파일 생성

3. 웹팩으로 빌드하기

  • webpack은 명령어로 등록이 안 되어있어서 터미널에서 오류 발생
    1) webpack 명령어 등록을 해주기
    2) package.json에 scripts로 등록 후 npm run dev
"scripts": {
    "dev": "webpack"
},

3) 터미널에 npx webpack 입력
👉 dist 디렉터리에 app.js 파일 생성됨

1) babel 설치

  • npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader @babel/plugin-proposal-class-properties
    - @babel/core: babel 기본
    - @babel/preset-env: 브라우저에 맞게 이전 문법지원
    - @babel/preset-react: jsx 지원
    - babel-loader: babel과 webpack 연결

2) babel, webpack 연결

webpack.config.js

//entry파일 읽고 module 적용 후 output으로 출력

entry: {
    app: ['./client']
}, // 입력

module: {
    rules: [{ // 여러개의 규칙 적용할 수 있기 때문에 배열
        test: /\.jsx?/, // 정규표현식. js, jsx파일에 rule 적용(babel)
        loader: 'babel-loader', 
        options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: ['@babel/plugin-proposal-class-properties'],
        },
    }],
},

output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js'
}, // 출력

4. @babel/preset-env와 plugins

1) @babel/preset-env

  • presets: plugin들의 모음
  • @babel/preset-env: 이전 브라우저 자동 지원
  • browserslist 옵션들 참고

webpack.config.js

options: {
    presets: [
        ['@babel/preset-env', {
            target: {
                browsers: ['> 5% in KR', 'last 2 chrome versions'],
                // 한국에서 브라우저 점유율이 5% 이상인 브라우저는 지원
                // chrome의 최신버전 2가지만 호환되게, 모든 브라우저를 호환하면 babel의 작업량이 늘어나서 느려짐 
            },
            debug: true,
        }],
        '@babel/preset-react'
    ],
    plugins: ['@babel/plugin-proposal-class-properties'],
},

2) plugins

module.exports = {
    mode: 'development',
    entry: {
      ...
    },
    module: {
      ...
    },
    plugins: [
        new webpack.LoaderOptionsPlugin({ debug: true }),
      // options에 debug: true 넣어주기
    ],
    output: {
      ...
    },
};

mode, entry, module, plugins, output이 제일 중요!

5. 끝말잇기 class 만들기

WordRelay.jsx

const React = require('react');
const { Component } = require('react');

class WordRelay extends Component {
    state = {
        word: '제로초',
        value: '',
        result: '',
    };

    onSubmitForm = (e) => {
        e.preventDefault();
        if (this.state.word[this.state.word.length - 1] === this.state.value[0]) {
            this.setState({
                result: '딩동댕',
                word: this.state.value,
                value: '',
            });
            this.input.focus();
        } else {
            this.setState({
                result: '땡',
                value: '',
            });
            this.input.focus();
        }
    };

    onChangeInput = (e) => {
        this.setState({
            value: e.target.value
        });
    };

    input; // this.input 생성

    onRefInput = (c) => {
        this.input = c;
    };

    render() {
        return (
            <>
                <div>{this.state.word}</div>
                <form onSubmit={this.onSubmitForm}>
                    <input ref={this.onRefInput} value={this.state.value} onChange={this.onChangeInput} />
                    <button>입력!</button>
                </form>
                <div>{this.state.result}</div>
            </>
        );
    }
}

module.exports = WordRelay;

input에 value, onChange는 세트. 아니면 defaultValue 넣기

6. webpack-dev-server와 hot-loader

  • npm i -D react-hot-loader
  • npm i -D webpack-dev-server: webpack.config.js 읽어 build 후 유지
"scripts": {
    "dev": "webpack-dev-server --hot"
 },

client.jsx

const React = require('react');
const ReactDom = require('react-dom');
const { hot } = require('react-hot-loader/root');

const WordRelay = require('./WordRelay');

const Hot = hot(WordRelay);

ReactDom.render(<Hot />, document.querySelector('#root'));

webpack.config.js

...
module: {
    rules: [{
        test: /\.jsx?/,
        loader: 'babel-loader',
        options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: [
                '@babel/plugin-proposal-class-properties','react-hot-loader/babel',
            ],
        },
    }],
},

로컬호스트 서버를 이용해서 프론트엔트 프로그램을 돌릴 수 있음. 저장하는 순간 변경된게 자동으로 빌드 됨

7. 끝말잇기 Hooks로 전환하기

WordRelay.jsx

const React = require('react');
const { useState, useRef } = require('react');

const WordRelay = () => {
    const [word, setWord] = useState('지은');
    const [value, setValue] = useState('');
    const [result, setResult] = useState('');
    const inputRef = useRef(null);

    const onSubmitForm = (e) => {
        e.preventDefault();
        if (word[word.length - 1] === value[0]) {
            setResult('딩동댕');
            setWord(value);
            setValue('');
            inputRef.current.focus();
        } else {
            setResult('땡');
            setValue('');
            inputRef.current.focus();
        }
    };

    const onChangeInput = (e) => {
        setValue(e.target.value);
    };

    return (
        <>
            <div>{word}</div>
            <form onSubmit={onSubmitForm}>
                <input ref={inputRef} value={value} onChange={onChangeInput} />
                <button>입력!</button>
            </form>
            <div>{result}</div>
        </>
    );

};

module.exports = WordRelay;

profile
🚧개발중🚧

0개의 댓글