如何将 FIBJS 脚本打包成 exe 可执行文件

更新日期: 2019-10-26阅读: 2.3k标签: 脚本

本文将会介绍如何将 FIBJS 脚本打包成Windows 上的 exe 可执行文件。


FIBJS 简介!Start it!

FIBJS 是一个主要为 Web 后端开发而设计的应用服务器开发框架,它建立在 Google v8 JavaScript 引擎基础上,并且选择了和传统的 callback 不同的并发解决方案。fibjs 利用 fiber 在框架层隔离了异步调用带来的业务复杂性,极大降低了开发难度,并减少因为用户空间频繁异步处理带来的性能问题。FIBJS 的创始人为国内知名程序员@响马老师。


脚本实例!Write it!

我们先从写一个简单的 FIBJS 脚本开始,然后将该脚本通过打包工具打包成 EXE 可执行文件。

先来创建一个文件 index.js,脚本内容如下:

let coroutine = require('coroutine');
let input = console.readLine("Please input something: ");
console.log("What you just typed is: ", input);
console.notice("This program will exit in 5 secends...");
coroutine.sleep(5000);

这段脚本会将你输入的内容显示在屏幕上,并且将会于 5 秒后自动退出。

如果你使用 fibjs 直接执行上述脚本,你会得到:

$ fibjs index.js
Please input something: 1
What you just typed is:  1
This program will exit in 10 secends...


开始打包!Build it!

现在我们会将上述脚本打包成为Windows 上的 EXE 可执行文件。

首先,我们需要如下这段打包代码(wrap.js):

var Fs = require("fs");
var Path = require("path");
var Process = require("process");
var Zip = require('zip');
var Io = require("io");
var Json = require('json');
var Os = require("os");

var LOCALCWD = Process.cwd(); //当前工作目录
var IGNOREFILES = [".gitignore", "/.git/", ".db", ".idea", ".log", "fibjs.exe", "/build/", "fib-jsToZip.js"]; //默认忽略文件及文件夹

function isFileBelong(fileList = [], path) {
    return fileList.some(function (item) {
        return path.indexOf(item) !== -1;
    });
}


function isFileMatchRegex(path, regex) {
    return path.match(regex);
}


function buildExe(from, to, memoryStream) {
    memoryStream.rewind();
    if (Fs.exists(to)) {
        Fs.unlink(to);
    }
    Fs.copy(from, to); //fibjs.exe
    Fs.appendFile(to, memoryStream.readAll()); //append js
}


// 路径存在返回true 否则警告返回false
function configCorrect(project) {
    let pathArray = project.FibjsPath !== undefined ? [project.Location, project.Output, project.FibjsPath] : [project.Location, project.Output];

    for (let i = 0; i < pathArray.length; i++) {
        let path = pathArray[i];
        if (!Fs.exists(path)) {
            Fs.mkdir(path);
        }
    }
}


/**
 * Pack up projects
 * @param {Object} packConfig 
 * @return {Array} outFullPathArray
 */
function buildPack(packConfig) {

    var projects = packConfig.Projects;
    var projCount = 0;
    var outFullPathArray = [];
    var systemExePath = Process.execPath; //fibjs 执行路径

    console.notice("\n\rfib-jsToZip start ... \n\r");

    projects.forEach(function (proj, index) {

        // 检查配置信息 
        configCorrect(proj);

        proj.Version = proj.Version === undefined ? new Date().getTime() : proj.Version; //版本号 无则时间戳
        let fileNameNoExten = proj.Name; //文件名(无扩展名)
        proj.Output = Path.fullpath(proj.Output); //输出路径(zip包所在目录)
        proj.OutZipFullPath = Path.join(proj.Output, fileNameNoExten + '.zip'); //zip包完整路径
        proj.FibjsPath = proj.FibjsPath === undefined ? systemExePath : proj.FibjsPath; //打包fibjs.exe路径 无则打包者系统fibjs

        let ms = new Io.MemoryStream();
        let zipFileInMem = Zip.open(ms, 'w');
        let rootIndexData = "require('./" + fileNameNoExten + "/index');"
        // let dataIndex = "require('./{0}/index')();".format(fileNameNoExten); //how to format string in fibjs
        zipFileInMem.write(Buffer.from(rootIndexData), "index.js"); //create index.js in root path

        //递归将文件写入zip包
        (function seekDir(path) {

            // 忽略数组中的文件
            if (isFileBelong(proj.Ignores, path)) return;

            // 忽略zip包
            if (isFileMatchRegex(path, /.*\.zip/ig)) return;

            if (Fs.stat(path).isDirectory()) {
                Fs.readdir(path).forEach(function (fd) {
                    seekDir(path + Path.sep + fd);
                });
            }
            else {
                zipFileInMem.write(path, Path.join(fileNameNoExten, path.replace(proj.Location, '')));
            }

        })(proj.Location);

        zipFileInMem.close();

        let zipFile = Fs.openFile(proj.OutZipFullPath, 'w');
        ms.rewind();
        ms.copyTo(zipFile);
        zipFile.close();

        console.log(" √ " + proj.Name + " > \"" + proj.OutZipFullPath + "\"");

        // create exe if IsBuild is true
        if (proj.IsBuild === true) {
            Os.platform() === 'win32' ? buildExe(proj.FibjsPath, Path.join(proj.Output, fileNameNoExten + ".exe"), ms) : buildExe(proj.FibjsPath, Path.join(proj.Output, fileNameNoExten), ms);
        }

        ms.close();
        projCount++;
        outFullPathArray.push(proj.OutZipFullPath);
    });

    console.notice("\n\r √ " + projCount + " projects packed up successfully!");

    return outFullPathArray; //返回各项目zip包完整路径
}

module.exports.buildPack = buildPack;

然后编写 build.js:

var Wrapper = require("./wrap.js");

var packConfig = {
    Projects: [
        {
            Name: "EXE 程序名称.exe",
            Location: "源码路径",
            Output: "EXE 文件生成路径",
            Version: "程序版本号",
            Ignores: [
                ".gitignore",
                "/.git/",
            ],
            IsBuild: true,
            FibjsPath: "使用的 fibjs 二进制文件的路径",
        }
    ],
};
    
var outFullPathArray = Wrapper.buildPack(packConfig);
console.log(outFullPathArray); //返回各项目zip包完整路径

然后我们需要下载对应 Windows 版本的 FIBJS 二进制文件(下载地址: http://fibjs.org/download/index.html),置于上述配置的 FibjsPath 目录下。

执行:

fibjs build.js

此时 Output 路径下将会生成对应的 EXE 文件。

作者:罗远航
链接: http://blog.luoyuanhang.com/2019/11/25/fibjs-wrapper/  


链接: https://www.fly63.com/article/detial/6645

javascript 3d 脚本库 - three.js的进行简要介绍

本文的目标是对three.js进行简要介绍。我们将从设置一个(案例)场景开始,使用一个旋转的立方体。在页面底部提供一个工作示例,以防您遇到困难,需要帮助。

mongodb shell 运行js脚本的四种方式

MongoDB 是一个基于分布式文件存储的数据库。是一个介于关系数据库和非关系数据库之间的产品。这篇文章讲解mongodb shell 运行js脚本的四种方式。

defer和async的区别

async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的,最典型的例子:Google Analytics

如何用网页脚本追踪用户

本文介绍如何编写 JavaScript 脚本,将用户数据发回服务器。数据发回服务器的常见做法是,将收集好的用户数据,放在unload事件里面,用 AJAX 请求发回服务器。

npm脚本执行多个任务

如果遇到一个类似的需求,比如执行npm publish命令前想先升级下项目的版本,基础操作是在shell中输入两次命令分别为npm run version和npm run publish,但是有没有更简单的方法呢?请看下面的内容:

8个实用Python的脚本,收藏备用

脚本写的好,下班下得早!程序员的日常工作除了编写程序代码,还不可避免地需要处理相关的测试和验证工作。例如,访问某个网站一直不通,需要确定此地址是否可访问,服务器返回什么,进而确定问题在于什么

两个实用的shell脚本实例

今天主要分享两个shell脚本实例,内容不重要,重点是看如何去实现。批量创建特殊要求用户,需求:批量创建10个系统帐号hwb01-hwb10并设置密码(密码为随机数,要求字符和数字等混合)。

Hershell:一款功能强大的跨平台反向Shell生成器

Hershell是一款功能强大的跨平台反向Shell生成器,该工具使用Go语言开发,基于TCP反向Shell实现其功能。该工具使用了TLS来保障数据通讯的安全性,并且提供了证书公共密钥指纹绑定功能来防止通信数据被拦截。

javascript中defer的作用是什么

defer是脚本程序强大功能中的一个“无名英雄”。它告诉浏览器Script段包含了无需立即执行的代码,并且,与SRC属性联合使用,它还可以使这些脚本在后台被下载,前台的内容则正常显示给用户。

javascript 动态解析脚本

一般而言,如果脚本很长,我们把它们放到一个JS文件中,然后生成一个script元素并把它加入DOM树,把src设置为JS文件的地址即可。但对于很自短的脚本,如果我们又不想用new Function与eval呢?

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!