์์งํ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ๋ํด ์ด ์์งค๋ณด๋ค ๋ ์ ์ค๋ช ํ ์์ ์ด ์์ต๋๋ค. ๋น์ฅ 2018๋ ์น ๊ฐ๋ฐ์ ๋ก๋๋งต๋ง ๋ด๋ ๋ฐฐ์ธ๊ฒ ๋์นฉ๋๋ค. (๊ทธ๋ฆฌ๊ณ ์ง๊ธ ์ด ์๊ฐ์๋ ๊ณ์ํด์ ๋์ด๋๊ณ ์์ต๋๋ค.) ์ด์ ๋ง ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ์์ํ๋ ค๋ ๋ถ์ด๋ ์ค๋์ ์ ์น ๊ฐ๋ฐ์ ๋ฐฐ์ด ๋ค ์ ๋ณด๋ฅผ ์ ๋ฐ์ดํธํ์ง ์์ ๋ถ๋ค์ ์๋ํ ๊ธฐ๋ถ์ด ๋ค๊ฒ๋๋ค. ๊ทธ๋๋ ๋ง์ ์์ํด๋ณด๋ฉด ์๊ฐ๋งํผ ์ด๋ ต์ง๋ ์์ต๋๋ค. ๋ชจ๋ ๊ฒ์ด ์๋ก ์ฝํ์๊ธฐ ๋๋ฌธ์ ํ๋๋ฅผ ๋ฐฐ์ฐ๋ฉด ๋์์ ๋ค๋ฅธ ํ๋๋ฅผ ๊ฐ์ด ๋ฐฐ์ฐ๊ฒ ๋ฉ๋๋ค. ์ด๋ฒ ๊ธ์์๋ง npm๊ณผ npm scripts, webpack์ ๋ค๋ฃน๋๋ค. ๋๋ฌด ๊ฑฑ์ ํ์ง ๋ง์ธ์.
์ฒ์ ์น ํ๋ก๊ทธ๋๋ฐ์ ๋ฐฐ์ธ ๋๋ HTML ํ์ผ์ ์ธ๋ถ CSS๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ <link>ํ๊ทธ๋ <script>ํ๊ทธ๋ก ๊ฐ์ ธ์ค๋ผ๊ณ ๋ฐฐ์๋๋ค. ์ด๋ ๊ฒ์:
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>index</title>
</head>
<body>
<h1 id="title">Hello, world!</h1>
<script src="index.js"></script>
</body>
</html>
์ด์ ๋๋ง ํด๋ ์น์ฌ์ดํธ๋ ์ ๋์๊ฐ๋๋ค. ํ์ง๋ง ๋ง์ ์ ์ด ๋ถํธํฉ๋๋ค.
index.html์๋ 30๊ฐ์ scriptํ๊ทธ๊ฐ ํ์ํ๊ฒ ๋ฉ๋๋ค. CSS๋ ๋ง์ฐฌ๊ฐ์ง๊ตฌ์.<script src="jquery-3.3.1.min.js"></script>์ ๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ฉด jQuery 3.4.0 ๋ฒ์ ์ด ๋์์ ๋ ๋ค์ ์ฝ๋๋ฅผ ๋ค์ด๋ฐ๋ ์๊ณ ๋ฅผ ํด์ผํฉ๋๋ค.๊ทธ๋์ npm์ด๋ผ๊ณ ํ๋ 'ํจํค์ง ๋งค๋์ '๋ฅผ ์ฌ์ฉํฉ๋๋ค. (์๋๋ ๋๋ถ๋ถ Bower๋ฅผ ์ฌ์ฉํ๋๋ฐ, ์ด์ npm์ด ๋ ์ธ๊ธฐ์์ต๋๋ค.) npm์ ๋ง์น ์ฑ์คํ ์ด์์ ์ดํ๋ฆฌ์ผ์ด์ ์ ๋ค์ด๋ฐ์ ์ฐ๋ฏ์ด ์๋ฐ์คํฌ๋ฆฝํธ ํจํค์ง๋ฅผ ์ฝ๊ฒ ์ฐพ๊ณ ๋ค์ด๋ฐ์์ ์น์ฌ์ดํธ์ ์ ์ฉ์ํฌ ์ ์๋๋ก ๋ง๋ค์ด์ค๋๋ค. ์ด๋ ๊ฒ ํ๋ฉด ํด๋น ์น์ฌ์ดํธ๊ฐ ์ด๋ค ํจํค์ง๋ฅผ ์ฌ์ฉํ๊ณ ์๋์ง ํ ๋์ ๋ณผ ์ ์๊ณ , ํจํค์ง์ ๋ฒ์ ๊ด๋ฆฌ๋ ํจ์ฌ ์ฌ์์ง๋๋ค.
npm์ Node.js๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค. Node.js ํํ์ด์ง์์ ์์ ์ ์ธ LTS๋ฒ์ ์ ๋ค์ด๋ฐ์ผ์ธ์. Node.js๋ฅผ ์ค์นํ๋ฉด npm๋ ์ค์น๋ฉ๋๋ค. npm์ ์ฌ์ฉํ๋ค๋ ๊ฒ์ CLI ํ๊ฒฝ์์ ์์ ์ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ๋ง์ ๋ถ๋ค์ด ์ปค๋งจ๋ ๋ผ์ธ์ ๋ณด๋ฉด ๊ฒ์ ๋จน๋๋ฐ, ๋๋ฌด ๊ฑฑ์ ํ์ง ์์ผ์ ๋ ๋ฉ๋๋ค. ์ต์ํด์ง๋ฉด ์คํ๋ ค GUI๋ณด๋ค ํธํฉ๋๋ค. ์, ์ค์น๊ฐ ๋๋ฌ๋ค๋ฉด ์ด์ ํฐ๋ฏธ๋์ด๋ cmd๋ฅผ ์ด๊ณ ์ ์ค์น๋์๋์ง ํ์ธํด๋ณด์ธ์.
Node.js ๋ฒ์ ํ์ธ:
$ node -v
npm ๋ฒ์ ํ์ธ:
$ npm -v
์ด์ 21์ธ๊ธฐ ํ๋ก ํธ์๋ ๊ฐ๋ฐ ํ๊ฒฝ ์ธํ
์ ์ฒซ ์ฝ์ ๋ด์ต๋๋ค. index.html์ด ์๋ ์์
๋๋ ํ ๋ฆฌ๋ก ์ด๋ํด์ npm ํ๊ฒฝ์ ์ด๊ธฐํํด์ค๋๋ค.
$ npm init
์ด๊ฒ์ ๊ฒ ์ค์ ํ๋ ์ง๋ฌธ์ด ๋ฐํ
๋ฐ ๊ทธ๋ฅ ๋ชจ๋ ์ํฐ๋ฅผ ๋๋ฌ์ฃผ์ธ์. ๋์ค์ ์์ ํ ์ ์์ต๋๋ค. ์ค์ ์ด ๋๋ฌ๋ค๋ฉด index.html์ด ์๋ ๋๋ ํ ๋ฆฌ์ package.json์ด๋ผ๋ ์๋ก์ด ํ์ผ์ด ์๊น๋๋ค.
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
์ด์ npm์ผ๋ก jQuery๋ฅผ ์ค์นํด๋ณผ๊น์?
$ npm install jquery
์ด ๋ช
๋ น์ด๋ฅผ ์คํํ๋ฉด npm์ ์ค์ ์ ์ฅ์์์ jQuery๋ฅผ ๋ค์ด๋ฐ์ node_modules๋ผ๋ ํด๋์ ์ ์ฅํฉ๋๋ค. package.json์ ์๋ก๊ณ ์นจํ๋ฉด ๋ด์ฉ์ด ๋ฐ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"jquery": "^3.3.1"
}
}
์ ๋ง ํธํฉ๋๋ค. ์ด์ ๋ค๋ฅธ ์ฌ๋๊ณผ ํ๋ก์ ํธ๋ฅผ ํจ๊ป ํ ๋ node_modules ํด๋๋ฅผ ์ฃผ์ง ์๊ณ package.json ํ์ผ์ ์ฃผ๋ฉด ์๋๋ฐฉ์ $ npm install ๋ช
๋ น์ด๋ฅผ ํตํด ํ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ํจํค์ง๋ฅผ ํ๋ฒ์ ๋ค์ด๋ฐ์ ์ ์๊ฒ ๋ฉ๋๋ค. node_modules/jquery/dist/ํด๋๋ฅผ ๋ณด๋ฉด jQuery ์ฝ๋๋ค์ด ๋ชจ์ฌ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>index</title>
</head>
<body>
<h1 id="title">Hello, world!</h1>
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="index.js"></script>
</body>
</html>
์ด๋ ๊ฒ ํ๋ฉด index.js์์ jQuery๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ํ์ง๋ง ํจํค์ง๋ฅผ ์ค์นํ๊ณ ๋ถ๋ฌ ์ฌ๋๋ง๋ค node_moduels ํด๋๋ฅผ ๋ค์ ธ๋ด์ผ ํ๋ ๊ฒ์ ์ฌ์ ํ ๋ถํธํฉ๋๋ค. ํ์ง๋ง ์ด๊ฒ๋ ์ฝ๊ฒ ํด๊ฒฐํ ์ ์์ต๋๋ค.
// index.js
var $ = require('jquery');
console.log($('#title').text());
jquery๋ ์ ์ญ์์ ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ, Node.js๋ ์๋ฒ์ฌ์ด๋ ์ธ์ด์ด๊ธฐ ๋๋ฌธ์ ํจํค์ง์ ๊ฒฝ๋ก๋ฅผ ๋ฐ๋ก ์ง์ ํด์ฃผ์ง ์์๋ ๋ชจ๋ ์์์ ํจํค์ง๋ฅผ ๊ฐ์ ธ์ ์ค๋๋ค. index.html์์ jQuery๋ฅผ ๋ถ๋ฌ์ค๋ <script>ํ๊ทธ๋ฅผ ์ง์ฐ๊ณ ์ฌ์ดํธ๋ฅผ ์๋ก๊ณ ์นจํด๋ณด์ธ์. ์ด๋ค๊ฐ์? ์์ฝ์ง๋ง ๋ธ๋ผ์ฐ์ ๋ require๋ฅผ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋น๋๋ค. (๋ธ๋ผ์ฐ์ ๋ ํ์ผ ์์คํ
์ ์ ๊ทผํ ๊ถํ์ ๊ฐ์ง๊ณ ์์ง ์์ต๋๋ค.) ๊ทธ๋์ ์ฐ๋ฆฌ๋ webpack๋ฅผ ์ฌ์ฉํฉ๋๋ค.
webpack์ '๋ชจ๋ ๋ฒ๋ค๋ฌ'์
๋๋ค. Browserify๋ผ๋ ๋ชจ๋ ๋ฒ๋ค๋ฌ๋ ์๋๋ฐ, webpack์ ๋ฒ๋ค๋ง ๋ฟ๋ง ์๋๋ผ ๋ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ๋ง์ด ์ ๊ณตํ๊ณ ์์ด ๋งค์ฐ ํธ๋ฆฌํฉ๋๋ค. ๋ฒ๋ค๋ง์ด๋ผ๋ ๊ฒ์ ์ฌ๋ฌ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ค์ ํ๋๋ก ํฉ์น๋ค๋ ์๋ฏธ์
๋๋ค. ํ์ฌ index.html์์๋ jquery.min.js์ index.js๋ฅผ ๋ฐ๋ก ๋ถ๋ฌ๋ค์ด๊ณ ์๋๋ฐ, webpack์ ์ฌ์ฉํ๋ฉด bundle.js์ ๊ฐ์ ํ์ผ ํ๋๋ง ๋ถ๋ฅผ ์ ์๊ฒ ๋ฉ๋๋ค. ๋ํ ์์ ์ฌ์ฉํ์ง ๋ชปํ require๋ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค. ๊ทธ๋ผ webpack์ ์ค์นํด๋ด
๋๋ค.
$ npm install webpack --save-dev
--save-dev์ ๊ฐ๋ฐ ์์กด์ผ๋ก ์ค์นํ๊ฒ ๋ค๋ ์๋ฏธ์
๋๋ค. ์ฆ, webpack์ด ๊ฐ๋ฐ์ฉ์ผ๋ก๋ง ์ฐ์ด๊ณ ์ค์ ๋ฐฐํฌํ์์๋ ์ฌ์ฉ๋์ง ์์ ๊ฒ์ด๋ผ๋ ๋ป์
๋๋ค. package.json์ ํ์ธํด๋ณด๋ฉด ์๊น ์ค์นํ jquery์๋ ๋ค๋ฅด๊ฒ devDependencies๋ก ์ค์น๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๊ทธ๋ผ ์ด์ webpack์ ์ธํ
ํด๋ณผ๊น์? webpack์ ์ธํ
ํ๊ธฐ ์ํด์๋ webpack.config.js๋ผ๋ ํ์ผ์ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ํ์ผ ์ด๋ฆ์ ๊ผญ webpack.config.js์ด์ด์ผ webpack์ด ์คํ๋ ๋ ์ด ํ์ผ์ ์ฐธ์กฐํ๊ฒ ๋ฉ๋๋ค.
// webpack.config.js
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js'
}
};
entry๋ ๋ฒ๋ค๋งํ ํ์ผ, output์ ๋ฒ๋ค๋งํ ๊ฒฐ๊ณผ๋ฌผ๋ก ๋์ฌ ํ์ผ์ ์๋ฏธํฉ๋๋ค. ์ฐ๋ฆฌ๋ index.js๋ฅผ ๋ฒ๋ค๋งํด์ bundle.js๋ก ๋ด๋ณด๋ผ ๊ฒ์
๋๋ค. index.html์ ์์ ํฉ์๋ค.
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>index</title>
</head>
<body>
<h1>Hello, world!</h1>
<script src="bundle.js"></script>
</body>
</html>
๊ทธ๋ฆฌ๊ณ webpack์ ์คํํ๋ฉด!
$ ./node_modules/.bin/webpack
bundle.js๊ฐ ๋ง๋ค์ด์ง๊ณ , ์ฌ์ดํธ๋ ์ ๋์๊ฐ๋๋ค. ํ์ง๋ง ๋งค๋ฒ index.js๋ฅผ ์์ ํ ๋๋ง๋ค webpack์ ์คํํด์ฃผ๋ ๊ฑด ๋ถํธํฉ๋๋ค. ์ด๊ฑด ์ด๋กํ ๊น์?
task runner๋ ๋น๋๋ฅผ ์๋ํํด์ฃผ๋ ๋๊ตฌ์
๋๋ค. ์์ ์๋ Grunt๋ Gulp๊ฐ ์ฐ์์ง๋ง, ์์ฆ์ npm์ ํฌํจ๋์ด ์๋ ์คํฌ๋ฆฝํธ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ์ถ์ธ์
๋๋ค. ๋ณ๋์ ํจํค์ง๋ฅผ ์ค์นํ ํ์ ์์ด package.json๋ง ์์ ํ๋ฉด ๋ฐ๋ก ๋๋๊น ์ ๋ง ํธํฉ๋๋ค.
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --progress -p",
"watch": "webpack --progress --watch"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.10.0",
},
"dependencies": {
"jquery": "^3.3.1"
}
}
build์ watch๋ผ๋ ๋ช
๋ น์ด๋ฅผ ์ถ๊ฐํ์ต๋๋ค.
$ npm run build
build๋ฅผ ํ๋ฉด webpack์ด ์คํ๋๋ฉฐ ์ฝ๋๋ฅผ ๋น๋ํด์ค๋๋ค. UglifyJS์ ๊ฐ์ ํ๋ฌ๊ทธ์ธ์ ์ค์นํ๊ณ ์คํฌ๋ฆฝํธ๋ฅผ ์กฐ๊ธ ์์ ํ๋ฉด minify๋ ๋ฐฐํฌ์ฉ ์ฝ๋๋ฅผ ๋ง๋ค ์๋ ์์ต๋๋ค. ์ด๊ฑด ๋ค์ ๊ธ์์ ๋ค๋ฃจ๊ฒ ์ต๋๋ค.
$ npm run watch
watch๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ด ์์ ๋ ๋๋ง๋ค ์๋์ผ๋ก webpack์ ์คํ์์ผ์ค๋๋ค. ํ ๋ฒ๋ง ์ผ๋๋ฉด ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ์์ ํ๊ณ ์ ์ฅํ ๋๋ง๋ค webpack์ด ์คํ๋์ด ๋ชจ๋ ์ฝ๋๊ฐ ๋ฒ๋ค๋ง๋ฉ๋๋ค. ์ด์ ์ฌ๊ธฐ์ ์น ์๋ฒ๋ฅผ ๋๋ฆฌ๋ฉด ๊ฐ๋ฐํ๊ฒฝ์ ๋ ํธ๋ฆฌํ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
์ํ์น๋ Nginx๋ฅผ ์ค์นํ์ง ์์๋ ์น์๋ฒ๋ฅผ ๊ตฌ์ถํ ์ ์์ต๋๋ค. webpack์ด ์ ๊ณตํ๋ ์น์๋ฒ๋ฅผ ์ค์นํ๋ฉด ๋ฉ๋๋ค.
$ npm install webpack-dev-server --save-dev
์ค์น๊ฐ ๋๋๋ฉด package.json์ ์คํฌ๋ฆฝํธ๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --progress -p",
"watch": "webpack --progress --watch",
"server": "webpack-dev-server --open"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.10.0",
"webpack-dev-server": "^2.11.1"
},
"dependencies": {
"jquery": "^3.3.1"
}
}
build์ watch์ฒ๋ผ server๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ webpack.config.js์๋ ์๋ฒ์ ๋ํ ์ค์ ์ ์ถ๊ฐํด์ค๋๋ค.
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js'
},
devServer: {
contentBase: './',
compress: true,
port: 8000
},
};
๊ทธ๋ฆฌ๊ณ ์๋ฒ๋ฅผ ์คํํ์ธ์.
$ npm run server
์ด๋ ๊ฒ ํ๋ฉด webpack.config.js๊ฐ ์๋ ๋๋ ํ ๋ฆฌ์ index.html์ด localhost:8000์์ ์ด๋ฆฝ๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ์์ ํ๋ฉด ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋ก๊ณ ์นจํด์ฃผ๊ธฐ๋ ํฉ๋๋ค. ์ ๋ง ์์ฒญ๋๊ฒ ํธํด์ก์ฃ . ์ด์ ๊ธฐ๋ณธ์ ์ธ ์ธํ
์ ๋ชจ๋ ๋๋์ต๋๋ค. ์ด๋ฒ ๊ธ์์ ์ฐ๋ฆฌ๋ 5๊ฐ์ ํ์ผ(index.html, index.js, bundle.js, package.json, webpack.config.js)๊ณผ ํ๋์ ํด๋(node_modules)๋ฅผ ์ป์์ต๋๋ค.
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>index</title>
</head>
<body>
<h1 id="title">Hello, world!</h1>
<script src="bundle.js"></script>
</body>
</html>
index.js
var $ = require('jquery');
console.log($('#title').text());
package.json
{
"name": "project-name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --progress -p",
"watch": "webpack --progress --watch",
"server": "webpack-dev-server --open"
},
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^3.10.0",
"webpack-dev-server": "^2.11.1"
},
"dependencies": {
"jquery": "^3.3.1"
}
}
webpack.config.js
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js'
},
devServer: {
contentBase: './',
compress: true,
port: 8000
},
};