node.js 실행파일 만들기

node.js로 만든 프로그램을 pkg 툴로 실행 파일로 만들면 필요한 모듈이 함께 번들링되어 원격 PC에 실행파일을 복사만 하면 되므로 매우 편리합니다. 먼저 NPM으로 실행 파일 빌드 툴인 PKG를 설치하고, PKG는 엔트리 파일과 타겟 운영체제, 출력 파일명을 지정하여 사용합니다. 그 외에도 다양한 옵션이 있으며, 필요할 때 사용할 수 있습니다.

node.js로 만든 프로그램을 다른 PC에서 실행하려면 node.js를 설치하고 패키지를 추가하는 번거로운 과정을 거쳐야 합니다.

만든지 오래된 프로그램이어서 버전이라도 안맞으면 사용한 모듈의 버전을 맞추는 귀찮은 작업을 추가로 해야하기도 합니다.

node.js로 만든 프로그램을 실행파일로 만들어 배포하면 필요한 모듈이 모두 실행파일 안에 번들링 되기 때문에 실행파일만 복사하면 원격 PC에서도 node.js 설치나 버전 호환성을 걱정하지 않아도 되는 장점이 있습니다.

먼저 NPM으로 실행파일 빌드 툴인 PKG를 설치합니다.

npm install pkg

콘솔에 "pkg"를 입력하면 다음처럼 추가 파라미터를 요구하는 에러 메시지가 표시되면 정상 설치된 것입니다.

$ > pkg
pkg@5.8.1
Error! Entry file/directory is expected
Pass --help to see usage information

PKG 기본 사용 커맨드는 다음과 같습니다.

pkg "자바스크립트엔트리파일" -t 타겟운영체제 -o 바이너리파일명

예를 들어 다음 처럼 작성합니다.

pkg "index.js" -t node18-win-x64 -o logchecker

엔트리 파일은 작성한 자바스크립트 프로그램의 메인 js 파일을 말합니다. 따옴표, 쌍타옴표는 생략해도 되지만, 특수 문자, 공백 등을 사용한 경우, 엔트리 파일 명을 명시적으로 구분하기 위해 사용합니다.

옵션

-t

-t 옵션에는 생성할 대상 운영체제, 또는 타겟 바이너리를 문자열로 지정합니다. "node18-win-x64"는 node.js 버전 18 코드(node18)를 윈도우 용(win) 64bit(x64) 바이너리로 생성해달라는 뜻입니다.

윈도우용은 "node18-win-x64", 리눅스용은 "node18-linux-x64"처럼 작성합니다.

타겟 문자열은 3가지 파트로 구분해서 표현합니다. 첫 번째는 node.js 버전, 두 번째는 운영체제, 세 번째는 32bit/64비트 구분입니다. 기본 설정 값을 사용할 때는 생략할 수 있습니다.
"node14-linux" 로 표현하면 현재 설치된 최신 node.js 버전이 아닌 node14버전의 32bit 리눅스 바이너리를 생성합니다.

ARM CPU 디바이스용 바이너리를 생성할 때는 "arm64"를 사용합니다.

-o

-o는 생성할 바이너리 파일의 이름을 지정합니다. 생략할 수 있고 생략하면 엔트리 자바스크립트 파일과 같은 이름의 바이너리 파일이 생성됩니다. 엔트리 파일인 "index.js" 면 윈도우용은 "index.exe" 리눅스용과 맥OS용은 확장자 없이 "index"로 바이너리 파일이 생성됩니다.

윈도우용 바이너리를 생성할 때는 출력 파일 이름에 확장자를 표시하지 않아도 알아서 "exe" 확장자를 붙입니다.

여러 개의 타겟 운영체제에 대한 바이너리를 한번에 생성하려면 다음처럼 타겟을 공백으로 구분해 여러 개를 나열할 수 있습니다.

pkg "index.js" -t "node18-win-x64,node18-linux-arm64,node18-macos" -o logchecker

기타 옵션

타겟 운영체제를 여러 개 나열하면 다음처럼 타겟별로 이름을 구분해서 바이너리 파일이 생성됩니다.

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----      2024-04-30   오후 2:27                logfiles
d-----      2024-04-28   오후 2:35                node_modules
d-----      2024-04-30   오후 2:46                output
-a----      2024-04-30   오후 2:46           3222 index.js
-a----      2024-04-30   오후 2:46         937984 log404.db
-a----      2024-04-30   오후 3:37       44922400 logchecker-node14-linux
-a----      2024-04-30   오후 3:36       36576072 logchecker-node14-linux-arm64
-a----      2024-04-30   오후 3:37       58089995 logchecker-node18-macos
-a----      2024-04-30   오후 3:36       44476383 logchecker-node18-win-x64.exe
-a----      2024-04-30   오후 3:37       44476423 logchecker-node18-win.exe
-a----      2024-04-30   오후 3:26       44476367 logchecker.exe
-a----      2024-04-28   오후 2:35          93394 package-lock.json
-a----      2024-04-28   오후 2:35            388 package.json

주로 사용하는 -t, -o 두 가지를 외에 나머지 옵션들은 -h 옵션으로 출력해서 필요할 때 찾아서 사용하면 됩니다.

pkg -h

  pkg [options] <input>

  Options:

    -h, --help           output usage information
    -v, --version        output pkg version
    -t, --targets        comma-separated list of targets (see examples)
    -c, --config         package.json or any json file with top-level config
    --options            bake v8 options into executable to run with them on
    -o, --output         output file name or template for several files
    --out-path           path to save output one or more executables
    -d, --debug          show more information during packaging process [off]
    -b, --build          don't download prebuilt base binaries, build them
    --public             speed up and disclose the sources of top-level project
    --public-packages    force specified packages to be considered public
    --no-bytecode        skip bytecode generation and include source files as plain js
    --no-native-build    skip native addons build
    --no-dict            comma-separated list of packages names to ignore dictionaries. Use --no-dict * to disable all dictionaries
    -C, --compress       [default=None] compression algorithm = Brotli or GZip

  Examples:

  – Makes executables for Linux, macOS and Windows
    $ pkg index.js
  – Takes package.json from cwd and follows 'bin' entry
    $ pkg .
  – Makes executable for particular target machine
    $ pkg -t node14-win-arm64 index.js
  – Makes executables for target machines of your choice
    $ pkg -t node12-linux,node14-linux,node14-win index.js
  – Bakes '--expose-gc' and '--max-heap-size=34' into executable
    $ pkg --options "expose-gc,max-heap-size=34" index.js
  – Consider packageA and packageB to be public
    $ pkg --public-packages "packageA,packageB" index.js
  – Consider all packages to be public
    $ pkg --public-packages "*" index.js
  – Bakes '--expose-gc' into executable
    $ pkg --options expose-gc index.js
  – reduce size of the data packed inside the executable with GZip
    $ pkg --compress GZip index.js