
웹 게임을 만들며 배우는 React에서 실습했던 내용을 토대로 다시 만들어보는 구구단 게임
npm init: 노드 프로그램 시작. 패키지 관리를 위한 package.json 생성npm i react react-dom: react, react-dom 설치npm i -D webpack webpack-cli: webpack, webpack-cli 개발 모드로 설치npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader: 바벨 설치npm i -D react-refresh @pmmmwh/react-refresh-webpack-plugin: 핫 리로딩을 위한 react-refresh 설치npm i -D webpack-dev-server: 개발용 서버 설치scripts 추가 "scripts": {
"start": "webpack serve --env development"
},
화면 로직과 직접적으로 상관이 있는
react관련 라이브러리는 배포용dependencies으로, 그렇지 않은 라이브러리는 개발용devDependencies로 설치
- 개발용 라이브러리는 빌드 후 코드에 포함되지 않는다.
entry - module - plugins - output
const RefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
module.exports = {
mode: 'development',
devtool: 'eval',
resolve: {
extensions: ['.js', '.jsx'],
},
entry: {
app: ['./index'],
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader', // use를 쓰면 options 못 씀 (babel.config.js 파일 생성해야 함)
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
},
},
],
},
plugins: [new RefreshWebpackPlugin()],
output: {
filename: 'bundle.js',
publicPath: '/',
},
devServer: {
publicPath: '/',
hot: true,
},
};
❓
require와import의 차이
require는 NodeJS에서 쓰는 CommonJS이고,import는 ES6 키워드module.exports와export도 같은 차이import로 특정 멤버만 가져올 수 있어서 효율적이다.
예)import { moduleFunc, moduleFunc2 } from module;
componentDidMount()를 쓰고 싶어서 찾아보니 Hooks에서는 useEffect()를 써야 한단다. (참고)import React, { useState, useRef, useEffect } from 'react';
import './Gugudan.css';
const Gugudan = () => {
const [first, setFirst] = useState(Math.ceil(Math.random() * 9));
const [second, setSecond] = useState(Math.ceil(Math.random() * 9));
const [value, setValue] = useState('');
const [result, setResult] = useState('🙄');
const [score, setScore] = useState(0);
const inputRef = useRef(null);
useEffect(() => {
inputRef.current.focus();
});
const onFormSubmit = (event) => {
event.preventDefault();
if (parseInt(value) === first * second) {
setResult('😊');
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue('');
setScore(score + 1);
} else {
setResult('🤔');
setValue('');
setScore(score - 1);
}
};
const onInputChange = (event) => {
setValue(event.target.value);
};
return (
<div className="gugudan">
<div className="score">Score: {score}</div>
<form onSubmit={onFormSubmit} className="gugudan-form">
<span className="question">
{first} x {second} ={' '}
</span>
<input
type="number"
ref={inputRef}
value={value}
onChange={onInputChange}
className="answer"
required
></input>
</form>
<div className="result">{result}</div>
</div>
);
};
export default Gugudan;
npm i -D css-loader style-loaderrules 추가{
test: /\.css$/,
use: ['style-loader', 'css-loader'], // 오른쪽부터 실행
},