1. 程式人生 > 實用技巧 >如何將 FIBJS 指令碼打包成 exe 可執行檔案

如何將 FIBJS 指令碼打包成 exe 可執行檔案

FIBjs簡介!Start it!

FIBJS 是一個主要為 Web 後端開發而設計的應用伺服器開發框架,它建立在 Google v8JavaScript引擎基礎上,並且選擇了和傳統的 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...

資源搜尋網站大全 https://www.renrenfan.com.cn 廣州VI設計公司https://www.houdianzi.com

開始打包!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 檔案。