웹 번들링 후 배포하기 📰

forhrever·2023년 3월 20일
0

튜토리얼 1

디렉터리 생성
튜토리얼을 위한 디렉터리를 만듭니다. 자유롭게 이름 지어도 좋습니다.

cd ~/Desktop
mkdir fe-sprint-webpack-tutorial
cd fe-sprint-webpack-tutorial

npm init

// 필요한 npm 설치 
npm init -y

//package.json
{
  "name": "fe-sprint-webpack-tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": ""
}

index.js 파일 생성

const _ = require('./underbar.js')

const shout = (...sentences) => console.log(...sentences);

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);

shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);
shoutOnce(loremIpsum);

lodash를 설치하기 전에, webpack의 작동원리를 파악을 위해 src/underbar.js에 once를 직접 구현해보겠습니다.

// 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

웹팩 설치하기
웹팩을 사용하기 위해서는 npm으로 webpack, webpack-cli를 설치해야 합니다. webpack은 이 프로젝트를 번들링하기 위한 라이브러리이긴 하지만, 실제 프로젝트에 사용하지 않기 때문에 devDependency 옵션을 설정하고 설치합니다.

webpack은 우선 번들링을 원하는 파일을 먼저 확인하고, import한 라이브러리나 코드가 있으면 해당 코드도 모두 인식하여 하나의 번들 안으로 모두 넣습니다. 여기서 번들링을 원하는 파일의 위치를 entry, 번들링의 결과물을 output이라고 합니다.

npm install -D webpack webpack-cli

웹팩 config 파일 작성

// webpack.config.js
const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'), // './dist'의 절대 경로를 리턴합니다.
    filename: 'app.bundle.js',
  },
};

번들링하기
번들링을 하기 위해서는 아래와 같은 명령어를 입력해야 합니다. 해당 명령어를 입력하고 번들링 결과를 확인합니다.

npx webpack

npm run build 설정하기
npm run build 스크립트로 언제든 번들링을 할 수 있습니다.

//터미널
npm run build

//package.json 파일 수정
{
  "name": "fe-sprint-webpack-tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
		"build": "webpack", // here
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "devDependencies": {
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }
}

튜토리얼 2

html 파일 생성

// 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">
  <title>Shout Lorem Ipsum</title>
</head>
<body>
  <div id="app"></div>
  <script src="index.js"></script>
</body>
</html>

index.html 파일을 dist 디렉터리로 옮겨서 번들 파일과 연결시키겠습니다.

<!-- dist/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">
  <title>Shout Lorem Ipsum Once</title>
</head>
<body>
  <div id="app"></div>
  <script src="app.bundle.js"></script>
</body>
</html>
// src/index.js
const _ = require('./underbar.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);

CSS 적용하기

// 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>
/* 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;
}

dist/style.css 파일의 위치를 src/style.css 로 옮기고, 파일을 index.js 에서 불러와봅니다.

// 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);

Styling

// 터미널
npm i -D css-loader style-loader

// webpack.config.js
const path = require("path");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "app.bundle.js",
  },
  module: {
    rules: [
      {
				// 파일명이 .css로 끝나는 모든 파일에 적용
        test: /\.css$/,
				// 배열 마지막 요소부터 오른쪽에서 왼쪽 순으로 적용
				// 먼저 css-loader가 적용되고, styled-loader가 적용되어야 한다.
				// 순서 주의!
        use: ["style-loader", "css-loader"],
				// loader가 node_modules 안의 있는 내용도 처리하기 때문에
				// node_modules는 제외해야 합니다
        exclude: /node_modules/,
      },
    ],
  },
};

이후 npm run build 명령을 통해 번들링이 잘 되었는지 확인합니다.

튜토리얼 3

HTML도 번들에 포함하는 작업해보겠습니다. 따로 생성해줬던 dist/index.html을 src 디렉터리로 옮기고 작업을 시작하겠습니다.

파일 구조
.
├── 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

// 터미널 
npm i -D html-webpack-plugin

설치 후 webpack.config.js 파일에 해당 플러그인을 적용합니다. 잘 적용되었으면, npm run build 로 결과를 확인합니다.

// 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")
  })]
};

최소화한 HTML을 보기 쉽게 바꾸면 아래와 비슷한 index.html 파일을 확인하실 수 있습니다. CSS는 app.bundle.js 파일에서 넣어주고, JavaScript는 html-webpack-plugin이 자동으로 스크립트 요소를 추가해준 모습을 보실 수 있습니다.

// dict/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">
  <title>Shout Lorem Ipsum Once</title>
  <script defer="defer" src="app.bundle.js"></script>
</head>

<body>
  <main>
    <h1>Shout Lorem Ipsum Once</h1>
    <div id="app"></div>
  </main>
</body>

</html>
profile
개발자 성장 계단 올라가기

0개의 댓글