SUEMISUEMY 2024-09-18 16:34 采纳率: 37.5%
浏览 19

node程序打包成.exe,为什么无法脱离node独立运行

node程序打包成.exe,为什么无法脱离node独立运行,.exe必须和node_modules放在同级目录并且电脑要有node环境才能运行,如何解决?
我需要将3d-tiles-tools增加批处理功能,并且将装个项目打包成.exe,双击.exe要运行optimizeB3dm.cjs(代码如下)

//optimizeB3dm.cjs
// import { spawn } from 'child_process';
// import fs from 'fs';
// import path from 'path';
// import async from 'async';
const { spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const async = require('async');

// 获取当前执行目录,即虚拟文件系统根目录
const baseDir = path.dirname(process.execPath);

// 输入和输出目录
const rootDir = path.join(baseDir, 'specs/MyData');
const outputDir = path.join(baseDir, 'output');

// 如果输出根目录不存在,则创建它
if (!fs.existsSync(outputDir)) {
    fs.mkdirSync(outputDir, { recursive: true });
}
// 创建一个限制并发执行数量的队列
const queue = async.queue((fileData, callback) => {
    const { inputFilePath, outputFilePath, isJson } = fileData;

    if (isJson) {
        // 如果是 JSON 文件,直接复制
        fs.copyFile(inputFilePath, outputFilePath, (err) => {
            if (err) {
                console.error(`复制 JSON 文件失败 ${inputFilePath}: ${err.message}`);
            } else {
                console.log(`复制成功 ${inputFilePath}`);
            }
            callback();
        });
    } else {
        // 如果不是 JSON 文件,则执行压缩
        const command = path.join(baseDir, 'node_modules/.bin/3d-tiles-tools');
        const args = [
            'optimizeB3dm',
            '-i', path.resolve(inputFilePath),
            '-o', path.resolve(outputFilePath),
            '--options',
            '--draco.compressMeshes',
            '--draco.compressionLevel=10'
        ];

        const proc = spawn(command, args, { shell: true });

        let dracoError = false;

        proc.stdout.on('data', (data) => {
            console.log(`stdout: ${data}`);
        });

        proc.stderr.on('data', (data) => {
            const errorMessage = data.toString();
            console.error(`stderr: ${errorMessage}`);

            if (errorMessage.includes("Draco encoding failed")) {
                dracoError = true;
            }
        });

        proc.on('error', (err) => {
            console.error(`Error processing ${inputFilePath}: ${err.message}`);
            callback(err);
        });

        proc.on('close', (code) => {
            if (dracoError) {
                console.log(`文件 ${inputFilePath} 不可被压缩。`);
            } else if (code !== 0) {
                console.error(`压缩失败 ${inputFilePath}`);
            } else {
                console.log(`压缩成功 ${inputFilePath}`);
            }
            callback();
        });
    }

}, 5); // 并发处理 5 个文件

// 递归遍历目录
function processDirectory(directory) {
    fs.readdir(directory, (err, files) => {
        if (err) throw err;

        files.forEach(file => {
            const fullPath = path.join(directory, file);

            fs.stat(fullPath, (err, stats) => {
                if (err) throw err;

                if (stats.isDirectory()) {
                    // 递归处理子目录
                    processDirectory(fullPath);
                } else {
                    const inputFilePath = fullPath;
                    const relativePath = path.relative(rootDir, fullPath);
                    const outputFilePath = path.join(outputDir, relativePath);

                    // 确保输出目录存在
                    const outputFileDir = path.dirname(outputFilePath);
                    if (!fs.existsSync(outputFileDir)) {
                        fs.mkdirSync(outputFileDir, { recursive: true });
                    }

                    if (path.extname(file) === '.json') {
                        // 如果是 .json 文件,直接复制
                        queue.push({ inputFilePath, outputFilePath, isJson: true });
                    } else if (path.extname(file) === '.b3dm') {
                        // 如果是 .b3dm 文件,添加到队列进行压缩
                        queue.push({ inputFilePath, outputFilePath, isJson: false });
                    }
                }
            });
        });
    });
}

// 开始处理
processDirectory(rootDir);

// 当队列中的任务完成时,打印完成消息
queue.drain(() => {
    console.log('全部文件处理完毕');
});


我的package.json


{
  "name": "3d-tiles-tools",
  "version": "0.4.2",
  "license": "Apache-2.0",
  "description": "3D Tiles tools",
  "author": {
    "name": "Cesium GS, Inc. and Contributors"
  },
  "type": "module",
  "source": "./src/index.ts",
  "exports": "./build/src/index.js",
  "types": "./build/src/index.d.ts",
  "bin": "./scripts/optimizeB3dm.cjs",
  "pkg": {
    "assets": [
      "node_modules/**/*",
      "scripts/optimizeB3dm.cjs",
      "src/**/*",
      "node_modules/.bin/3d-tiles-tools"
    ],
    "targets": [
      "node18-win-x64"
    ],
    "scripts": [
      "scripts/optimizeB3dm.cjs"
    ]
  },
  "keywords": [
    "3D Tiles"
  ],
  "homepage": "https://github.com/CesiumGS/3d-tiles-tools",
  "repository": {
    "type": "git",
    "url": "https://github.com/CesiumGS/3d-tiles-tools.git"
  },
  "bugs": {
    "url": "https://github.com/CesiumGS/3d-tiles-tools/issues"
  },
  "engines": {
    "node": ">=16.0.0"
  },
  "dependencies": {
    "@gltf-transform/core": "^3.9.0",
    "@gltf-transform/extensions": "^3.9.0",
    "@gltf-transform/functions": "^3.9.0",
    "3d-tiles-tools": "^0.4.2",
    "archiver": "^5.3.1",
    "async": "^3.2.6",
    "better-sqlite3": "^8.0.1",
    "cesium": "^1.103.0",
    "draco3d": "^1.5.6",
    "draco3dgltf": "^1.5.6",
    "gltf-pipeline": "^4.1.0",
    "gltfpack": "^0.19.1",
    "meshoptimizer": "^0.19.0",
    "minimist": "^1.2.7",
    "node-stream-zip": "^1.15.0",
    "pino": "^8.15.0",
    "pino-pretty": "^10.2.0",
    "seedrandom": "^3.0.5",
    "sharp": "^0.32.1",
    "yargs": "^17.5.1"
  },
  "devDependencies": {
    "@microsoft/api-documenter": "^7.19.24",
    "@microsoft/api-extractor": "^7.33.6",
    "@types/jasmine": "^4.0.3",
    "@types/yargs": "^17.0.22",
    "@typescript-eslint/eslint-plugin": "^5.38.0",
    "@typescript-eslint/parser": "^5.38.0",
    "@vercel/ncc": "^0.38.1",
    "c8": "^8.0.1",
    "del-cli": "^5.0.0",
    "eslint": "^8.23.1",
    "eslint-config-cesium": "^9.0.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-node": "^11.1.0",
    "glob": "^10.3.10",
    "jasmine": "^4.3.0",
    "mkdirp": "^1.0.4",
    "nyc": "^15.1.0",
    "prettier": "2.7.1",
    "ts-node": "^10.9.1",
    "typescript": "^4.8.3"
  },
  "scripts": {
    "start": "node scripts/optimizeB3dm.cjs",
    "about:start": "echo 'Start the tools, as a TypeScript command line application'",
    "about:eslint": "echo 'Perform linting of the source code. This may modify the source files.'",
    "about:build": "echo 'Run the TypeScript compiler to generate the build output.'",
    "about:build-post": "echo 'Perform any post-build steps'",
    "about:test": "echo 'Execute the unit tests'",
    "about:coverage": "echo 'Compute the test coverage'",
    "about:prettier-check": "echo 'Check the formatting of the source code (without fixing formatting errors).'",
    "about:prettier": "echo 'Ensure the right formatting of the source code, automatically fixing formatting errors.'",
    "about:generate-third-party": "echo 'Update the ThirdParty.json file with the most recent dependency versions'",
    "about:docs-prepare-directory": "echo 'Prepare the output directory for the API definition file'",
    "about:docs-extract-api": "echo 'Extract the API definition file from the current build output.'",
    "about:docs-generate-markdown": "echo 'Generate the API documentation based on the API definition file'",
    "about:docs-generate": "echo 'Generate the API documentation based on the current build output'",
    "about:docs": "echo 'Perform a build and generate the API documentation based on the build output'",
    "about:package-clean": "echo 'Delete the contents of the 'build' output folder'",
    "about:package-prepare": "echo 'Prepare a package: Linting, formatting, build, test, documentation, and third-party information updates'",
    "about:package": "echo 'Prepare a package that can then be published on NPM'",
    "eslint": "eslint \"./**/*.ts\" --cache",
    "build": "tsc --build --verbose --force && npm run build-post",
    "build-post": "npm run build-post-ktx && npm run build-post-cli",
    "build-post-ktx": "npx copyfiles --flat ./src/ktx/ktx/external/basis_encoder.* ./build/src/ktx/ktx/external",
    "build-post-cli": "npx copyfiles --flat ./bin/cli.mjs ./build/src",
    "test": "npx ts-node node_modules/jasmine/bin/jasmine.js --config=specs/jasmine.json",
    "coverage": "npx c8 --clean npm run test",
    "prettier-check": "prettier --check \"**/*\"",
    "prettier": "prettier --write \"**/*\"",
    "generate-third-party": "node generateThirdParty.js",
    "docs-prepare-directory": "mkdirp etc",
    "docs-extract-api": "api-extractor run --config api-extractor.jsonc --local --verbose",
    "docs-generate-markdown": "api-documenter markdown -i build/api-extractor -o build/docs",
    "docs-generate": "npm run docs-prepare-directory && npm run docs-extract-api && npm run docs-generate-markdown",
    "docs": "npm run build && npm run docs-generate",
    "package-clean": "del-cli ./build/** del-cli ./temp/**",
    "package-prepare": "npm run eslint && npm run prettier-check && npm run build && npm run test && npm run coverage && npm run docs-generate && npm run generate-third-party",
    "package": "npm run package-clean && npm run package-prepare && npm pack"
  }
}

接着我进行打包

pkg . --targets node18-win-x64 --output 3d-tiles-tools.exe --assets 'node_modules/**/*'
  • 写回答

3条回答 默认 最新

  • qbbmnnnnnn 2024-09-20 15:54
    关注

    我之前也是用pkg打包,遇到了不少问题,后来是使用了nexe打包的,你可以试试这个打包工具

    评论

报告相同问题?

问题事件

  • 创建了问题 9月18日

悬赏问题

  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见
  • ¥15 一共有五道问题关于整数幂的运算还有房间号码 还有网络密码的解答?(语言-python)
  • ¥20 sentry如何捕获上传Android ndk 崩溃
  • ¥15 在做logistic回归模型限制性立方条图时候,不能出完整图的困难
  • ¥15 G0系列单片机HAL库中景园gc9307液晶驱动芯片无法使用硬件SPI+DMA驱动,如何解决?