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 //React, React-dom 불러오기
const React = require('react');
const ReactDom = require('react-dom');
jsx문법 사용 시 웬만하면 파일 확장자를 jsx로 쓰기
<!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>
//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;
const React = require('react');
const ReactDom = require('react-dom');
// 필요한 모듈 불러오기
const WordRelay = require('./WordRelay');
ReactDom.render(<WordRelay />, document.querySelector('#root'));
//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라는 것)
- webpack은 명령어로 등록이 안 되어있어서 터미널에서 오류 발생
1) webpack 명령어 등록을 해주기
2) package.json에 scripts로 등록 후npm run dev
"scripts": { "dev": "webpack" },
3) 터미널에
npx webpack
입력
👉 dist 디렉터리에 app.js 파일 생성됨
@babel/core
: babel 기본@babel/preset-env
: 브라우저에 맞게 이전 문법지원@babel/preset-react
: jsx 지원babel-loader
: babel과 webpack 연결//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'
}, // 출력
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'],
},
module.exports = {
mode: 'development',
entry: {
...
},
module: {
...
},
plugins: [
new webpack.LoaderOptionsPlugin({ debug: true }),
// options에 debug: true 넣어주기
],
output: {
...
},
};
mode, entry, module, plugins, output이 제일 중요!
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
넣기
npm i -D react-hot-loader
npm i -D webpack-dev-server
: webpack.config.js 읽어 build 후 유지"scripts": {
"dev": "webpack-dev-server --hot"
},
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'));
...
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',
],
},
}],
},
로컬호스트 서버를 이용해서 프론트엔트 프로그램을 돌릴 수 있음. 저장하는 순간 변경된게 자동으로 빌드 됨
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;