Node.js 애플리케이션을 배포하고 관리하는 과정에서 패키징(Packaging)은 매우 중요한 단계입니다.
패키징은 소스 코드를 배포 가능한 형태로 변환하는 과정으로, 다양한 환경에서 일관되게 애플리케이션을 실행할 수 있도록 합니다.
이번 포스팅에서는 Node.js 애플리케이션 패키징에 대해 알아보고, Webpack과 pkg를 사용하여 패키징하는 방법을 설명하겠습니다.
패키징(Packaging)이란 무엇이고 왜 하는가?
패키징은 애플리케이션의 소스 코드를 배포 가능한 형태로 압축하고, 필요한 모든 종속성을 포함하여 하나의 파일 또는 여러 파일로 만드는 과정입니다.
이를 통해 다양한 환경에서 일관되게 애플리케이션을 실행할 수 있으며, 다음과 같은 이점을 얻을 수 있습니다:
- 종속성 관리: 필요한 모든 라이브러리와 모듈을 포함하여 배포하므로, 실행 환경에서 종속성을 다시 설치할 필요가 없습니다.
- 코드 보호: 소스 코드를 압축하거나 난독화하여 배포하면 코드의 무단 사용을 방지할 수 있습니다.
- 배포 간소화: 단일 파일 또는 패키지를 배포하면 설치 및 설정 과정이 단순해져 배포가 용이해집니다.
Webpack
Webpack이란?
Webpack은 JavaScript 애플리케이션의 모듈 번들러로, 여러 개의 파일을 하나의 파일로 묶어주는 도구입니다.
주로 프론트엔드 애플리케이션에서 사용되지만, Node.js 애플리케이션에서도 유용하게 사용할 수 있습니다.
특히 TypeScript와 함께 사용할 때 강력한 트랜스파일링 기능을 제공합니다.
공식 페이지: webpack
장점
- 모듈화: 모듈 시스템을 통해 코드의 재사용성을 높이고, 관리하기 쉽게 만듭니다.
- 성능 최적화: 코드 압축, 난독화, 코드 스플리팅 등의 기능을 통해 애플리케이션 성능을 최적화합니다.
- 개발 환경: 개발 서버, 핫 모듈 교체(Hot Module Replacement) 등의 기능을 통해 개발 생산성을 높입니다.
- 유연성: 다양한 로더와 플러그인을 통해 거의 모든 유형의 파일과 작업을 처리할 수 있습니다.
주요 개념 및 기능
Webpack 설정은 프로젝트 루트에 webpack.config.js
파일을 생성하여 프로젝트의 webpack을 설정합니다.
1. Entry (진입점):
Webpack이 번들링을 시작하는 지점입니다.
일반적으로 애플리케이션의 루트 파일을 지정합니다.
Webpack은 이 파일을 기준으로 의존성 트리를 생성합니다.
module.exports = { entry: './src/index.js', };
2. Output (출력):
번들링된 파일이 저장될 위치와 파일명을 지정합니다.
module.exports = { output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, };
3. Loaders (로더):
Webpack은 기본적으로 JavaScript와 JSON 파일만 처리할 수 있습니다.
로더는 이를 확장하여 다른 유형의 파일(CSS, 이미지, TypeScript 등)을 처리할 수 있게 합니다.
module.exports = { module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, };
4. Plugins (플러그인):
플러그인은 로더와 달리 더 광범위한 작업을 수행합니다.
번들링 과정의 여러 단계에서 다양한 기능을 제공할 수 있습니다.
예를 들어, HtmlWebpackPlugin
은 번들링된 스크립트를 자동으로 포함한 HTML 파일을 생성합니다.
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { plugins: [ new HtmlWebpackPlugin({ template: './src/index.html', }), ], };
5. Mode (모드):
개발 모드(development
)와 프로덕션 모드(production
)를 설정하여 최적화 수준을 제어할 수 있습니다.
프로덕션 모드는 코드 압축 및 최적화를 자동으로 수행합니다.
module.exports = { mode: 'development', // or 'production' };
아래와 같이 Common, Development, Production 설정파일을 각각 만들고, package.json
에 맞는 script를 선택해서 사용할 수 있습니다.
그리고 그러기 위해선 webpack-merge
패키지 설치가 필요합니다.
$ $ npm install webpack webpack-cli webpack-merge --save-dev
Common (webpack.common.js
)
// webpack.common.js const path = require("path"); module.exports = { entry: "./src/app.ts", module: { rules: [ { test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/, }, ], }, resolve: { extensions: [".tsx", ".ts", ".js"], }, output: { filename: "bundle.js", path: path.resolve(__dirname, "dist"), }, target: "node", };
Development 설정 파일(webpack.dev.js
)
// webpack.dev.js const { merge } = require("webpack-merge"); const common = require("./webpack.common.js"); module.exports = merge(common, { mode: "development", devtool: "inline-source-map", devServer: { static: "./dist/bundle.js", }, });
Production 설정파일(webpack.prod.js
)
// webpack.prod.js const { merge } = require("webpack-merge"); const common = require("./webpack.common.js"); module.exports = merge(common, { mode: "production", optimization: { minimize: true, }, });
npm 패키지 파일(package.json
)
배포용 인 build
와 개발용인 dev
를 따로 관리합니다.
{ "name": "my-node-app", "version": "1.0.0", "main": "dist/bundle.js", "scripts": { "build": "webpack --config webpack.prod.js", "start": "node dist/bundle.js", "dev": "webpack serve --config webpack.dev.js" }, "dependencies": { "express": "^4.17.1" }, "devDependencies": { "@types/express": "^4.17.11", "@types/node": "^14.14.41", "ts-loader": "^8.0.17", "ts-node": "^9.1.1", "typescript": "^4.2.4", "webpack": "^5.28.0", "webpack-cli": "^4.6.0", "webpack-dev-server": "^3.11.2", "webpack-merge": "^5.7.3" } }
pkg
pkg 소개
pkg
는 Node.js 애플리케이션을 독립 실행 파일로 패키징하는 도구입니다.
이를 통해 Node.js 런타임 없이도 애플리케이션을 실행할 수 있는 네이티브 실행 파일을 생성할 수 있습니다.
pkg
는 특히 배포와 실행 환경의 일관성을 보장하는 데 유용하며, 다음과 같은 주요 기능을 제공합니다:
- 독립 실행 파일 생성:
pkg
는 Node.js 애플리케이션을 하나의 실행 파일로 압축하여 Node.js 런타임과 애플리케이션 코드를 포함합니다. - 멀티 플랫폼 지원: Windows, macOS, Linux 등 다양한 운영 체제에서 실행 파일을 생성할 수 있습니다.
- 손쉬운 배포: 생성된 실행 파일은 추가 의존성 설치 없이 바로 실행할 수 있어 배포가 간편합니다.
아래 github 링크를 참조하세요.
https://github.com/vercel/pkg?tab=readme-ov-file#readme
기본 사용법
1. pkg
설치
pkg
는 npm을 통해 설치할 수 있습니다:
$ npm install -g pkg
2. pkg 패키징 설정
프로젝트의 package.json
파일에 pkg
필드를 추가하여 설정할 수 있습니다:
bin
필드도 추가해주어야 합니다.
package.json
{ "name": "my-app", "version": "1.0.0", "main": "dist/bundle.js", "bin": "dist/bundle.js", "scripts": { "build": "webpack --config webpack.prod.js", "pkg": "pkg . --out-path ./bin" }, "pkg": { "scripts": "dist/bundle.js", "assets": ["views/**/*", "public/**/*"], "targets": ["node16-win-x64", "node16-linux-x64", "node16-macos-x64"] } }
3. 패키징
package.json
의 script
에 pkg
필드를 pkg . --out-path ./bin
로 설정해두어서 bin
폴더에 pkg 패키징 을 수행할 수 있습니다.
$ npm run pkg
참조 링크
- Webpack 공식 사이트: webpack
- https://github.com/vercel/pkg?tab=readme-ov-file#readme
- https://github.com/jh4843/devitworld-nodejs-basic/10_packaging