[Node.js – 기초 강좌] 9. Packaging 하기 (Webpack, pkg)

Node.js 애플리케이션을 배포하고 관리하는 과정에서 패키징(Packaging)은 매우 중요한 단계입니다.

패키징은 소스 코드를 배포 가능한 형태로 변환하는 과정으로, 다양한 환경에서 일관되게 애플리케이션을 실행할 수 있도록 합니다.

이번 포스팅에서는 Node.js 애플리케이션 패키징에 대해 알아보고, Webpack과 pkg를 사용하여 패키징하는 방법을 설명하겠습니다.

nodejs-packaging-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는 특히 배포와 실행 환경의 일관성을 보장하는 데 유용하며, 다음과 같은 주요 기능을 제공합니다:

  1. 독립 실행 파일 생성: pkg는 Node.js 애플리케이션을 하나의 실행 파일로 압축하여 Node.js 런타임과 애플리케이션 코드를 포함합니다.
  2. 멀티 플랫폼 지원: Windows, macOS, Linux 등 다양한 운영 체제에서 실행 파일을 생성할 수 있습니다.
  3. 손쉬운 배포: 생성된 실행 파일은 추가 의존성 설치 없이 바로 실행할 수 있어 배포가 간편합니다.

아래 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.jsonscriptpkg필드를 pkg . --out-path ./bin로 설정해두어서 bin 폴더에 pkg 패키징 을 수행할 수 있습니다.

$ npm run pkg

참조 링크

Leave a Comment