TypeScript를 통해 만들어진 파일을 Webpack이 번들 파일 내로 포함시키게 합니다.
npm install --save-dev webpack webpack-cli typescript ts-loader
모듈 번들러입니다.
Webpack을 명령줄에서 사용하거나 package.json 파일 내에서 호출할 때 사용합니다.
package.json에 TypeScript를 포함시켜서 다른 사람들에게 필요하다는 사실을 알려주기 위해 설치합니다.
비교적 작은 패키지로 TypeScript를 호출해서 tsc 명령어를 호출해 TypeScript를 JavaScript로 컴파일링한 뒤 이를 모두 번들링하게 될 Webpack으로 전달하는 역할을 합니다.
// webpack.config.js
const path = require("path");
module.exports = {
// Webpack에게 번들링을 시작할 애플리케이션의 시작점을 지정
entry: "./src/index.ts",
module: {
rules: [
{
// .ts이거나, .tsx가 맨 마지막에 오는 파일을 찾음
test: /\.tsx?$/,
// ts-loader를 사용
use: "ts-loader",
// node_modules은 건드리지 않음
exclude: /node_modules/,
},
],
},
resolve: {
// 웹팩이 resolve할 수 있는 확장자 리스트
extensions: [".tsx", ".ts", ".js"],
},
output: {
// 웹팩으로 생성하려는 파일
filename: "bundle.js",
// bundle.js 파일을 디렉토리 안에 있는 dist 파일에 넣음
path: path.resolve(__dirname, "dist"),
},
};
import Dog from "./Dog.js";
import ShelterDog from "./ShelterDog.js";
import { add, multiply, divide } from "./utils.js";
src폴더에는 .js파일이 없고 .ts파일만 있기 때문에 웹팩이 찾지 못합니다.
따라서 파일 import의 확장자를 제거합니다.
import Dog from "./Dog";
import ShelterDog from "./ShelterDog";
import { add, multiply, divide } from "./utils";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Webpack</title>
</head>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
// package.json
{
"scripts": {
"build": "webpack"
},
}
npm run build
단순화되어 있는 번들을 가지고 역매핑을 통해 빌드 전의 상태를 보여줌으로써 번들을 구성하고 있는 코드가 어디서 오는지를 보여줍니다.
// tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
}
}
// webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/index.ts",
// 소스 맵을 추출해 최종 번들에 포함
devtool: "inline-source-map",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
npm run build
개발 단계에서는 bundle 파일은 경량화되지 않았습니다.
// webpack.config.js
const path = require("path");
module.exports = {
// mode 작성
mode: "development",
entry: "./src/index.ts",
devtool: "inline-source-map",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
사용할 Webpack Dev 서버는 라이브 서버이며 번들링도 백그라운드에서 처리합니다.
매번 별도의 번들 파일로 만들어 dist에 쓰는 대신 메모리에 번들을 보관하여 처리합니다.
dist 디렉토리가 비어 있어도 실행된다는 의미입니다.
npm install --save-dev webpack-dev-server
// package.json
{
"scripts": {
"serve": "webpack serve"
},
}
// webpack.config.js
const path = require("path");
module.exports = {
mode: "development",
entry: "./src/index.ts",
devtool: "inline-source-map",
// devServer 추가
devServer: {
static: {
directory: path.join(__dirname, "./"),
},
},
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
// output 폴더 이름과 동일하게
publicPath: "/dist",
},
};
npm run serve
개발자는 개발과 프로덕션을 사용하기 때문에 webpack.config.js 파일 두 개를 사용하면 편합니다.
webpack.dev.js으로 이름을 바꾼다면 개발에 필요한 config 파일로 명확해집니다.
webpack.config.js를 찾는 게 기본값이지만 --config를 사용해서 webpack.dev.js로 특정합니다.
{
"scripts": {
"serve": "webpack serve --config webpack.dev.js",
},
}
프로덕션용 webpack.config.js 파일을 생성합니다.
// Webpack.prod.js
const path = require("path");
module.exports = {
// production으로 변경
mode: "production",
entry: "./src/index.ts",
devtool: "inline-source-map",
devServer: {
static: {
directory: path.join(__dirname, "./"),
},
},
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/dist",
},
};
webpack.config.js를 찾는 게 기본값이지만 --config를 사용해서 webpack.prod.js를 특정합니다.
{
"scripts": {
"build": "webpack --config webpack.prod.js"
},
}
파일의 내용을 수정하고 번들링 했을 때, 기존 번들파일과 내용이 변경된 다른 파일이란 것을 브라우저가 인식하지 못하면 캐싱 문제가 발생할 수 있습니다.
플러그인을 사용하면 파일이 계속 추가되지 않고 다시 빌드할 때마다 폴더가 자동으로 비워집니다.
npm install --save-dev clean-webpack-plugin
// Webpack.prod.js
// 플러그인 불러오기
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const path = require("path");
module.exports = {
mode: "production",
entry: "./src/index.ts",
devtool: "inline-source-map",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist"),
publicPath: "/dist",
},
// 플러그인 추가
plugins: [new CleanWebpackPlugin()],
};