์นํฉ์ด๋ ๋ชจ๋์ ์ํ ๋ฒ๋ค๋ฌ์ด๋ค. ๋ชจ๋์ด๋ import, export๊ฐ ๊ฐ๋ฅํ๋ฉฐ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋ ์กฐ๊ฐ์ด๋ฉฐ ๋ฒ๋ค๋ง์ด๋ js, css, asset ํ์ผ ๋ฑ์ ํ๋์ ํ์ผ๋ก ๋ฌถ์ด์ฃผ๋ ์์ ์ ์๋ฏธํ๋ค.
์นํฉ์ ๋ชจ๋ํ ๋๊ตฌ๋ก์ ๋ค์ํ ๋ก๋๋ฅผ ์ถ๊ฐํ ์ ์์ผ๋ฉฐ ์ฌ๋ฌ ๊ฐ์ ํ์ผ์ ํ๋๋ก ๋ฒ๋ค๋งํ๊ธฐ ๋๋ฌธ์ HTTP ์์ฒญ ํ์๋ฅผ ์ค์ผ ์ ์๋ค. ๋ํ ๋ค๋ฅธ ๋ฆฌ์์ค ํฌ๋งท์ ๋ชจ๋๋ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค
ํ ํ์ผ์ด ๋ค๋ฅธ ํ์ผ์ ํ์๋กํ๋ฉด ์นํฉ์ ์ด๊ฒ์ dependency๋ก ์ฒ๋ฆฌํ๋ฉฐ ์ด๋ฅผ ํตํด ์ด๋ฏธ์ง๋ ์น ํฐํธ์ ๊ฐ์ด ์ฝ๋๊ฐ ์๋ ๋ฆฌ์์ค๋ฅผ dependency๋ก ๊ด๋ฆฌํ ์ ์๊ฒ ํ๋ค.
์นํฉ์ ๋ฒ๋ค๋ง ์์ ์ dependency graph๋ฅผ ๊ทธ๋ฆฌ๋๋ฐ dependency graph๋ ์ ์๋ entry์์ ์ถ๋ฐํด ์ดํ๋ฆฌ์ผ์ด์ ์ ํ์ํ ๋ชจ๋์ ํฌํจํ๋ ๊ทธ๋ํ๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๋น๋ํ๋ค. ๊ทธ๋ํ๋ฅผ ์์ฑ์ํจ ํ ํ๋ ๋๋ ์์์ ๋ฒ๋ค๋ก ๋ฒ๋ค๋งํด ๋ธ๋ผ์ฐ์ ์ ๋ก๋ํ ์ค๋น๋ฅผ ๋๋ธ๋ค.
๋ค์์ ์นํฉ์ ์ดํดํ๋๋ฐ ํ์ํ ํต์ฌ ๊ฐ๋ ๋ค์ ๋ํ ์ค๋ช ์ด๋ค.
entry๋ dependency graph์ ์ถ๋ฐ์ ์ด๋ค. entry๋ฅผ ํตํด depency graph๊ฐ ๊ฐ์ฅ ๋จผ์ ํฌํจํ ๋ชจ๋์ ๊ฒฝ๋ก๋ฅผ ์ค์ ํ๋ค.
// webpack.config.js
module.exports = {
entry: './path/to/my/entry/file.js',
};
output์ ๋ฒ๋ค๋ง ์๋ฃ๋ ํ์ผ์ ๋ด๋ณด๋ผ ์์น๋ฅผ ์ง์ ํ๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก dist
๋๋ ํ ๋ฆฌ ํ์ ๊ฒฝ๋ก์ ์ ์ฅ๋๋ฉฐ ํ์ผ ์ด๋ฆ์ด๋ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ก ์ง์ ํ ์๋ ์๋ค.
clean
ํ๋กํผํฐ๋ฅผ true
๋ก ์ค์ ํ๋ฉด output ๊ฒฝ๋ก์ ๋๋ ํ ๋ฆฌ์ ์ฌ์ฉํ์ง ์๋ ํ์ผ์ ์๋์ผ๋ก ์ ๋ฆฌํ ์ ์๋ค.
// webpack.config.js
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'webpack-practice.bundle.js',
},
};
์นํฉ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฐ์คํฌ๋ฆฝํธ์ json ํ์ผ๋ง ์ดํดํ ์ ์๋ค. loader๋ ์๋ฐ์คํฌ๋ฆฝํธ์ json ํ์ผ์ด ์๋ ๋ค๋ฅธ ์ ํ์ ๋ฆฌ์์ค๋ค์ dependency graph์ ์ถ๊ฐํ ์ ์๋ ๋ชจ๋๋ก ๋ณํํ๋ ์ญํ ์ ํ๋ค.
v๋ก๋๋ test
์ use
ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๋๋ฐ, test
์๋ ํ์ผ์ ํ์์, use
์๋ test
์์ ์ง์ ํ ์ ํ์ ํ์ผ์ ๋ณํํ ๋ ์ฌ์ฉํ loader๋ฅผ ๋ช
์ํด์ผํ๋ค.
// webpack.config.js
const path = require('path');
module.exports = {
output: {
filename: 'webpack-practice.bundle.js',
},
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
};
loader๋ฅผ ์ค์ ํด์ฃผ๋ฉด ํ์ผ ์ ํ์ ์๊ด์์ด import๊ฐ ๊ฐ๋ฅํ๋ค.
loader๋ ํน์ ์ ํ์ ํ์ผ์ ๋ชจ๋๋ก ๋ณํํ๋ ์ญํ ์ ํ์ง๋ง plugin์ ๋ฒ๋ค ์ต์ ํ, asset ๊ด๋ฆฌ ๋ฐ ํ๊ฒฝ๋ณ์ ์ค์ ๋ฑ์ ์ฌ์ฉ๋๋ค.
plugin์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ plugin ํจํค์ง๋ฅผ import๋ requireํด ๊ฐ์ ธ์จ ๋ค์ plugins
ํ๋กํผํฐ์ ์ถ๊ฐํด์ผํ๋ค.
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
๋ค์์ create react app(cra) ์์ด ์นํฉ์ ๊ตฌ์ฑํ๋ ์์ ์ด๋ค.
cra๋ ์นํฉ๊ณผ ์นํฉ ๊ตฌ์ฑ ์์๋ค์ ์์ง ๋ชปํ๋๋ผ ๋ฆฌ์กํธ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋ฆฌ์กํธ ๊ฐ๋ฐ ํ๊ฒฝ์ ๊ตฌ์ถํด์ฃผ๋ ๋๊ตฌ์ด๋ค. ๊ทธ๋ฌ๋ cra๋ ์นํฉ ์ค์ ์ ์ ํํ๊ณ ๋ถํ์ํ dependency๋ค์ด ๋ง์ผ๋ฉฐ ํ๊ฒฝ ์ค์ ์ ์ฌ์ฉ์๊ฐ ์ง์ ์ ์ํ์ง ๋ชปํ๋ค๋ ๋จ์ ์ด ์๋ค.
๊ฐ์ฅย ๋จผ์ ์นํฉ ํจํค์ง๋ฅผ ์ค์นํด์ผํ๋ค.
npm install webpack
or
yarn add webpack
๋ค์์ผ๋ก ์นํฉ config ํ์ผ์ธ webpack.config.js
ํ์ผ์ ์์ฑํ๋ค.
webpack.config.js
ํ์ผ์์ mode
๋ฅผ development๋ก ์ค์ ํ๋ค.
// webpack.config.js
module.exports = {
mode: 'development',
};
yarn add --dev webpack-cli
์นํฉ cli ํจํค์ง๋ฅผ ์ค์นํ ํ ๋น๋ํ๋ฉด dist
๋๋ ํ ๋ฆฌ์ ๋ค์๊ณผ ๊ฐ์ ํ์ผ์ด ์คํ๋๋ค.
// src/index.js
const test = 'test';
// dist/main.js
(() => {
var __webpack_modules__ = {
'./src/index.js': () => {
eval(
"const test = 'test';\r\n\n\n//# sourceURL=webpack://webpack-practice/./src/index.js?"
);
},
};
var __webpack_exports__ = {};
__webpack_modules__['./src/index.js']();
})();
์นํฉ์ ๋ชจ๋ ๋ฒ๋ค๋ฆฌ์ด๋ค. ๋ค๋ฅธ ์ค์ ์ด ์์ผ๋ฉด src
๋๋ ํ ๋ฆฌ์ ์์ฑํ index.js
๋ฅผ ์ฌ์ฉํ๊ณ ๋ชจ๋ dependency๋ค์ ํ๋์ ํ์ผ ์ฆ, main.js
๋ก ๋ฒ๋ค๋งํ๋ค.
๋ค์์ ์ ์ฅ ๋ฐ ์๋ก๊ณ ์นจ ์์ด ๋ธ๋ผ์ฐ์ ์์ ์ฝ๋ ๋ณ๊ฒฝ์ ํ์ธํ๊ธฐ ์ํด webpack-server๋ฅผ ์ค์นํ๋ ๊ณผ์ ์ด๋ค.
yarn add --dev webpack-server webpack-dev-server
์์ ๊ฐ์ด ํจํค์ง ์ค์น ํ package.json
์คํฌ๋ฆฝํธ์ webpack serve ๋ช
๋ น์ ์ถ๊ฐํ๋ค
// package.json
"scripts": {
"start": "webpack serve"
},
์ด์ yarn์ ํตํด ์ฌ์ดํธ๋ฅผ ์ปดํ์ผ ๋ฐ serve ํ ์ ์๋ค.
index.html
์ ์์ฑํ๊ณ ๋ฒ๋ค๋ js ํ์ผ์ ์ถ๊ฐํ๊ธฐ ์ํด html-webpack-plugin์ ์ค์นํด์ผํ๋ค.
yarn add html-webpack-plugin
์ค์น ํ ํด๋น plugin์ ๊ฐ์ ธ์ ์นํฉ ์ค์ ํ์ผ์ ์ถ๊ฐํด์ค๋ค.
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const htmlWebpackPlugin = requrie('html-webpack-plugin');
module.exports = {
mode: 'development',
devServer: {
port: 8001,
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
์ด์ template
ํ๋กํผํฐ์ ์ง์ ๋ ๊ฒฝ๋ก์ ์์นํ html ํ์ผ์ ํ
ํ๋ฆฟ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
yarn start
์ปค๋งจ๋๋ก ๋น๋ ํ localhost:8001
์์ ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ํตํด source๋ฅผ ํ์ธํ๋ฉด index.html
ํ์ผ์์ script ํ๊ทธ๋ฅผ ์ค์ ํ์ง ์์์ง๋ง ํ๋ฌ๊ทธ์ธ์ ์ํด ์ถ๊ฐ๋์ด์์์ ํ์ธํ ์ ์๋ค.
๋ค์์ html ํ์ผ์ ํตํด ๋ธ๋ผ์ฐ์ ์ js ํ์ผ์ ๋ด์ฉ์ ํ์ํด์ผํ๋ค.
๋จผ์ index.html
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ค.
// index.html
...
<body>
<h1>This is a html file.</h1>
<div id="fromjs"></div>
</body>
...
index.js
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ค.
document.querySelector('#fromjs').innerHTML = `<h1>From index.js</h1>`;
๋ค์ย yarn์ ํตํด ๋น๋ํ๋ฉด "This is a html file."ย ์๋์ js ํ์ผ์ ํตํด ์ถ๊ฐํ "From index.js" ๋ด์ฉ์ด ์ถ๋ ฅ๋๋ค.
๋ค์๊ณผย ๊ฐ์ด ๋ฆฌ์กํธ ํจํค์ง๋ฅผ ์ค์นํ๋ค.
yarn add react react-dom --save
์ค์น ํ index.js
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ์ถ๊ฐํ๋ค.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render('Hello from index.js', document.querySelector('#fromjs'));
์ด์ ํฐ๋ฏธ๋์์ yarn start
์ปค๋งจ๋๋ฅผ ์
๋ ฅํ๋ฉด ReactDOM
์ ํตํด ๋ ๋ํ ์ปจํ
์ธ ๊ฐ ์ถ๋ ฅ๋๋ค.
๊ทธ๋ฌ๋ 'Hello from index.js'๊ฐ ์๋ <h1>Hello from index.js</h1>
๋ฅผ ์
๋ ฅํ ๊ฒฝ์ฐ ์ปดํ์ผ ๋์ง ์๋๋ค.
์ด๋ ํ์ํ ๊ฒ์ด ๋ฐ๋ก babel์ด๋ค.
ํธ๋์คํ์ผ์ด๋ ๋ค๋ฅธ ์ธ์ด๋ก ๋ณํ์ํค๋ ์์ ์ ์๋ฏธํ๋ค. babel์ ES6 ๋ฌธ๋ฒ์ผ๋ก ์์ฑ๋ ์ฝ๋๋ฅผ ES5 ๋ฌธ๋ฒ์ผ๋ก ํธ๋์คํ์ผํด์ฃผ๋ ํธ๋์คํ์ผ๋ฌ์ด๋ฉฐ babel-loader๋ babel๊ณผ ์นํฉ์ ์ฐ๊ฒฐ์์ผ์ฃผ๋ loader์ด๋ค.
๋ค์๊ณผ ๊ฐ์ด ํจํค์ง๋ฅผ ์ค์นํ๋ค.
yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react babel-loader
ํจํค์ง ์ค์น ํ webpack.config.js
ํ์ผ์ module
ํ๋กํผํฐ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ค.
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development',
devServer: {
port: 8001,
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react', '@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime'],
},
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
],
};
babel ์ค์น ๋ฐ babel-loader๋ฅผ ์นํฉ๊ณผ ์ฐ๊ฒฐํ๋ ์ค์ ์ ์๋ฃํ ํ์ index.js
ํ์ผ์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ค.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(<h1>Hello from js</h1>, document.querySelector('#fromjs'));
๋ค์์ CSS๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์นํฉ์ ์ถ๊ฐํ๋ ์์ ์ด๋ค.
๋จผ์ css-loader์ style-loader ํจํค์ง๋ฅผ ์ค์นํ๋ค.
yarn add css-loader style-loader
webpack.config.js
ํ์ผ์ moduel
ํ๋กํผํฐ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ค.
module: {
rules: [
{
test: /\.m?js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react', '@babel/preset-env'],
plugins: ['@babel/plugin-transform-runtime'],
},
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
์ด์ src
ํ์ ๊ฒฝ๋ก์ cssํ์ผ์ ์ถ๊ฐํ๊ณ index.js
์์ css ํ์ผ์ importํ๋ฉด ํ๋ก์ ํธ์ css ์คํ์ผ์ ์ ์ฉํ ์ ์๋ค.
// src/styles/style.css
* {
color: red;
}
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './styles/styles.css';
ReactDOM.render(<h1>Hello from js</h1>, document.querySelector('#fromjs'));
Reference