-
๐ฆ ์นํฉ(Webpack) 2 | ์นํฉ๊ณผ ๋ฐ๋ฒจ๋ก CRA ๊ตฌํํ๊ธฐwebpack 2021. 12. 12. 05:58
Creact-React-App
๋ฆฌ์กํธ์์๋ es6 ๋ฑ ์ต์ ๋ฌธ๋ฒ์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์นํฉ๊ณผ ๋ฐ๋ฒจ์ด ํ์ํ๋ค. ์นํฉ์ ํ์ผ๋ค์ ํ๋๋ก ๋ฌถ์ด ๋น๋์์ผ์ฃผ๊ธฐ ์ํด ํ์ํ๊ณ , ๋ฐ๋ฒจ์ ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ๋ ๊ตฌํ ๋ธ๋ผ์ฐ์ ์์ ์ ๋์ํ ์ ์๋๋ก ํด์ฃผ๊ธฐ ์ํด ํ์ํ๋ค.
ํ์ง๋ง create-react-app, CRA๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ๊ฐ๋ฐ ํ๊ฒฝ์ ์์์ ์ธํ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ์ฐ๋ฆฌ๊ฐ ์นํฉ๊ณผ ๋ฐ๋ฒจ ์ธํ ์ ํ์ง ์์๋ ๋๋ค.
CRA์์ด ์ง์ React ํ๋ก์ ํธ ์์ํ๊ธฐ
CRA๊ฐ ์๋๋๋ ์๋ฆฌ๋ฅผ ์๊ธฐ ์ํด CRA์์ด ์ง์ ๊ฐ๋ฐ ํ๊ฒฝ์ ๊ตฌ์ถํด๋ณด์.
1. ํ์ํ ํด๋, ํ์ผ๋ค ์์ฑํ๊ธฐ
์ง์ creact-react-app์ผ๋ก ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์์ํ๋ฉด ์๋์ ๊ฐ์ ํด๋ ๊ตฌ์กฐ๋ฅผ ๋ณผ ์ ์๋ค.
์ฌ๊ธฐ์ public ํด๋๋ ์ ์ ํ์ผ(html ๋ฑ)์ ์ํ ํด๋์ด๋ค. src๋ react javascript ์ฝ๋๋ค์ด ๋ค์ด๊ฐ ํด๋์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๋์ค์ build๋ฅผ ํ๊ฒ ๋๋ฉด dist๋ผ๋ ํด๋๊ฐ ์์ฑ๋๊ฒ ๋๋๋ฐ, distํด๋๋ ์นํฉ์ผ๋ก ๋ฒ๋ค๋ง ๋ ํ์ผ๋ค์ด ๋ค์ด๊ฐ๊ฒ ๋๋ค.
public, src, dist ํด๋ ์์ฑ
mkdir public src dist
public ํด๋ ์์ html ํ์ผ ์์ฑ
cd public touch index.html
src ํด๋ ์์ index.js ํ์ผ ์์ฑ
cd src touch index.js
2. ๊ฐ๋จํ ๋ฆฌ์กํธ ์ฝ๋ ์์ฑํ๊ธฐ
๊ทธ ์ ์ react์ react-dom์ install ํด์ผ ํ๋ค.
npm install react react-dom
react์ react-dom์ด ์ฑ๊ณต์ ์ผ๋ก package.json์ ์ถ๊ฐ๋์๋ค๋ฉด ์ด์ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์.
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>React App</title> </head> <body> <div id="root"></div> </body> </html>
index.js
import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render( <h1>hello world</h1>, document.getElementById('root') );
3. ์นํฉ ์ธํ ํ๊ธฐ
์นํฉ ์ค์ ํ๊ธฐ ์ ์ ์นํฉ์ install ํด์ฃผ์ด์ผ ํ๋ค(๊ฐ๋ฐํ๊ฒฝ์์๋ง ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ -D ์ต์ ์ถ๊ฐ).
npm install webpack webpack-cli webpack-dev-server -D
webpack์ ๊ธฐ๋ณธ webpack package๊ณ , webpack-cli๋ webpack์ ๋ช ๋ น์ด๋ก ์๋์ํฌ ์ ์๋๋ก ๋์์ฃผ๋ ๋๊ตฌ์ด๋ค. webpack-dev-server๋ ์ค์๊ฐ์ผ๋ก ํ๋ฉด์ ๋ฆฌ๋ก๋ ํด์ฃผ๋ ๋ก์ปฌ ์๋ฒ์ด๋ค.
์ด์ ์นํฉ ์ค์ ์ ํด์ฃผ์. ์นํฉ์ webpack.config.js ํ์ผ์์ ์ค์ ํด์ฃผ์ด์ผ ํ๋ค.
๋ฃจํธ ํด๋ ์๋์ webpack.config.js ํ์ผ์ ์์ฑํด์ฃผ์.
touch webpack.config.js
webpack.config.js
๋จผ์ mode์ devtool, resolve๋ฅผ ์ค์ ํด์ค๋ค.
const path = require('path'); module.exports = { mode : "development", devtool : 'eval', resolve : { extensions : ['.js', '.jsx', '.css'] }, }
- mode๋ production, development, none์ผ๋ก ์ด 3๊ฐ์ง๊ฐ ์๋ค. production๋ชจ๋๋ ์ค์ ๋ฐฐํฌ๋ฅผ ์งํํ ๋ ์ค์ ํด์ฃผ๋ฉด ๋๊ณ , ๊ฐ๋ฐ ํ๊ฒฝ์ผ ๋๋ development๋ก ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
- ๋ณดํต ๊ฐ๋ฐ ๋ชจ๋์์๋ devtool ์ค์ ์ eval๋ก ํ๋ค. eval๋ก ์ค์ ํ๋ฉด ์ฝ๋๊ฐ ๋๋ ํ๋๋ค.
- resolve.extensions ์ค์ ์ ํน์ ํ์ฅ์๋ง ๋น๋ํ๋ ๊ฒ์ด๋ค.
์ด์ entry point๋ฅผ ์ง์ ํด์ฃผ์ด์ผ ํ๋ค. entry๋ webpack ํํ ์ด๋ค ํ์ผ์ ์์์ผ๋ก ๋ฒ๋ค๋ง์ ํ ๊ฒ์ธ์ง ์๋ ค์ฃผ๋ ์ญํ ์ ํ๋ค.
const path = require('path'); module.exports = { mode : "development", devtool : 'eval', resolve : { extensions : ['.js', '.jsx', '.css'] }, entry : path.join(__dirname, "src", "index.js"), }
์์ ์ฝ๋๋ src ๋๋ ํ ๋ฆฌ ์์ index.js ํ์ผ์ ์์์ผ๋ก ๋ฒ๋ค๋ง์ ํ๋ผ๊ณ ์๋ ค์ฃผ๋ ์ฝ๋์ด๋ค.
webpack์ด ๋์๊ฐ๋ฉด์ webpack.config.js ํ์ผ์ ์ฝ๊ฒ ๋๋๋ฐ, index.js ํ์ผ์ ์์์ผ๋ก index.js ํ์ผ์ ์ฐ๊ฒฐ๋ ํ์ผ๋ค์ ๋ฒ๋ค๋งํด์ฃผ๊ฒ ๋๋ค.
์ด์ ์์์ ์ ์ง์ ํด์ฃผ์์ผ๋ ํ์ผ๋ค์ด ๋ฒ๋ค๋ง๋์ด output๋ path๋ฅผ ์ง์ ํด์ฃผ์ด์ผ ํ๋ค.
const path = require('path'); module.exports = { mode : "development", devtool : 'eval', resolve : { extensions : ['.js', '.jsx', '.css'] }, entry : path.join(__dirname, "src", "index.js"), output : { path: path.resolve(__dirname, "dist") } }
์์ ์ฝ๋๋ webpack์๊ฒ ๋ฒ๋ค๋ง ๋ ํ์ผ๋ค์ dist ํด๋ ์์ ๋ฃ์ด๋ฌ๋ผ๊ณ ์๋ ค์ฃผ๋ ์ฝ๋์ด๋ค.
html ํ์ผ์ด ๋ฒ๋ค๋ง ๋๊ธฐ ์ํด์๋ html-webpack-plugin์ด ํ์ํ๋ค.
npm install html-webpack-plugin -D
webpack.config.js ํ์ผ์ ํ๋ฌ๊ทธ์ธ ์ค์ ์ ์ถ๊ฐํด์ค๋ค.
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode : "development", devtool : 'eval', resolve : { extensions : ['.js', '.jsx', '.css'] }, entry : path.join(__dirname, "src", "index.js"), output : { path: path.resolve(__dirname, "dist") }, plugins : [ new HtmlWebpackPlugin({ template : path.join(__dirname, "public", "index.html") }) ], }
4. ๋ฐ๋ฒจ ์ธํ ํ๊ธฐ
์นํฉ์ผ๋ก ์์ค์ฝ๋๋ค์ ๋ฒ๋ค๋งํ๊ธฐ ์ ์ ๋ฐ๋ฒจ๋ก ๋จผ์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ๋ณํํด์ฃผ์ด์ผ ํ๋ค.
๋ฐ๋ฒจ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ @babel/core์ babel-loader, @babel/preset-react, @babel/preset-env ๋ฅผ ์ค์นํด์ผ ํ๋ค.
npm install @babel/core babel-loader @babel/preset-react @babel/preset-env
@babel/core๋ core transpiler(๋ณํ๊ธฐ)์ด๊ณ , babel-loader๋ webpack์์ babel์ ์ฌ์ฉํ ์ ์๋๋ก ๋์์ฃผ๋ ๋๊ตฌ์ด๋ค.
ํธ๋์คํ์ผ๋ง์ ํ ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ ์ด ์๋ ํ์ผ๋ค๋ ํธ๋์คํ์ผ๋ง์ ํด์ผํ๋ค.
@babel/preset-react๋ ๋ฆฌ์กํธ ์ฝ๋(jsx)๋ฅผ ํธ๋์คํ์ผ๋งํด์ฃผ๋ ๋๊ตฌ์ด๊ณ , @babel/preset-env๋ es6์ฝ๋๋ฅผ es5๋ก ํธ๋์คํ์ผ๋งํด์ฃผ๋ ๋๊ตฌ์ด๋ค.
์ด์ ์นํฉ์์ ๋ฐ๋ฒจ์ ์ฌ์ฉํ ์ ์๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํด์ฃผ์.
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode : "development", devtool : 'eval', resolve : { extensions : ['.js', '.jsx', '.css'] }, entry : path.join(__dirname, "src", "index.js"), output : { path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", options : { presets : ['@babel/preset-env', '@babel/preset-react'] } } }, ] }, plugins : [ new HtmlWebpackPlugin({ template : path.join(__dirname, "public", "index.html") }) ], }
์์ ์ฝ๋๋ webpack์๊ฒ ๋ง์ฝ .js, .jsx๋ก ๋๋๋ ํ์ฅ์๋ฅผ ๋ง๋๋ฉด babel-loader๋ก ๋จผ์ ๋ณํ์ ํ๊ณ ๋ฒ๋ค๋ง์ ํ๋ผ๊ณ ์๋ ค์ฃผ๋ ์ฝ๋์ด๋ค. ๊ทธ๋ฆฌ๊ณ options๋ก @babel/preset-env์ @babel/preset-react ๋ฅผ ์ถ๊ฐํด์ฃผ์๋ค.
5. ๋ก๋ ์ถ๊ฐํ๊ธฐ
์นํฉ์ ๊ธฐ๋ณธ์ ์ผ๋ก js, json ํ์ผ๋ง์ ๋ฒ๋ค๋งํ๊ธฐ ๋๋ฌธ์ css ํ์ผ, ์ด๋ฏธ์ง ํ์ผ๋ค์ ๋ฒ๋ค๋ง ํ๊ธฐ ์ํด์๋ loader๋ผ๋ ๊ฒ์ด ํ์ํ๋ค.
์๋ฅผ ๋ค์ด css ํ์ผ์ ๋ฒ๋ค๋งํ๊ธฐ ์ํด์๋ ์๋์ ๊ฐ์ด ๋ก๋๋ค์ install ํด์ฃผ์ด์ผ ํ๋ค.
npm i style-loader css-loader -D
๊ทธ๋ฆฌ๊ณ babel-loader ์ค์ ๊ณผ ๊ฐ์ด rules ์์ ์ค์ ์ ํด์ฃผ๋ฉด ๋๋ค.
webpack.config.js
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode : "development", devtool : 'eval', resolve : { extensions : ['.js', '.jsx', '.css'] }, entry : path.join(__dirname, "src", "index.js"), output : { path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", options : { presets : ['@babel/preset-env', '@babel/preset-react'] } } }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ] }, plugins : [ new HtmlWebpackPlugin({ template : path.join(__dirname, "public", "index.html") }) ], }
6. webpack-dev-server
webpack-dev-server๋ฅผ ์ฌ์ฉํ์ฌ ์ค์๊ฐ ๋ฆฌ๋ก๋ฉ์ ํ๊ธฐ ์ํด์๋ ์๋์ ์ฝ๋๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { mode : "development", devtool : 'eval', resolve : { extensions : ['.js', '.jsx', '.css'] }, entry : path.join(__dirname, "src", "index.js"), output : { path: path.resolve(__dirname, "dist") }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: "babel-loader", options : { presets : ['@babel/preset-env', '@babel/preset-react'] } } }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, ] }, plugins : [ new HtmlWebpackPlugin({ template : path.join(__dirname, "public", "index.html") }) ], devServer : { hot: true, port : 9090 } }
hot์ ๋ชจ๋ ๋ณํ๋ฅผ ์๋์ผ๋ก ๋ก๋ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๊ณ , port๋ ๋ก์ปฌ์์ ์๋ฒ๊ฐ ๊ตฌ๋๋ ๋ ์ฌ์ฉํ port ์ฃผ์์ด๋ค.
7. script ์ถ๊ฐ
์ด์ ๋ง์ง๋ง์ผ๋ก script์ ๋ช ๋ น์ด๋ฅผ ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
"scripts": { "dev": "webpack serve", "build": "webpack", ... }
npm run dev๋ฅผ ์ ๋ ฅํ๋ฉด, hello world๊ฐ ์ ์ถ๋ ฅ๋๊ณ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
npm run dev
[์ฐธ๊ณ ์๋ฃ]
Setup react with webpack and babel
Guide to setup react from scratch, without using create-react-app and by configuring webpack and babel manually.
medium.com
webpack
webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.
webpack.js.org
Babel · The compiler for next generation JavaScript
The compiler for next generation JavaScript
babeljs.io
'webpack' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ฆ ์นํฉ(Webpack) 1 | ์นํฉ์ ๊ฐ๋ , ๋ฒ๋ค๋ฌ(Bundler), ์นํฉ ์ฌ์ฉ๋ฐฉ๋ฒ (0) 2020.12.27