陈建华的博客
专注web开发
node打包可执行文件工具——Pkg使用心得
2020-04-29 17:40:38   阅读186次

项目地址


这个项目很神奇,直接将node.js项目打包成windows可以直接执行的exe文件(也支持FreeBSD、linux、macos、arm系统),甚至不需要安装Node.js,且无须修改你项目中的任何代码!

首先安装pkg

npm install -g pkg

然后在项目目录下执行

pkg entrance.js

即可打包linux,macos,win3个平台的可执行文件。entrance.js为你node项目的入口文件。

如果只想打包windows下的exe,则加上-t参数。win即为打包成windows平台下的exe文件,具体可选参数参见项目目录

pkg -t win entrance.js

 

稍等片刻后项目目录下就会生成打包好的entrance.exe文件。

pkg会自动从入口文件开始查找依赖的文件并全数打包进去,无须修改项目里的任何代码。

 

其他

pkg可以根据package.json下的配置进行打包,默认入口文件为bin指向的文件。

执行

pkg .

或是

pkg package.json

即可自动按照package.json的配置打包。

//package.json
{
    //其他配置项
    "bin": "service.js",//入口文件
    "pkg": {
        "scripts": [
            "build/**/*.js"//需要打包进来的其他js文件,可添加多个
        ],
        "assets": [
            "dist/**/*"//静态文件的目录,可添加多个
        ]
    }
}

 


注意:静态文件需要在项目中将文件的引用换成

path.join(__dirname, 'dist')

的形式,才可以正常打包,否则可能会读取不到。

 

示例

使用vue-cli建立项目,并使用npm run build将你的项目编译生成静态文件到dist目录下。这些都是vue-cli自带的内容,不再赘述。

在项目目录下新建一个service.js文件,并添加以下代码,在本地起一个express静态服务器,使你能够在本地访问你的网站(部署到线上也是类似)

1060590-20180123182203772-1212264666.png

//service.js
const express = require('express');
const app = express();
const path = require('path');
 
app.use(express.static(path.join(__dirname, 'dist')));//注意这里使用path.join(__dirname, 'dist')而不是'dist',虽然在命令行中执行起来效果是一样的,不过pkg打包会无法识别到dist目录
 
var server = app.listen(8081, function () {
    var host = server.address().address
    var port = server.address().port
    console.log(`AIbuy agents server start successfully on http://${host}:${port}`)
})

 

此时你可以在控制台执行

node service.js

来启动你的服务器了,启动完成后,浏览器访问http://localhost:8081/即可查看你的网站。

 

接下来我们使用将service.js和dist目录打包成一个exe文件,方便他人使用

首先安装pkg

npm install -g pkg

然后修改package.json,添加bin(如果不是service.js的话)和pkg项

{
    //其他配置项
    "bin": "service.js",//指定入口文件
    "pkg": {
        "assets": [
            "dist/**/*"//指定要打包的静态文件目录
        ]
    }
}


然后在项目目录下执行

pkg -t win package.json

完成后即生成一个exe文件,双击启动即相当于执行node service.js,然后你浏览器里(http://localhost:8081/)就能访问打包好的项目了!也不需要提前安装node,给老板演示很方便有木有!



====================


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


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


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

20181031174804215.png

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


{
  "name": "test",
  "version": "0.0.0",
  "private": true,
  "bin":"./bin/www",
  "scripts": {
    "start": "node ./bin/www",
    "pkg": "pkg . -t  node6-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)scripts和assets用来配置未打包进可执行文件的脚本和资源文件,文件路径可以使用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没办法帮你自动识别要打包哪个文件,所以文件就丢失了,所以这时候就使用scripts和assets来告诉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;





===========================





nodejs项目打包为exe


2020-04-17 

 约 2 分钟


需求

需要在没有node环境的电脑上运行node程序

打包工具安装

npm install pkg -g

打包程序

找到程序入口文件:pkg 入口文件 -o 输出名

pkg src/index.js  -o app

以上指令会生成app.exe文件

错误处理

可能会遇到以下错误

> Targets not specified. Assuming:
 node10-win-x64> Fetching base Node.js binaries to PKG_CACHE_PATH
 fetched-v10.17.0-win-x64     [                    ] 0%> Error! getaddrinfo ENOENT github-production-release-asset-2e65be.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com:443> Asset not found by direct link:
 {"tag":"v2.6","name":"uploaded-v2.6-node-v10.17.0-win-x64"}> Error! read ECONNRESET

处理方法

找到当前用户home文件夹,windows一般为C:\Users\用户名

在home文件夹里找到.pkg-cache/v2.6文件夹 (具体以当前有v2.x文件夹为主)

下载对应系统对应版本(版本可相差不大)的node二进制文件

将第三步下载的文件移动到第二步的文件夹(将第二步的文件夹.pkg-cache/v2.6里的文件先删除完)

将移动后的文件重命名为fetched-v10.xx.x-win-x64(具体参考第三步下载的版本名)

重新打包







-----------------------------------------------------
转载请注明来源此处
原地址:#

-----网友评论----
暂无评论
-----发表评论----
微网聚博客乐园 ©2014 blog.mn886.net 鲁ICP备14012923号   网站导航