March 10, 2021
๋จผ์ Node.js๋ฅผ ์ค์นํด์ผ ํ๋ค.
์๋์ ๋ช ๋ น์ด๋ก node.js์ npm์ด ์ ์ค์น๋์๋์ง version์ ํ์ธํด๋ณผ ์ ์๋ค.
$ node -v
$ npm -v
์๋์ ๋ช ๋ น์ด๋ก npm์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐํํ ์ ์๋ค.
$ npm init -y
๊ทธ๋ฌ๋ฉด ์๋์ ๊ฐ์ ๋ด์ฉ์ ํฌํจํ package.json ํ์ผ์ด ์๋์ผ๋ก ์์ฑ๋๋ค.
{
"name": "ํ๋ก์ ํธ ์ด๋ฆ",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
์๋์ ๋ช ๋ น์ด๋ก npm ํน์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ ์ ์๋ค.
$ npm install {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ}
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น๊ฐ ์๋ฃ๋๋ฉด node_modules๋ผ๋ ํด๋๊ฐ ์์ฑ๋๊ณ ๊ทธ ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ค์น๋๋ค.
package.json ์ ์๋์ ๋ด์ฉ์ด ์ถ๊ฐ๋๋ค. ์๋ฅผ ๋ค์ด jquery
๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ์ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ด dependencies
์์ฑ์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ๊ณผ ์ค์น๋ ๋ฒ์ ์ด ์ถ๊ฐ๋๋ค.
"dependencies": {
"jquery": "^3.6.0"
}
๋ง์ฝ ๋ช
๋ น์ด ๋ค์ --save-dev
๋ฅผ ํจ๊ป ๋ถ์ฌ์ ์ค์นํ๋ค๋ฉด dependencies
๊ฐ ์๋๋ผ devDependencies
์์ฑ์ผ๋ก ์ถ๊ฐ๋๋ค.
์ค์น
dependencies
$ npm install {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ}
# or
$ npm i {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ}
devDependencies
$ npm install {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ} --save-dev
# or
$ npm i {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ} -D
์ ๊ฑฐ
$ npm uninstall {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ}
์ ์ญ ์ค์น
$ npm install {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ} --global
# or
$ npm install {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ} -g
์ด๋ ์์น์์ ํด๋น ๋ช ๋ น์ด๋ฅผ ์คํํ๋ ๊ทธ ์์น์ ์ค์น๊ฐ ๋๋ ๊ฒ์ด ์๋๋ผ ์๋์ ํด๋์ ์ค์น๋๋ค. (์์คํ ๋ ๋ฒจ์ ์ ์ญ์ผ๋ก ์ค์น๋๋ ๊ฒ)
# windows
%USERPROFILE%\AppData\Roaming\npm\node_modules
# macOS
/usr/local/lib/node_modules
dependencies
npm i {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ}
jQuery
๋ ํ๋ฉด์ DOM์ ์กฐ์ํ๊ธฐ ์ํ ์ ํธ์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ธฐ ๋๋ฌธ์ ๋ฐฐํฌ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค.react
, angular
, chart
devDependencies
npm i {๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ด๋ฆ} -D
webpack
, js-compression
, sass
๋ชจ๋ ๋ฒ๋ค๋ง : ๋ช์ญ, ๋ช๋ฐฑ๊ฐ์ ์์๋ค์ ํ๋์ ํ์ผ๋ก ํฉ์ณ์ค๋ค.
npm ์ด๊ธฐํ
$ npm init -y
webpack ์ค์น
$ npm i webpack webpack-cli -D
lodash ์ค์น (JS ์ ํธ๋ฆฌํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)
$ npm i lodash
index.html ์์ฑ
<html>
<head>
<title>Webpack Demo</title>
<script src="https://unpkg.com/lodash@4.16.6"></script>
</head>
<body>
<script src="src/index.js"></script>
</body>
</html>
src/index.js ์์ฑ
function component() {
var element = document.createElement('div');
/* lodash is required for the next line to work */
element.innerHTML = _.join(['Hello','webpack'], ' ');
return element;
}
document.body.appendChild(component());
์นํฉ ๋น๋ ๊ฒฐ๊ณผ๋ฌผ๋ก ์คํํ๊ธฐ ์ํด ์๋์ ๊ฐ์ด ์์
index.html
<html>
<head>
<title>Webpack Demo</title>
</head>
<body>
<script src="dist/main.js"></script>
</body>
</html>
src/index.js ์ lodash ๋ผ์ด๋ธ๋ฌ๋ฆฌ import ๋ฌธ ์ถ๊ฐ
import _ from 'lodash';
//...
์นํฉ ๋น๋ ๋ช ๋ น์ด๋ฅผ ์คํํ๊ธฐ ์ํด package.json ํ์ผ์ ์ปค์คํ ๋ช ๋ น์ด ์ถ๊ฐ
"scripts": {
//...
"build": "webpack"
}
npm run build
๋ช
๋ น์ด๋ฅผ ์คํํ๋ฉด dist ํด๋์ ๋ฒ๋ค๋ง ๊ฒฐ๊ณผ๋ฌผ์ด ์์ฑ๋๋ค.๋ฃจํธ ๊ฒฝ๋ก์ webpack.config.js ์ถ๊ฐ
// `webpack` command will pick up this config setup by default
var path = require('path');
module.exports = {
mode: 'none',
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist')
}
};
var path = require('path');
: node.js์ ๋ชจ๋ ๋ฌธ๋ฒ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค. path ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค๊ณ ์์ path
๋ผ๋ ๋ณ์์ ๋ด๋๋ค. ๊ทธ๋์ ์ด path
์ resolve
๋ผ๋ api ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ค.development
, production
, none
์ด 3๊ฐ์ง๋ก ์ง์ ํ ์ ์๋ค. none
์ ์ค์ ํ์ง ์์ผ๋ฉด ๋น๋ ๊ฒฐ๊ณผ๋ฌผ์ด ๋๋
ํ ๋์ด ๋์จ๋ค.๋น๋(๋ฒ๋ค๋ง) ๊ฒฐ๊ณผ๋ฌผ ๊ฒฝ๋ก ๋ณ๊ฒฝ ๋ฐฉ๋ฒ
๋ง์ฝ ์ด ํด๋ ๊ฒฝ๋ก์ ํ์ผ๋ช ์ public/output.js ์ ๊ฐ์ด ๋ณ๊ฒฝํ๊ณ ์ถ๋ค๋ฉด webpack.config.js ํ์ผ์์ ์๋์ ๊ฐ์ด ์์ ํด์ฃผ๋ฉด ๋๋ค.
//..
module.exports = {
//..
output: {
filename: 'output.js',
path: path.resolve(__dirname, 'public')
}
};
ํ์ผ ๋จ์์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ชจ๋ ๊ด๋ฆฌ
a.js
์์ ์ ์ธํ ๋ณ์๋ฅผ b.js
์์ ์ฌ์ฉํ ์ ์๊ณ ์์ ํ ์ ์์ด์ ๋ฌธ์ ๊ฐ ์์๋ค.modules
๋ผ๋ ๋ฌธ๋ฒ์ผ๋ก import, export ๊ฐ๋
์ด ์ธ์ด ๋ ๋ฒจ๊น์ง ๋ค์ด์ค๊ฒ ๋์๋ค.์น ๊ฐ๋ฐ ์์ ์๋ํ ๋๊ตฌ
์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น ๋ฅธ ๋ก๋ฉ ์๋์ ๋์ ์ฑ๋ฅ
Babel ์ค์น
$ npm i @babel/core @babel/preset-env babel-loader -D
export
๋ค๋ฅธ ํ์ผ์์ ๊ฐ์ ธ๋ค ์ธ ๋ณ์๋ ํจ์ ์์ export
ํค์๋๋ฅผ ๋ถ์ธ๋ค.
export var name = 'Jessie';
export function sum(a, b) {
return a + b;
}
import
export๋ ๋ณ์๋ ํจ์๋ฅผ { }
์์ ์ ์ธํ์ฌ ์ฌ์ฉํ๋ค.
import { name, sum } from 'ํ์ผ ๊ฒฝ๋ก';
console.log(name); // Jessie
console.log(sum(10, 20)); // 30
devtool: 'source-map'
์์ฑ์ ์ถ๊ฐํด์ฃผ๋ฉด ๋น๋๋๊ธฐ ์ ์ ์๋ณธ ํ์ผ์ ๊ฐ๋ฐ์๋๊ตฌ์์ ๋ณผ ์ ์๋ค.var path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.bundle.js'
},
module: {
rules: [{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}, {
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
stats: {
colors: true
},
devtool: 'source-map'
};
production
, development
, none
development
: ๊ฐ๋ฐ์๋ค์ด ์ข ๋ ๋ณด๊ธฐ ํธํ๊ฒ ์นํฉ ๋ก๊ทธ๋ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ณด์ฌ์ง๋ค.production
: ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ๊ธฐ๋ณธ์ ์ธ ํ์ผ ์์ถ ๋ฑ์ ๋น๋ ๊ณผ์ ์ด ์ถ๊ฐ๋๋ค.none
: ๋๋
ํ ๋์ง ์๊ณ ๋ฒ๋ค๋ง๋๋ค.production
์ผ๋ก ์๋ ์ค์ ๋๋ค.filename
: ๋น๋ ๊ฒฐ๊ณผ๋ฌผ ํ์ผ ์ด๋ฆ ์ง์ filename
์ด ๋์ผํ๋ฉด, ๋ธ๋ผ์ฐ์ ์บ์ฑ ๋๋ฌธ์ ๊ฐ์ ํ์ผ์ ํ๋ฉด์ ๋ฟ๋ ค์ฃผ๊ธฐ ๋๋ฌธ์ ๊ฐ์ ์๋ก๊ณ ์นจ์ ํด์ผ ํ๋ค.filename
์ '[name].[hash].bundle.js'
์ ๊ฐ์ด ์ ์ํ๋ฉด, ์นํฉ์ด ํด์ ๊ฐ์ ์ด์ฉํด์ ๋น๋๋ฅผ ํ ๋๋ง๋ค ๊ณ ์ ๊ฐ๋ค์ ๋ถ์ฌ์ค๋ค. ์ด๋ ๊ฒ ๋๋ฉด filename์ด ๋ณ๊ฒฝ๋๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ์บ์ฑ์ด ๋์ง ์๊ณ ๋ณ๊ฒฝ๋ ํ์ผ์ ์ฌ์ฉ์๊ฐ ์ ์์ ์ผ๋ก ๋ณผ ์ ์๋๋ก ํด์ค๋ค.
output: {
//...
filename: '[name].[hash].bundle.js'
},
entry
์์ output
์ผ๋ก ๋ณํ์ ํ ๋ ์ค๊ฐ์ ๊ฐ์
ํ๋ Loader.rules
: ์นํฉ์ผ๋ก ๋ณํํ ๋ ์ ์ฉ๋ ๋ก๋๋ค์ ๋ฐฐ์ด ์ ๊ฐ์ฒด ํํ๋ก ์ถ๊ฐํ๋ค.test
: ๋ก๋๋ฅผ ์ ์ฉํ ํ์ผ์ ํ์ฅ์ ์ง์ use
: ๋ก๋ ์ง์ example
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
.css
ํ์ฅ์๋ฅผ ๊ฐ์ง ๋ชจ๋ ํ์ผ์ ๋์์ผ๋ก style-loader
,css-loader
๋ก๋๋ฅผ ์ ์ฉ๋ง์ฝ index.js
์ base.css
๋ผ๋ ํ์ผ์ importํ ์ํ์์ ์์ ์ค์ ์ฒ๋ผ ํ์ํ ๋ก๋๋ฅผ ์ ์ํ์ง ์๊ณ ๋น๋๋ฅผ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
index.js
๋ฅผ ๊ฐ์ง๊ณ ํด์์ ์์ํ๋๋ฐ index.js
์์ ์๋ base.css
๋ฅผ ๋ณด๊ณ ์ด๊ฑธ ๋น๋ ๊ฒฐ๊ณผ๋ฌผ์ css ์ฝ๋๋ฅผ ๋ฃ์ผ๋ ค๊ณ ํ ๋ fail ์ด ๋ฌ๋ค.์ฌ์ค ์๋ JS ํ์ผ ์์ CSS๋ฅผ ๋ฃ์ ์ ์๋ค. ๊ทธ๋์ ๋ก๋๋ฅผ ์ค์ ํด์ผ ํ๋ค๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ.
ERROR in ./base.css
Module parse failed: Unexpected token
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
์๋์ ๊ฐ์ด css-loader
๋ง ๋ก๋๋ก ์ง์ ํด์ฃผ๊ณ ๋น๋๋ฅผ ํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
module: {
rules: [{
test: /\.css$/,
use: ['css-loader']
}]
},
base.css
ํ์ผ์์ ์ง์ ํ ์คํ์ผ์ด ์ ์ฉ๋์ง ์๋๋ค!๋ง์ฝ ์๋์ ๊ฐ์ด css-loader
๋ฅผ ๋จผ์ ๋ก๋๋ก ์ง์ ํด์ฃผ๊ณ , style-loader
๋ฅผ ๊ทธ ๋ค์์ ๋ก๋๋ก ์ง์ ํด์ฃผ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
module: {
rules: [{
test: /\.css$/,
use: ['css-loader', 'style-loader']
}]
},
ERROR in ./base.css
Module build failed (from ./node_modules/css-loader/dist/cjs.js): CssSyntaxError
์๋์ ๊ฐ์ด ์์๋ฅผ ๊ผญ ์ง์ผ์ค์ผ ํ๋ค.
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
css-loader
: ๋น๋ ๊ฒฐ๊ณผ๋ฌผ์ css ์ฝ๋๋ฅผ ํฌํจ์์ผ์ค๋ค.style-loader
: ์คํ์ผ ์ฝ๋๋ฅผ <head>
ํ๊ทธ ์์ ์ธ๋ผ์ธ ์คํ์ผ๋ก ๋ฃ์ด ์ฃผ๋ ์ญํ ์ ํ๋ค.scss๋ ์๋์ ๊ฐ์ด ์ค์ ํ ์ ์๋ค.
module: {
rules: [{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}]
},
sass-loader
: sass ๋ฅผ ๋จผ์ css ํ์ผ๋ก ๋ฐ๊พธ๊ณ css-loader
: ๋น๋ ๊ฒฐ๊ณผ๋ฌผ์ css ์ฝ๋๋ฅผ ํฌํจ์์ผ์ฃผ๊ณ style-loader
: ๋น๋ ๊ฒฐ๊ณผ๋ฌผ ๋ด ์คํ์ผ ์ฝ๋๋ฅผ ํ๊ทธ ์์ ์ธ๋ผ์ธ์ผ๋ก ๋ฃ์ด์ค๋คexample : html-webpack-plugin
// webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin');
//...
module.exports = {
//...
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
})
],
//...
}
index.html
template ๊ธฐ๋ฐ์ผ๋ก ๋น๋ ๊ฒฐ๊ณผ๋ฌผ์ ์ถ๊ฐํด์ค๋ค.package.json์ ์๋์ ๊ฐ์ด dev ๋ช ๋ น์ด๋ฅผ ์ถ๊ฐํด์ค๋ค.
"scripts": {
//...
"dev": "webpack-dev-server",
"build": "webpack"
}
$ npm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D