๋ฒ๋ค๋ฌ์ ๋ํด ์ค๋ช ํ๊ธฐ ์ด์ ์ ๋ฒ๋ค๋ฌ๊ฐ ๋์ค๊ฒ ๋ ๋ฐฐ๊ฒฝ์ ๋ํด ์๊ณ ๊ณต๊ฐํด์ผ ํ๋ค.
์๋ฐ์คํฌ๋ฆฝํธ๋ ์น ํ์ด์ง๋ฅผ ์ ์ดํ๋ ์ฉ๋๋ก ์ฌ์ฉ๋๊ณ , ๋ํ ์๋ ์ ์น ํ์ด์ง๋ ๋ณต์กํ ๊ธฐ๋ฅ์ด ๋ณ๋ก ์์๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ํ๋์ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ก๋ ๋ชจ๋ ์์์ ๊ด๋ฆฌํด๋ ๊ด์ฐฎ์๋ค.
ํ์ง๋ง ์น์ด ์ ์ ๋ณต์กํด์ง๊ณ ์๋ฐ์คํฌ๋ฆฝํธ๋ ๋ค์ํ ๊ธฐ๋ฅ์ ์ํํ๋ฉด์ ๋จ์ํ ์น์ ์ ์ดํ๋ ์ญํ ๋ก๋ง ์ฐ์ด์ง ์๋๋ค.
์ด๋ฐ ์ํฉ ์์์ ํ๋์ JS ํ์ผ๋ก ๋ชจ๋ ์์๋ค์ ๊ด๋ฆฌํ๊ธฐ๋ ๊ต์ฅํ ๋ณต์กํ๊ณ ์ด๋ ค์ ๊ธฐ ๋๋ฌธ์ ์๋ก์ด ๊ธฐ์ ์ด ์ถํํ๋ค. ๋ฐ๋ก ๋ชจ๋ ์์คํ ์ด๋ค.
ํ๋์ JS ํ์ผ์ ๋ถ๋ฆฌํ๊ณ ๊ฐ๊ฐ์ ํ์ผ๋ค์ ๋ชจ๋์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค. Node ํ๊ฒฝ์์๋ ์ฃผ๋ก common js, ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์๋ ES2015 ์ดํ๋ก ESM์ ์ง์ํ๋ค.
ESM์ ์ฐ๋ฆฌ๊ฐ ์ ์๊ณ ์๋ import, export ํค์๋๋ฅผ ์ด์ฉํ ๋ฐฉ๋ฒ์ด๋ค.
import { user } from './user.js';
const username = user.name;
ESM์์ ๊ฐ๋ฐ์๋ ๋ธ๋ผ์ฐ์ ์๊ฒ ํด๋น ์คํฌ๋ฆฝํธ ํ์ผ์ด ๋ชจ๋์ด๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ์ด์ผ ํ๋ค.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/style.css" />
<script type="module" src="./js/edit.js"></script>
<script type="module" src="./js/main.js"></script>
<title>Document</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
๋ค์๊ณผ ๊ฐ์ด script ํ๊ทธ์ type์ module์ด๋ผ๊ณ ๋ช ์ํด์ฃผ๋ฉด ๋๋ค. ์ฐธ๊ณ ๋ก ๋ชจ๋์ ํญ์ ์คํ์ด ์ง์ฐ๋๋ค.(defer ์์ฑ ์ฒ๋ผ)
๋ชจ๋์ ์ด์ฉํ ๋ ์ฝ๊ฐ์ ์ฃผ์์ฌํญ์ด ์๋๋ฐ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
// user.js
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi = () => {
console.log(
"Hello my name is " + this.name + " I'm " + this.age + " years old."
);
};
}
export default new User("Lee", 27);
// edit.js
import User from "./user.js";
console.log(User);
User.name = "Joo";
console.log("User is edited!!");
// main.js
import User from "./user.js";
console.log(User);
User.sayHi();
์๋จ์ html ํ์ผ์ ๋ช ์๋ ๋ชจ๋์ด ๋ค์๊ณผ ๊ฐ์ JS ํ์ผ๋ค์ ์คํํ๋ค๊ณ ํด๋ณด์. ์ด๋ค ๊ฒฐ๊ณผ๊ฐ ์ถ๋ ฅ๋ ๊น?
main์์ importํ User์ ์์ฑ์ด ๋ณํ๋ค. ์ด๋ ๋ชจ๋์ ํน์ฑ ๋๋ฌธ์ธ๋ฐ, ๋ชจ๋์ ์ต์ด ํธ์ถ ์ ๋จ ํ ๋ฒ๋ง ์คํ๋๋ค.
์ด ๋๋ฌธ์ ๋ค๋ฅธ ๋ชจ๋์์ importํ ์์์ด ์์ ๋๋ฉด ๊ฐ์ ์์์ importํ ๋ชจ๋๋ ๊ทธ ์ํฅ์ ๋ฐ๋๋ค.
๋ํ ๋ชจ๋์ ์๊ธฐ ์์ ๋ง์ ์ค์ฝํ๊ฐ ์์ด exportํ์ง ์๋ ์ด์ ๋ค๋ฅธ ๋ชจ๋์์ ๋ด๋ถ ์ค์ฝํ์ ๋ณ์์ ์ ๊ทผํ ์ ์๋ค.
์ต์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ํ์ผ์ ๋ชจ๋๋ก ๋๋์ด ๊ฐ๋ฐํ๋ค๋ ๊ฒ์ ์์๋ค. ํ์ง๋ง ๋ชจ๋์ ์ฅ์ ๊ณผ ๋ฒ๋ค๋ฌ๊ฐ ์ด๋ค ์ฐ๊ด์ด ์์๊น?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./css/style.css" />
<script type="module" src="./js/edit1.js"></script>
<script type="module" src="./js/edit2.js"></script>
<script type="module" src="./js/edit3.js"></script>
<script type="module" src="./js/edit4.js"></script>
<script type="module" src="./js/edit5.js"></script>
<script type="module" src="./js/edit6.js"></script>
<script type="module" src="./js/edit7.js"></script>
<script type="module" src="./js/edit8.js"></script>
<script type="module" src="./js/edit9.js"></script>
<script type="module" src="./js/edit10.js"></script>
<script type="module" src="./js/main.js"></script>
<title>Document</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>
๋ค์๊ณผ ๊ฐ์ ํํ์ ์น ์ฑ์ด ์๋ค.
ํธ์์ edit์ ์ธ๋ฑ์ฑ์ ํ์ง๋ง ๊ฐ๊ฐ์ ๋ชจ๋ ๋คํธ์ํฌ ์์ฒญ์ ํตํด ๋ฐ์์ง๋ ๊ฐ๊ธฐ ๋ค๋ฅธ ์คํฌ๋ฆฝํธ ํ์ผ์ด๋ผ๊ณ ๊ฐ์ ํด๋ณด์.
10๊ฐ ์ ๋ ์ฏค์ด์ผ ์ปค๋ค๋ ๋๋ ์ด๊ฐ ์๊ธฐ์ง ์๊ฒ ์ง๋ง ํ์ผ์ด ์๋ฐฑ ๊ฐ๋ผ๋ฉด ์ด๋จ๊น? ์๋ฐฑ ๋ฒ์ ๋คํธ์ํฌ ์์ฒญ์ ์๋ฌด๋ฆฌ ์๊ฐํด๋ ๋นํจ์จ์ ์ผ ๊ฒ ๊ฐ๋ค.
๋ฒ๋ค๋ฌ๋ ์ด๋ฌํ ํํ๋ก ๊ตฌ์ฑ๋ JS ํ์ผ๋ค์ ํ๋๋ก ๋ฌถ์ด์ค ์ ์๋ค.
!function(){"use strict";var n,e,t,r,o,a,i,c,s,u,f,l,p,d,v={705:function(n){n.exports=function(n){var e=[];return e.toString=function(){return this.map((function(e){var t="",r=void 0!==e[5];return e[4]&&(t+="@supports (".concat(e[4],") {")),e[2]&&(t+="@media ".concat(e[2]," {")),r&&(t+="@layer".concat(e[5].length>0?" ".concat(e[5]):""," {")),t+=n(e),r&&(t+="}"),e[2]&&(t+="}"),e[4]&&(t+="}"),t})).jo...
๋ํ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ๋๋ ํ ํ๋๋ฐ, ๊ฐ๋ฐ์์ ํธ์์ฑ์ ๋์ด๊ธฐ ์ํ ์ค๋ฐ๊ฟ์ด๋ ๋ค์ฌ์ฐ๊ธฐ ๋ฑ์ ๋ชจ๋ ์์ ๊ณ ๋ธ๋ผ์ฐ์ ๊ฐ ํด๋ ๋ง ๊ฐ๋ฅํ ์ ๋์ ํ์ผ๋ก ์์ถํ๋ค.
์ด๋ฐ ํจ์จ ์ฆ๋ ์ด์ธ์๋ babel์ ํตํ ๋ฌธ๋ฒ๋ณํ, postCSS๋ฅผ ์ด์ฉํ autoprefixer ๋ฑ ๋ค์ํ ์์ ์ ์ํํ ์ ์๋ค.
parcel์ ๋ฒ๋ค๋ฌ์ ํ ์ข ๋ฅ์ด๋ค. parcel์ ์ฅ์ ์ ๊ฐ๋ณ๋ค๋ ๊ฒ์ ๊ผฝ์ ์ ์๋ค.
zero-configuration(config ํ์ผ์ด ํ์ํ์ง ์์)์ด๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ์์ ์ ์ฅ์์๋ ์กฐ๊ธ ๋ ์ฝ๊ฒ ์ ๊ทผํ ์ ์๋ค.
yarn add parcel-bundler
ํ๋ก์ ํธ์ ๋ค์๊ณผ ๊ฐ์ ํจํค์ง๋ฅผ ์ถ๊ฐํ๋ฉด ๊ทธ๊ฒ์ผ๋ก ์ค์น๋ ๋์ด๋ค.
๊ฐ๋จํ ํ๋ก์ ํธ๋ผ๋ฉด ์ดํ์ ๋ฐ๋ก ๋ฒ๋ค๋ง ๋ช ๋ น์ ์งํํ ์๋ ์๋ค.
autoprefixer๋ babel ๋ฑ์ ์ด์ฉํ๋ ค๋ฉด ์ถ๊ฐ ํจํค์ง๊ฐ ํ์ํ๋ค.
ํ์ํ ํจํค์ง๋ฅผ ์ค์นํ package.jsonํ์ผ์ ๋ค์๊ณผ ๊ฐ๋ค.
{
"name": "part8_parcel",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.17.10",
"@babel/plugin-transform-runtime": "^7.17.10",
"@babel/preset-env": "^7.17.10",
"autoprefixer": "9",
"parcel-bundler": "^1.12.5",
"parcel-plugin-static-files-copy": "^2.6.0",
"postcss": "^8.4.13"
},
"scripts": {
"start": "parcel index.html"
},
"staticFiles": {
"staticPath": "statics"
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
parcel-plugin-static-files-copy๋ staticํ ํ์ผ๋ค์ ๋น๋ ๊ฒฐ๊ณผ์ copyํด์ฃผ๋ ํจํค์ง, @babel/preset-env ๋ฐ๋ฒจ ์ปดํ์ผ์ ํ์ํ ํ๋ฌ๊ทธ์ธ ๊ทธ๋ฃน, @babel/plugin-transform-runtime๋ ์ถ๊ฐ ํ๋ฌ๊ทธ์ธ์ธ๋ค.
browserslist๋ autoprefixer๋ babel์๊ฒ ์ง์ํ๋ ๋ธ๋ผ์ฐ์ ์ ๋ฒ์๋ฅผ ์๋ ค์ค๋ค.
ํด๋น json์์๋ ์ ์ธ๊ณ ์ ์ ์จ 1% ์ด์์ธ ๋ธ๋ผ์ฐ์ ์ ๋ง์ง๋ง 2 ๋ฒ์ ๊น์ง ์ง์ํ๋ผ๊ณ ๋ช ์ํ๊ณ ์๋ค.
// .babelrc.js
module.exports = {
presets: ["@babel/preset-env"],
plugins: [["@babel/plugin-transform-runtime"]],
};
// .postcssrc.js
module.exports = {
plugins: [require("autoprefixer")],
};
parcel์ ์์ฃผ ์ฌ์ฉ๋๋ babel์ด๋ postCSS ๋ฑ์ ํธ๋์คํ์ผ๋ฌ๋ค์ ๋ด์ฅ ์ง์ํ๋๋ฐ ์์ ๊ฐ์ ํ์ผ์ด ๋ชจ๋ ๋ด๋ถ์ ์กด์ฌํ๋ค๋ฉด ๋ฒ๋ค๋ง ์ ์๋ ๋ณํํด์ค๋ค.
์นํฉ์ parcel๋ณด๋ค ์ฌ์ฉ์ด ์กฐ๊ธ ๋ ๊น๋ค๋กญ๋ค. parcel์ด zero-confiuration์ด์๋ค๋ฉด webpack์ ์ฌ์ฉ์๊ฐ ์ง์ config๋ฅผ ์ค์ ํด์ผํ๋ค.
๋ณต์กํ์ง๋ง ๊ทธ๋ ๊ฒ ํจ์ผ๋ก์จ ํ๋ก์ ํธ๋ฅผ ๋น๋ํ ๋ ์ธ์ธํ ๋ถ๋ถ์ ์ค์ ํ ์ ์๋ค.
parcel๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํจํค์ง๋ค์ ์ค์นํด์ผ ํ๋ฉฐ ์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
{
"name": "part8",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server --mode development",
"build": "webpack --mode production"
},
"license": "MIT",
"devDependencies": {
"autoprefixer": "^10.4.7",
"babel-loader": "^8.2.5",
"copy-webpack-plugin": "^10.2.4",
"css-loader": "^6.7.1",
"html-webpack-plugin": "^5.5.0",
"postcss": "^8.4.13",
"postcss-loader": "^6.2.1",
"style-loader": "^3.3.1",
"webpack": "^5.72.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.0.0-rc.1",
"@babel/core": "^7.17.10",
"@babel/plugin-transform-runtime": "^7.17.10",
"@babel/preset-env": "^7.17.10"
},
"browserslist": [
"> 1%",
"last 2 versions"
],
}
๋น์ทํ์ง๋ง ์ฝ๊ฐ์ ๋ค๋ฅธ ์ ์ด ์๋๋ฐ, ํนํ loader๊ฐ ๋์ ๋๋ค.
parcel์ ์์ฃผ ์ฌ์ฉ๋๋ ํธ๋์คํ์ผ๋ฌ๋ฅผ ๋ด์ฅ ์ง์ํ์ง๋ง ์นํฉ์ ๊ทธ๋ ์ง ์๊ธฐ ๋๋ฌธ์ ์ง์ loader๋ฅผ ์ค์ ํด์ค์ผ ํ๋ค.
// const path = require("path");
const HtmlPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
// ํ์ผ์ ์ฝ์ด๋ค์ด๋ ์ง์
์ ์ค์
entry: "./src/main.js",
// ๊ฒฐ๊ณผ๋ฌผ ๋ฐํ ์ต์
output: {
// ๊ธฐ๋ณธ์ path dist, filename main.js
// path: path.resolve(__dirname, "dist"),
// filename: "mai.js",
clean: true,
// ๊ธฐ์กด ๋น๋ ๊ฒฐ๊ณผ ์ ๊ฑฐ
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader", "postcss-loader"],
// ์์ ์ค์, ๋ค์์๋ถํฐ ๋ก๋
},
{
test: /\.js$/,
use: ["babel-loader"],
},
],
},
// ๋ฒ๋ค๋ง ํ ๊ฒฐ๊ณผ๋ฌผ์ ์ฒ๋ฆฌ ๋ฐฉ์
plugins: [
new HtmlPlugin({
template: "./index.html",
}),
// ๋ณต์ฌํด์ ๋ชฉํ ํด๋(dist)๋ก copyํด์ค
new CopyPlugin({
patterns: [{ from: "statics" }],
}),
],
};
์ค์น๋ ํจํค์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ค์ ํ webpack.config.js ํ์ผ์ด๋ค. ์ฃผ์์ผ๋ก ๋ฌ๋ฆฐ ์ค๋ช ๋ฌธ๊ตฌ ์ฒ๋ผ ๋ค์ํ ๋ถ๋ถ์ ์ธ์ธํ๊ฒ ์กฐ์ ํ ์ ์๋ค.
๋ฒ๋ค๋ง์ ๋ํด ์์๋ณด๊ณ ๊ฐ์ฅ ๋์ค์ ์ธ webpack๊ณผ parcel์ ์กฐ๊ธ ๊ฑด๋๋ ค๋ดค์ง๋ง ๋ํ ํ๋ก์ ํธ๋ฅผ ํด ๋ณธ ๊ฒฝํ์ด ์์ด์์ธ์ง ๋ชธ์ ์๋ฟ๋ ๋๋์ ์๋๋ค.
๊ทธ๋๋ ๊ทธ ํ์์ฑ์ ๋๊ปด์ง๋ค.
ํ๋ก ํธ์๋ ๊ฐ๋ฐ์๋ผ๋ฉด ๋ค์ํ ๋๊ตฌ๋ค์ ๋ง์ด ์ด์ฉํ๋๋ฐ ๋ธ๋ผ์ฐ์ ๋ HTML, CSS, JS ํ์ผ๋ง ์ดํดํ ์ ์๋ค.
์ด๋ ๋ฒ๋ค๋ฌ๊ฐ ํ์ํ๋ค. ๊ฐ๋ฐ ํธ์์ฑ์ ์ํด ์ฌ์ฉํ๋ ๋๊ตฌ๋ค์ ๋ธ๋ผ์ฐ์ ๊ฐ ์ ์ ์๋ ํํ๋ก ๋ณํํด์ฃผ๋ ๊ฒ.
ํ๋ ์์ํฌ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํด ๊ฐ๋ฐํ๋ ํ์ฌ ํธ๋ ๋์์๋ ํ์์ ์ด๋ผ๊ณ ํ ์ ์๊ฒ ๋ค.
๊ณผ๊ฑฐ์ ๊ธฐ๋ณธ ์๋ฐ์คํฌ๋ฆฝํธ ํ๊ฒฝ์์ ๋ฆฌ๋์ค ํจํค์ง๋ฅผ ์ด์ฉํด๋ณด๋ ค๊ณ ์๋ํ ์ ์ด ์๋ค.
ํ์ง๋ง ๋ฆฌ๋์ค ํจํค์ง ๋ด๋ถ๊ฐ ๋ชจ๋์ importํ ๋ ๋ค์ ํ์ฅ์๋ฅผ ์๋ตํ ํํ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
์ด๋ parcel์ ์ด์ฉํด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์๋๋ฐ ๋ฌธ๋ ์๊ฐ๋๋ค.