React 기본 학습 -3. webpack-dev-server 와 핫리로딩 - 끝말잇기 예제
리액트 강좌를 보면서 학습한 내용 정리용.
webpack-dev-server 와 핫리로딩 - 끝말잇기 예제
핫리로딩에 필요한 패키지
- @pmmmwh/react-refresh-webpack-plugin
- react-refresh/babel
리로딩과 핫리로딩의 차이점
- 리로딩 : 새로고침(=브라우저 새로고침)
- 핫리로딩 : 기존데이터 유지하면서 화면을 바꿔줌
webpack.config.js
const path = require('path');
const webpack = require('webpack');
const RefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
module.exports = {
name: 'wordrelay-setting',
mode: 'development', // 실서비스: production
devtool: 'eval',
resolve: {
extensions: ['.js', '.jsx']
},
entry: {
app: ['./client'],
}, // 입력
module: {
rules: [{
test: /\.jsx?/,
loader: 'babel-loader',
options: {
presets: [
// preset 에 상세 옵션 줄때 아래와 같이 설정 가능
['@babel/preset-env', {
targets: {
browsers: ['> 5% in KR'], // 한국에서 점유율 5% 이상 브라우저에 대응
},
debug: true,
}], '@babel/preset-react'], // plugin 들의 모음이 preset 임.
plugins: [
'@babel/plugin-proposal-class-properties',
'react-refresh/babel'
]
},
}],
},
plugins: [
new webpack.LoaderOptionsPlugin({ debug: true }),
new RefreshWebpackPlugin(),
], // 추가적으로 붙이고 싶은 것들이 있으면 여기
output: {
// path 와 publicPath 의 차이
// path는 실제경로. publicPath 는 가상의 경로(상대경로)
path: path.join(__dirname, 'dist'), // path.join 은 현재폴더 경로 + dist 를 반환함
filename: 'app.js',
publicPath: '/dist/', // publicPath 는 node의 express.static 과 비슷
}, // 출력
devServer: {
publicPath: '/dist/',
hot: true // 핫리로딩 - 변경점 감지
},
};
- plugin 들의 모음이 preset 임.
package.json
{
"name": "lecture",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack serve --env development"
},
"author": "",
"license": "ISC",
"dependencies": {
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/preset-env": "^7.12.1",
"@babel/preset-react": "^7.12.5",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
"babel-loader": "^8.2.1",
"react-refresh": "^0.9.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
}
}
client.jsx
const React = require('react'); // require는 node의 모듈 시스템
const ReactDom = require('react-dom');
const WordRelay = require('./WordRelay');
ReactDom.render(<div><WordRelay/></div>, document.querySelector('#root'));
WordRelay.jsx (Class 로 기입한 경우)
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.currentTarget.value });
};
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;
WordRelay.jsx (Hooks 로 기입한 경우)
const React = require('react');
const { useState, useRef } = React;
// 이와같이 const { xxx } = React; 이런건 구조분해 문법이라 불림.
// exports 되는게 객체나 배열이면 구조 분해할 수 있음.
const WordRelay = () => {
const [word, setWord] = useState('마이티');
const [value, setValue] = useState('');
const [result, setResult] = useState('');
const inputRef = useRef(null);
// Class 메소드들은 hooks 로 기입할 경우 더이상 클래스가 아니기때문에 따로 변수로 선언해 주어야 함.
// hooks에서는 ref 에서는 항상 current 를 붙여줘야 함. (예) inputRef.current.focus(); )
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.currentTarget.value);
};
// hooks는 render 없이 바로 리턴
// hooks 를 쓰게 되면 더이상 this 를 사용하지 않음(예) this.state.value)
return (
<>
<div>{word}</div>
<form onSubmit={onSubmitForm}>
<input ref={inputRef} value={value} onChange={onChangeInput} />
<button>입력!!!!</button>
</form>
<div>{result}</div>
</>);
}
module.exports = WordRelay;
GitHub : React-Study-1/2.끝말잇기/