whatisthis?
220315 [TIL] Today I Learned ๐ฏ React.js - (2) ๋ณธ๋ฌธ
React.js
Day 03 React Hooks + WebPack
๐พ PART 1
* ์ง๊ธ๊น์ง์ ์ฝ๋
๐ webpack.config.js
const path = require("path");
module.exports = {
name: "wordrelay-setting",
mode: "development", // ์ค์๋น์ค์์ 'production'์ผ๋ก
devtool: "eval", // ๋น ๋ฅด๊ฒ
resolve: {
extensions: [".js", ".jsx"],
},
entry: {
app: ["./client.jsx", "WordRealy.jsx"],
},
output: {
path: path.join(__dirname, "dist"), //__dirname์ ํ์ฌํด๋๊ฒฝ๋ก
filename: "app.js",
},
};
์ฐธ๊ณ - devtool์ ๊ฐ๋ฐ์ ์ฉ์ดํ๊ฒ ํ๊ธฐ ์ํด ์์ค๋งต์ ์ ๊ณตํ๋ ์ต์ .
๋๋ ํ๋ ํ์ผ์ ์ค๋ฅ๊ฐ ์ด๋์์ ๋ฌ๋์ง ํ์ธ์ด ํ๋๋ฏ๋ก
์์ค๋งต์ ํตํด ํ์ธํ ์ ์๊ฒ ํด์ค๋ค.
๐ ์๋ ๊ธ์ ์ฐธ๊ณ ํด์ ํ์ด๋ณด์.
npx webpack
์ปค๋งจ๋๋ผ์ธ์ ๋ช ๋ น์ด๋ฅผ ์น๋ ค๋ฉด, ๋ฑ๋ก์ ํด์ค์ผํ๋ค.
๋ฐฉ๋ฒ 1 / ๋ช ๋ น์ด๋ก ๋ฑ๋ก
๋ฐฉ๋ฒ 2 / package.json์ "scripts" : {} ์์ ์ ๊ธฐ
"scripts": {
"dev": "webpack"
},
๋ฐฉ๋ฒ 3 / $npx webpack ์ด๋ผ๊ณ ์ ๋ ฅ
- ๐โ๏ธ ์ด ๋ฐฉ๋ฒ์ผ๋ก ํด๋ณด์!
Module parse failed: Unexpected token (6:16)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| const WordRelay = require("./WordRelay");
|
> ReactDom.render(<WordRelay />, document.querySelector("#root"));
|
๊ทธ๋ฌ๋ฉด ์ด๋ฐ์์ผ๋ก ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
๋์ถฉ ํด์ํ์๋ฉด,
" Module์ ์ฐพ๋๊ฑธ ์คํจํ๋ค
-> ์ด file ํ์ ์ ๋ค๋ฃจ๋ ค๋ฉด, ์ ์ ํ loder๊ฐ ํ์ํ๋ค. "
>> jsx๋ฅผ ํด์ํ ์ ์๋ ๋ฐ๋ฒจ ์ ํ ์ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋๊ฒ์.
๋ฐ๋ฒจ์ ์ค์นํ๋ค๊ณ ๋ฐ๋ก JSX๋ฅผ ์ธ ์ ์๋? >> โ
๋ฐ๋ฒจ ๋ด์์๋ ์ค์ ์ ํด์ค์ผ ํ๋ค.
1 / ํ์ํ ๋ฐ๋ฒจ ์ค์นํ๊ธฐ
$ npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader
- core : ๊ธฐ๋ณธ์ ์ธ ๊ฒ ํฌํจ
- preset-env : ๋ธ๋ผ์ฐ์ ์ ๋ง๊ฒ ์ต์ ๋ฌธ๋ฒ์ ์๋ ๋ฌธ๋ฒ์ผ๋ก ๋ฐ๊ฟ์ค
- preset-react : JSX๋ฅผ ์ธ ์ ์๊ฒ
- babel-loader : ๋ฐ๋ฒจ๊ณผ ์นํฉ ์ฐ๊ฒฐ
package.json ํ์ธ"devDependencies": { "@babel/core": "^7.17.7", "@babel/plugin-proposal-class-properties": "^7.16.7", "@babel/preset-env": "^7.16.11", "@babel/preset-react": "^7.16.7", "babel-loader": "^8.2.3", // ์๋ต }
2 / webpack.config.js ์์
module ๋ผ๋ ํ๋กํผํฐ ์ถ๊ฐ ํ,
rules ๋ผ๋ ๋ฐฐ์ด์์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ด์ค.module: { rules: [ { test: /\.jsx?/, // ์ ๊ทํํ์ -js๋ jsx loader: "babal-loader", options: { presets: ["@babel/preset-env", "@babel/preset-react"], }, }, ], },
test - ํ์ผ์ด js๋ jsx์ธ์ง ํ ์คํธํ๋ผ๋ ์๋ฏธ.
์ ๊ทํํ์์ผ๋ก ์์ฑํ๋๋ฐ, ์๋ ๋ฌธ์ ์ฐธ๊ณ .
loader - babel-loader์ ์ฐ๋ผ๋ ์๋ฏธ.
(cr: babelsjs.io)
๐โ๏ธ Using a Preset
Within a Babel config, if the preset is on npm, you can pass in the name of the preset and
Babel will check that it's installed in node_modules already.
This is added to the presets config option, which takes an array.
3 / ๋ค์ํ๋ฒ $ npx webpack ์ ๋ ฅํ๊ธฐ
๋๋์ด ์ ์์ ์ผ๋ก built ์๋ฃ ๐
๐ ์ ๊ทํํ์ ์ด๋?
/ / ์์ ์์ฑ.
\.๋ ์ด์ค์ผ์ดํ = "."์ ์๋ฏธํจ.
๐ป ์์
์ ํ๋ฒํธ๋ฅผ ์
๋ ฅ ํ "ํ์ธ" ๋ฒํผ์ ๋๋ฅด์ธ์.
###-####-####์ ํ์์ผ๋ก ์
๋ ฅํ์ธ์.
const form = document.querySelector('#form')
const input = document.querySelector('#phone')
const output = document.querySelector('#output')
const re = /^(?:\d{3}|\(\d{3}\))([-\/\.])\d{4}\1\d{4}$/
function testInfo(phoneInput) {
const ok = re.exec(phoneInput.value)
if (!ok) {
output.textContent = `ํ์์ ๋ง์ง ์๋ ์ ํ๋ฒํธ์
๋๋ค. (${phoneInput.value})`
} else {
output.textContent = `๊ฐ์ฌํฉ๋๋ค. ์ ํ๋ฒํธ๋ ${ok[0]} ์
๋๋ค.`
}
}
form.addEventListener('submit', (event) => {
event.preventDefault()
testInfo(input)
})
์นํฉ์ด ์ ๋น๋๋์๋์ง ํ ์คํธ ํ๊ธฐ ์ํด
WordRelay.jsx ํ์ผ์ ๊ณ ์ณ๋ณด์.
const React = require("react");
const { Component } = React;
class WordRelay extends Component {
state = {
text: "Hello Webpack",
};
render() {
return <h1>{this.state.text}</h1>;
}
}
module.exports = WordRelay;
+) ์ฐธ๊ณ ๋ก, app.js ๋ณด๋ฉด ์ฝ๋๊ฐ ์๋์ผ๋ก ์์ฑ๋์ด์์.
- ์นํฉ์ด client.jsx๋ WordRelay.jsx๋ฅผ ํฉ์ณ์ app.js ์์ ๋ด์ฉ์ ๋ง๋ ๊ฒ์!
์์ฉ ์์
- ์ง๋๋ฒ ์์ ์๋ ๊ตฌ๊ตฌ๋จ ๊ฒ์์ ์นํฉ์ผ๋ก ๋น๋ํด๋ณด์!
์ง๊ธ๊น์ง์ ๊ณผ์ ๋๋ก
1. npm init
2. npm i react, react-dom
3. npm i -D webpack webpack-cli
4. npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties
5. webpack.config.js ์ค์ ํ๊ธฐ
- name / mode / devtool
- resolve - extensions: .js, .jsx
- entry
app: "./client"
- module
test
loader
options - presets
- output
- path: path.join(__dirname, "dist")
- filename : 'app.js'
6. GuGuDan.jsx ์์ฑ
- ์ง๋๋ฒ์ ์์ฑํ๋ ๊ฒ ํ์ฅ์๋ช ๋ง ๋ฐ๊พธ๊ณ ,
- react require๋ก ๊ฐ์ ธ์ค๊ณ ,
- module.exports = GuGuDan
+) ์ฌ๊ธฐ์ React.useState์ React.useRef๋ฅผ ์ฌ์ฉํ๋ฏ๋ก
๊ตฌ์กฐ๋ถํด ๋ฌธ๋ฒ์ผ๋ก ๋์ ์ ์ธํด์ค.
>> ์๋ ๋ณธ๋ฌธ์์
const [first, setFirst] = React.useState(''); ์ด๋ฐ์์ผ๋ก ์จ์ฃผ๋๊ฑธ
const [first, setFirst] = useState(''); ๋ผ๊ณ ๋ง ํด์ค๋ ๋๋ค.
const React = require("react");
const { useState, useRef } = React;
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("");
let inputRef = useRef(null);
const onFormSubmit = e => {
e.preventDefault();
if (parseInt(value) === first * second) {
setResult(prevResult => {
return "์ ๋ต์
๋๋ค! " + value;
});
setFirst(Math.ceil(Math.random() * 9));
setSecond(Math.ceil(Math.random() * 9));
setValue("");
inputRef.current.focus();
} else {
setResult("โ ์ค๋ต์
๋๋ค");
setValue("");
inputRef.current.focus();
}
};
const onInputChange = e => {
setValue(e.target.value);
};
return (
<>
<h1>๐ฏ๊ตฌ๊ตฌ๋จ ๊ฒ์๐ฏ</h1>
<div>
๐ {first} ๊ณฑํ๊ธฐ {second} ๋?
</div>
<form onSubmit={onFormSubmit}>
<input
ref={inputRef}
type="number"
required
placeholder="์ ๋ต ์
๋ ฅ"
value={value}
onChange={onInputChange}
/>
<button type="submit">์
๋ ฅ</button>
</form>
<div>{result}</div>
</>
);
};
module.exports = GuGuDan;
7. ์ด์ $npx webpack์ด๋ผ๊ณ ์น๊ฑฐ๋, package.json์์ scripts ๋ถ๋ถ์
"scripts": {
"dev": "webpack"
},
์์๊ฐ์ด ์ ์ธํ์ผ๋ฏ๋ก,
$npm run dev ๋ผ๊ณ ์ณ๋ ๋๋ค.
์ฐธ๊ณ - ๋ ๋น์ฐํ ./dist/app.js๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๊ณ (๋นํ์ผ)
npx webpack์ ํ๋๋ฐ, ๊ทธ๋ฅ ์๋์ผ๋ก ์์ฑ๋๋ค.
๐ ๋๋ ํฐ๋ฆฌ ๊ตฌ์กฐ
index.html์ ๋ฐ๋์ ์์ด์ผํ๊ณ
client.jsx๋ ์ํธ๋ฆฌ์ฉ. (entry๋ ๋ณดํต client.jsx๋ก)
๊ทธ๋ฆฌ๊ณ ./dist/app.js๋ output์ฉ.
๋ชจ๋ jsxํ์ผ์ ํฉ์ณ์ app.js๋ฅผ ๋ง๋ค๊ณ ,
๊ทธ๊ฑธ index.html์ script:src๋ก ์ฐ๊ฒฐํ์.
์ฐธ๊ณ
๐ง webpack.config.js
module: {
rules: [
{
test: /\.jsx?/,
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
],
},
์ด๋ถ๋ถ์ ๋ณด๋ฉด,
loader๊ฐ babel-loader์ด๊ณ , ๊ทธ์ ํด๋นํ๋ options๊ฐ presets ๋ถ๋ถ์ ํด๋นํ๋ค.
๋ง์ฝ, @babel/preset-env์ ๋ํ ์ค์ ์ด ๋ ํ์ํ๋ค๋ฉด??
** preset์ด๋, ํ๋ฌ๊ทธ์ธ๋ค์ ๋ชจ์์ด๋ค.
options: {
presets: [
[
"@babel/preset-env", {
targets: {
browsers: ["last 2 chrome versions"],
},
debug: true,
],
"@babel/preset-react",
],
},
์ด๋ฐ์์ผ๋ก ํด๋น preset์ ๋ฐฐ์ด๋ก ๊ฐ์ธ์ฃผ๊ณ ,
์ฒซ๋ฒ์งธ ์์๋ก๋ ์ด๋ฆ์ ์ ์ด์ฃผ๊ณ
๋๋ฒ์งธ ์์๋ก option์ ์ ์ด์ฃผ๋ฉด ๋๋ค.
์ฌ๊ธฐ์๋ preset-env์ ์ต์ ์ค ํ๋๋ก, target - browser์ ์ด์ฉํ๋ค.
(ํฌ๋กฌ์ ์ต์ 2๋ฒ์ ๊น์ง๋ง ํธํ๋๋๋ก)
๐ป [์ฐธ๊ณ ] ๋ธ๋ผ์ฐ์ ๋ฆฌ์คํธ (target)
์ถ๊ฐ๋ก, plugins๋
module์ option์ preset๊ณผ ํจ๊ป ์ผ์๋๋ฐ,
plugins: [new webpack.LoaderOptionsPlugin({ debug: true })],
์ด๋ฐ์์ผ๋ก ๋จ๋ ์ผ๋ก ์จ๋ ๋๋ค.
module.exports = {
mode: "development", // ์ค์๋น์ค์์ 'production'์ผ๋ก
devtool: "eval", // ๋น ๋ฅด๊ฒ
resolve: {
extensions: [".js", ".jsx"],
},
entry: {
app: ["./client"],
},
module: {
rules: [
{
// ์๋ต
},
plugins: [new webpack.LoaderOptionsPlugin({ debug: true })], // ๐๐ ์ด ์์น์
output: {
path: path.join(__dirname, "dist"),
filename: "app.js",
},
};
- ์ฐธ๊ณ ๋ก, webpack์ LoaderOptions์ plugin์ ์ ๋ถ debug๋ฅผ true๋ฅผ ์ฃผ๋๊ฒ์.
const { webpack } = require("webpack");
+)
์๋์ผ๋ก ์ด๋ ๊ฒ webpack์ ๋ถ๋ฌ์ค๋ ์ฝ๋๊ฐ ์์ฑ๋๋ค.
(new webpack ๋ถ๋ถ ์ฃผ๋ชฉ)
* ์ง๊ธ๊น์ง์ ์ฝ๋
๐ webpack.config.js
const path = require("path");
const { webpack } = require("webpack");
module.exports = {
mode: "development", // ์ค์๋น์ค์์ 'production'์ผ๋ก
devtool: "eval", // ๋น ๋ฅด๊ฒ
resolve: {
extensions: [".js", ".jsx"],
},
entry: {
app: ["./client"],
},
module: {
rules: [
{
test: /\.jsx?/,
loader: "babel-loader",
options: {
presets: [
[
"@babel/preset-env",
{
targets: {
browsers: ["last 2 chrome versions"],
},
debug: true,
},
],
"@babel/preset-react",
],
},
},
],
},
output: {
path: path.join(__dirname, "dist"),
filename: "app.js",
},
};
์ฐธ๊ณ - LoaderOptionsPlugin ์ด๋ถ๋ถ์ด ์๋ฌ๊ฐ ๋์
(์๋ง ์นํฉ ๋ฒ์ ํธํ์ฑ ๋ฌธ์ ์ธ๋ฏ)
๊ทธ๋ฅ ๋นผ๋ฒ๋ฆฌ๋ผ๊ณ ํด์ ๋บ๋ค.
+)
$ npm run dev ํด๋ณด๋ฉด ์ด๋ฐ์์ผ๋ก ๋ฌ๋ค
@babel/preset-env: `DEBUG` option
Using targets:
{
"chrome": "98"
}
Webpack ๊ณต์ Doc.
์นํฉ์ด ๊ฐ์กฐํ ๊ฐ๋ ์ ํฌ๊ฒ ๋ค์ฏ๊ฐ์ง.
- entry
- output
- loaders
- plugins
- mode
โ ์นํฉ ์ค์ ์์ฑํ ๋ TIP
entry - module - plugins - output ์์ผ๋ก ์์ฑํ๋ฉด ์ฌ์.
(ํ๋ฆ์ ๋ฐ๋ผ์)
entry์ ์๋ ํ์ผ์ module ์ ์ฉํ๊ณ , plugin๋ ์ถ๊ฐ์ ์ผ๋ก ์ ์ฉํ๊ณ
output์ผ๋ก ๋์ด.
'WEB STUDY > REACT' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
220317 [TIL] Today I Learned ๐ฏ React.js (0) | 2022.03.17 |
---|---|
220316 [TIL] Today I Learned ๐ฏ React.js (0) | 2022.03.16 |
220315 [TIL] Today I Learned ๐ฏ React.js - (1) (0) | 2022.03.15 |
220314 [TIL] Today I Learned ๐ฏ React.js (0) | 2022.03.14 |
220313 [TIL] Today I Learned ๐ฏ React.js (0) | 2022.03.13 |