Web Bundling & Webpack usage
은에 빠졌다. 정군의 말에 따르면 반도체에 금이 은으로 대체된다고하니 지금은 은이고 성공하면 금으로 가자 꺄륵
오늘도 개발을 더 편하게 할 수 있게 자동으로 배포파일을 만들어주는 웹팩 가자.
1. without react
튜토리얼로 정리하려고 했더니 끝이없어.. 지금까지의 정리본은 보존하고, 최종코드와 필요한 명령어 및 중간중간의 첨언만 정리한다.
출처: codestates
# 1. 프로젝트폴더 생성
$npm init -y # 2. npm 초기화
# 3. src폴더 및 src/index.js 파일 생성
# 4. 동작을 담은 예시 action.js파일 생성
$npm install -D webpack webpack-cli # 5. 웹팩 설치
111111111111111111111111111111111111111111111111111
5.1. webpack을 이용해 하나로 합친다.
# #5.2. webpack은 번들링을 원하는 파일을 먼저 확인, import한 라이브러리나 코드가 있으면 해당 코드도 모두 인식하여 하나 의 번들안으로 모두 넌흔다. 번들링을 원하는 파일의 위치를 entry, 번들링의 결과물을 output
111111111111111111111111111111111111111111111111111
# 6. 웹팩 config파일 작성: entry와 output정보를 적을 수 있다.
$npx webpack # 7. 번들링하기
# 8. npm run build설정: npm run build script 추가
# package.json > "script" > "build": "webpack" 추가
# 9. src/index.html 생성
$npm i -D css-loader style-loader # 10. 로더 설치
# 10.1. loader 설정이 없으면 require, css 등 에러발생
2222222222222222222222222222222222222222222222222222
# 10.2. loader Styling
# style-loader: Add exports of a module as style to DOM
# css-loader: Loads CSS file with resolved imports and return CSS code
# less-loader: Loads and compiles a LESS file
# sass-loader: Loads and complies a SASS/SCSS file
# postcss-loader: Loads and transforms a CSS/SSS file using PostCSS
# stylus-loader: Loads and complites a Stylus file
# 10.3. loader: JS, json이 아닌 파일을 불러오는 역할을 한다.
22222222222222222222222222222222222222222222222222222
# 11. 파일트리
# .
# ├── LICENSE
# ├── dist
# │ └── app.bundle.js
# ├── package-lock.json
# ├── package.json
# ├── src
# │ ├── index.html # here
# │ ├── index.js
# │ ├── style.css
# │ └── underbar.js
# └── webpack.config.js
#
# 2 directories, 9 files
# 12. html webpack plugin: 번들링에 유용한 다양한 툴이 적용가능하다.
$npm i -D html-webpack-plugin
33333333333333333333333333333333333333333333333333333
# 12.1. plugin
# 번들링 과정 중 개발자가 원하는 다양한 작업을 할 수 있도록 돕는다.
# html-webpack-plugin은 번들링 과정 중 html파일을 자신이 원하는 형태로 가공하여 번들에 포함할 수 있게 돕는다.
33333333333333333333333333333333333333333333333333333
2. 완성코드
<!-- ./src/index.html -->
<!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="style.css" />
<title>Shout Lorem Ipsum Once</title>
</head>
<body>
<main>
<h1>Shout Lorem Ipsum Once</h1>
<div id="app"></div>
</main>
<script src="app.bundle.js"></script>
</body>
</html>
// ./src/index.js
const _ = require("./underbar.js");
require("./style.css");
const shout = (...sentences) => console.log(...sentences);
const shoutToHTML = (...sentences) => {
const app = document.querySelector("#app");
app.append(
...sentences.map((sentence) => {
const shoutHere = document.createElement("div");
shoutHere.className = "shout";
shoutHere.textContent = sentence;
return shoutHere;
})
);
return;
};
const loremIpsum =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis egestas feugiat elit, ac tincidunt neque vestibulum at. Mauris a eros sit amet urna efficitur tempus.";
const shoutOnce = _.once(shout);
const shoutToHTMLOnce = _.once(shoutToHTML);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
/* ./src/style.css */
/* dist/style.css */
* {
box-sizing: border-box;
border: 0;
padding: 0;
margin: 0;
}
main {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
div.shout {
padding: 12px;
margin: 4px;
border-radius: 8px;
border: 0.5px solid gray;
}
// ./src/underbar.js
const _ = {
once(func) {
// 아래 변수들은 아래 선언/리턴되는 함수 안에서 참조됩니다.
// 리턴되는 함수의 scope 내에 존재하므로, 리턴되는 함수를 언제 실행해도 이 변수들에 접근할 수 있습니다.
let result;
let alreadyCalled = false;
return function (...args) {
// TIP: arguments 키워드 혹은, spread operator를 사용하세요.
if (!alreadyCalled) {
alreadyCalled = true;
result = func(...args);
}
return result;
};
},
};
module.exports = _; // 다른 파일에서 사용할 수 있게 export
// .package.json
{
"name": "fe-sprint-webpack-tutorial",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"devDependencies": {
"css-loader": "^6.7.2",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0"
}
}
// .webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "app.bundle.js",
},
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
exclude: /node_modules/,
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html"),
}),
],
};
deprecated
# your home
$mkdir without-react
$cd without-react
# home/without-react
$npm init -y
Wrote to /home/ty/Workspace/without-react/package.json:
{
"name": "without-react",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
$mkdir src
$cd src
# home/without-react/src
$touch action.js
$vim action.js
// src/action.js
const _ = {
once(func) {
// 아래 변수들은 아래 선언/리턴되는 함수 안에서 참조됩니다.
// 리턴되는 함수의 scope 내에 존재하므로, 리턴되는 함수를 언제 실행해도 이 변수들에 접근할 수 있습니다.
let result;
let alreadyCalled = false;
return function (...args) {
// TIP: arguments 키워드 혹은, spread operator를 사용하세요.
if (!alreadyCalled) {
alreadyCalled = true;
result = func(...args);
}
return result;
};
},
};
module.exports = _; // 다른 파일에서 사용할 수 있게 export
# vim :wq 저장 후 종료
# home/without-react/src
$touch index.js
$vim index.js
// src/index.js
const _ = require("./action.js");
const shout = (...sentences) => console.log(...sentences);
const shoutToHTML = (...sentences) => {
const app = document.querySelector("#app");
app.append(
...sentences.map((sentence) => {
const shoutHere = document.createElement("div");
shoutHere.className = "shout";
shoutHere.textContent = sentence;
return shoutHere;
})
);
return;
};
const loremIpsum =
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis egestas feugiat elit, ac tincidunt neque vestibulum at. Mauris a eros sit amet urna efficitur tempus.";
const shoutOnce = _.once(shout);
const shoutToHTMLOnce = _.once(shoutToHTML);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
shoutToHTMLOnce(loremIpsum);
# vim :wq 저장 후 종료
# home/without-react/src
$npm install -D webpack webpack-cli
$touch webpack.config.js
$vim webpack.config.js
// webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"), // './dist'의 절대 경로를 리턴합니다.
filename: "app.bundle.js",
},
};
# vim :wq 저장 후 종료
# home/without-react/src
$npx webpack
# dist/app.bundle.js 생성됬으면 빌드 성공
$..
# home/without-react
$vim packgae.json
{
"name": "fe-sprint-webpack-tutorial",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack", // 추가코드
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"devDependencies": {
"webpack": "^5.73.0",
"webpack-cli": "^4.10.0"
}
}
# vim :wq 저장 후 종료
# home/without-react
$cd src
# home/without-react/src
$touch index.html
$vim index.html
<!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="style.css" />
<title>Shout Lorem Ipsum Once</title>
</head>
<body>
<main>
<h1>Shout Lorem Ipsum Once</h1>
<div id="app"></div>
</main>
<script src="app.bundle.js"></script>
</body>
</html>
추후 과정의 경우에는 bundle로 지정한 dist폴더와 src폴더를 오가면서 동작을 이해시켜주는 과정이다. 최종코드와 문서를 확인하여 동작을 이해하는것이 더 효율적이다.
webpack도 사용하다보면 편리한 툴일 수 밖에 없을거란 생각이들고, 금일 들었던 github 배포방식만 제대로 알아도 따로 빌드해서 파일을 물리적으로 올려줄 필요없이, 기존 방식대로 git으로 push하는 방식을 사용할 수 있다.