NODEJS项目打包成单个执行文件PKG

来源:互联网 发布:java 整型转二进制 编辑:程序博客网 时间:2024/06/05 14:17

Package your Node.js project into an executablehttps://npmjs.com/pkg

This command line interface enables you to package your Node.js project into an executable that can be run even on devices without Node.js installed.

Use Cases

  • Make a commercial version of your application without sources
  • Make a demo/evaluation/trial version of your app without sources
  • Instantly make executables for other platforms (cross-compilation)
  • Make some kind of self-extracting archive or installer
  • No need to install Node.js and npm to run the packaged application
  • No need to download hundreds of files via npm install to deployyour application. Deploy it as a single file
  • Put your assets inside the executable to make it even more portable
  • Test your app against new Node.js version without installing it

Usage

npm install -g pkg

After installing it, run pkg --help without arguments to see list of options.

The entrypoint of your project is a mandatory CLI argument. It may be:

  • Path to entry file. Suppose it is /path/app.js, thenpackaged app will work the same way asnode /path/app.js
  • Path to package.json. Pkg will follow bin property ofthe specifiedpackage.json and use it as entry file.
  • Path to directory. Pkg will look for package.json inthe specified directory. See above.

Targets

pkg can generate executables for several target machines at atime. You can specify a comma-separated list of targets via--targetsoption. A canonical target consists of 3 elements, separated bydashes, for examplenode6-macos-x64 or node4-linux-armv6:

  • nodeRange node${n} or latest
  • platform freebsd, linux, macos, win
  • arch x64, x86, armv6, armv7

You may omit any element (and specify just node6 for example).The omitted elements will be taken from current platform orsystem-wide Node.js installation (it's version and arch).There is also an aliashost, that means that all 3 elementsare taken from current platform/Node.js. By default targets arelinux,macos,win for current Node.js version and arch.

Config

During packaging process pkg parses your sources, detectscalls torequire, traverses the dependencies of your projectand includes them into executable. In most cases youdon't need to specify anything manually. However your codemay haverequire(variable) calls (so called non-literalargument to require) or use non-javascript files (forexample views, css, images etc).

  require('./build/' + cmd + '.js')  path.join(__dirname, 'views/' + viewName)

Such cases are not handled by pkg. So you must specify thefiles - scripts and assets - manually inpkg property ofyour package.json file.

  "pkg": {    "scripts": "build/**/*.js",    "assets": "views/**/*"  }

Just be sure to call pkg package.json or pkg . to make useofscripts and assets entries.

Scripts

scripts is a globor list of globs. Files specified as scripts will be compiledusingv8::ScriptCompiler and placed into executable withoutsources. They must conform JS standards of those Node.js versionsyou target (seeTargets), i.e. be already transpiled.

Assets

assets is a globor list of globs. Files specified as assets will be packagedinto executable as raw content without modifications. Javascriptfiles may be specified asassets as well. Their sources willnot be stripped. It improves performance of execution of thosefiles and simplifies debugging.

See alsoDetecting assets in source code andSnapshot filesystem.

Options

Node.js application can be called with runtime options(belonging to Node.js or V8). To list them typenode --help ornode --v8-options. You can "bake" these runtime options intopackaged application. The app will always run with the optionsturned on. Just remove-- from option name.

pkg app.js --options expose-gc

Output

You may specify --output if you create only one executableor --out-path to place executables for multiple targets.

Debug

Pass --debug to pkg to get a log of packaging process.If you have issues with some particular file (seems not packagedinto executable), it may be useful to look through the log.

Build

pkg has so called "base binaries" - they are actually samenode executables but with some patches applied. They areused as a base for every executablepkg creates. pkgdownloads precompiled base binaries before packaging yourapplication. If you prefer to compile base binaries fromsource instead of downloading them, you may pass--buildoption to pkg. First ensure your computer meets therequirements to compile original Node.js:BUILDING.md

Usage of packaged app

Command line call to packaged app ./app a b is equivalentto node app.js a b

Snapshot filesystem

During packaging process pkg collects project files and placesthem into executable. It is called a snapshot. At run time thepackaged application has access to snapshot filesystem where allthat files reside.

Packaged files have /snapshot/ prefix in their paths (orC:\snapshot\ in Windows). If you usedpkg /path/app.js command line,then __filename value will be likely/snapshot/path/app.jsat run time. __dirname will be /snapshot/path as well. Here isthe comparison table of path-related values:

valuewith nodepackagedcomments__filename/project/app.js/snapshot/project/app.js __dirname/project/snapshot/project process.cwd()/project/deploysuppose the app is called ...process.execPath/usr/bin/nodejs/deploy/app-x64app-x64 and run in /deployprocess.argv[0]/usr/bin/nodejs/deploy/app-x64 process.argv[1]/project/app.js/snapshot/project/app.js process.pkg.entrypointundefined/snapshot/project/app.js process.pkg.defaultEntrypointundefined/snapshot/project/app.js require.main.filename/project/app.js/snapshot/project/app.js 

Hence, in order to make use of a file collected at packagingtime (require a javascript file or serve an asset) you shouldtake__filename, __dirname, process.pkg.defaultEntrypointorrequire.main.filename as a base for your path calculations.For javascript files you can justrequire or require.resolvebecause they use current __dirname by default. For assets usepath.join(__dirname, '../path/to/asset'). Learn more aboutpath.join inDetecting assets in source code.

On the other hand, in order to access real file system at run time(pick up a user's external javascript plugin, json configuration oreven get a list of user's directory) you should takeprocess.cwd()or path.dirname(process.execPath).

Detecting assets in source code

When pkg encounters path.join(__dirname, '../path/to/asset'),it automatically packages the file specified as an asset. SeeAssets. Pay attention thatpath.join must have twoarguments and the last one must be a string literal.

This way you may even avoid creating pkg config for your project..

使用样例:

pkg package.json -t  node7-win-x86 --output zmdog.exe  --debug

package.json 中需要定义应用入口节点 "bin":"./bin/www",

打包成EXE 后读取配置文件使用:

js文件中需要使用process.cwd

require(path.join(process.cwd(),'cfg.json' ))

需要使用path.join( process.cwd())

如果是只读的文件,需要打包到exe中,就只需要使用path.join(__dirname,'somefile')


资源文件打包  需要定义节点

package.json file.

  "pkg": {    "scripts": "build/**/*.js",    "assets": "views/**/*"  }

即可打包成单一的exe,项目只读文件是快照的方式存放在内存,同时也可访问真实文件。

打包速度还挺快。