nodejs后端项目(ncc+pkg)打包成可执行.exe单文件(支持linux、windows、mac)

812次阅读
没有评论

前端项目打包可以用webpack,nodejs后端项目有时候为了代码保密和分发运行方便也需要打包。

ncc工具

ncc是一个将nodejs项目及依赖打包成单文件的cli工具。

安装:

cnpm i -g @vercel/ncc
# 或
npm i -g @vercel/ncc

使用:

ncc build input.js -o dist
// https://github.com/vercel/ncc

pkg工具

ncc工具可以将nodejs项目打包为可执行文件,支持windows、linux、macos.

安装:

npm install pkg --save-dev
# 或者全局安装
npm install -g pkg

概要:如果将node项目打包为一个可执行的文件,那么对于部署、安装来说,以及源码的保护性都有很多的好处

1.全局安装pkg库,也可以不局部安装,全局安装为了方便(npm install pkg -g)

以下为了演示,用express搭建一个默认的web项目,如下,结构如下:

nodejs后端项目(ncc+pkg)打包成可执行.exe单文件(支持linux、windows、mac)

2. 编辑package.json文件,如下:

{
  "name": "test",
  "version": "0.0.0",
  "private": true,
  "bin":"./bin/www",
  "scripts": {
    "start": "node ./bin/www",
    "pkg": "pkg . -t  node10-win-x64 -o app"
  },
  "pkg":{
    "assets":["public/**/*","views/*"]
  },
  "dependencies": {
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "express": "~4.16.0",
    "http-errors": "~1.6.2",
    "jade": "~1.11.0",
    "morgan": "~1.9.0"
  },
  "bundledDependencies": ["express"]
}

解释:1)指定bin,为项目启动文件

2) pkg .,会寻找指定目录下的package.json文件,然后在找bin字段作为入口文件。

3)-t指定打包的目标平台和Node版本,如-t node6-win-x64,node6-linux-x64,node6-macos-x64可以同时打包3个平台的可执行程序

4) -o指定输出可执行文件的名称,但如果用-t指定了多个目标,那么就要用--out-path指定输出的目录

5)scriptsassets用来配置未打包进可执行文件的脚本和资源文件,文件路径可以使用glob通配符。这里就浮现出一个问题:为什么有的脚本和资源文件打包不进去呢?

要回答这个问题,就涉及到pkg打包文件的机制。按照pkg文档的说法,pkg只会自动地打包相对于__dirname__filename的文件,例如path.join(__dirname, '../path/to/asset')。至于require(),因为require本身就是相对于__dirname的,所以能够自动打包。假设文件中有以下代码:

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

cmd和viewname这些路径都不是常量,pkg没办法帮你自动识别要打包哪个文件,所以文件就丢失了,所以这时候就使用scriptsassets来告诉pkg,这些文件要打包进去

3. 运行npm run pkg打包 出来你想要的可执行文件

附:我配置pkg中的assets和我app.js对应代码

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

4. pkg打包后的路径和node有些区别,详情对应如下

nodejs后端项目(ncc+pkg)打包成可执行.exe单文件(支持linux、windows、mac)

比如:__dirname 对应 proccess.cwd()

exe文件路径:process.execPath

build失败异常解决

nodejs后端项目(ncc+pkg)打包成可执行.exe单文件(支持linux、windows、mac)

1. pkg需要特殊的node环境,默认去cache目录找,没有从github下载(比较慢,可能会造成打包失败

nodejs后端项目(ncc+pkg)打包成可执行.exe单文件(支持linux、windows、mac)

解决办法:直接下对应的文件放在pkg的cache目录下面

1. 对应的fetch下载地方: https://github.com/vercel/pkg-fetch/releases

2. 一般全局安装后pkg后,pkg的缓存目录是在 C:Users用户名.pkg-cache

3. 将下载好的文件放在目录下重新打包就不会下载,打包成功率会高很多!

nodejs后端项目(ncc+pkg)打包成可执行.exe单文件(支持linux、windows、mac)

官方文档地址:https://www.npmjs.com/package/pkg

facingscreen
版权声明:本站原创文章,由 facingscreen2022-10-28发表,共计2749字。
转载说明:本文为搜栈网原创文章,除特殊说明外皆由CC-4.0协议发布,转载请注明出处,如有帮助欢迎打赏。
评论(没有评论)
验证码