当前位置: 首页 > 知识库问答 >
问题:

同时维护Node.js和Electronic的本机模块依赖关系

柯景龙
2023-03-14

我正在尝试构建一个需要nodegit的电子应用程序,nodegit是一个原生模块。据我所知,本机模块的本机库必须与运行时引擎(我指的是Node.js或Electron)针对相同的node_module_version

例如,如果我的电子以node_module_version64运行,那么我的nodegit应该安装以node_module_version64为目标的本机库。

目前我的项目中有一些测试,我想同时在Electron和Node.js上运行它们。因为(1)Electronic更接近最终产品的环境,(2)Node.js调试起来要容易得多。

要实现这一目标,本机模块必须同时与Electronic和Node.js兼容。然而,这几乎是不可能的。

有趣的是,从列出电子版(本图中称为chrome版本)和node.js版本的node_module_version的图表来看,它们的node_module_version很少匹配。很难找到使用node.js的电子版本,该版本同时使用相同的node_module_version。因此,我必须使用不同的node_module_version来处理Electron和node.js。换句话说,原生模块只能兼容Electron或Node.js中的任何一个,而不能同时兼容这两个。

我很好奇是否有可能将Node.js和Electronic使用的本机模块分开,而无需重新构建模块或者是否有版本切换功能让我快速切换本机模块的版本?

或者,如果任何人都能共享一种方法,使电子和node.js使用相同的node_module_version,那就更好了。

共有1个答案

鱼恩
2023-03-14

不知道有没有更好的解决方案,我想出了一个极其简单的脚本,用环境选择复制和粘贴模块文件(附在下面)。仍然会非常感激任何关于如何解决这个问题的好主意。

'use strict';

const fs = require('fs-extra');
const path = require('path');

let args = process.argv.slice(2);
let cachePath = path.resolve(__dirname, '../.module_cache');
let configPath = path.join(cachePath, '.config');
let modulePath = path.resolve(__dirname, '../node_modules');

wrapper(args)
.catch(err => {
    console.error(err);
})

function wrapper(args) {
    switch (args[0]) {
        case 'save':
            return saveModule(args[1], args[2]);

        case 'load':
            return loadModule(args[1], args[2]);

        case 'drop':
            if (args.length === 3) {
                return dropModuleEnvironment(args[1]);
            }
            else {
                return dropModule(args[1]);
            }

        case 'ls':
            return listModules();

        case 'which':
            return printWhichModule(args[1]);

        case 'versions':
            return listModuleVersions(args[1]);

        case 'help':
            printUsage();
            return Promise.resolve();

        default:
            printUsage();
            return Promise.reject(new Error("Unexcepted arguments: " + args.join(', ')));
    }
}

function printUsage() {
    console.log(`
  Usage:
    save <module> <environment>: cache a module environment for later use
    load <module> <environment>: load a previously saved module environment, and set it to be active
    drop <module> [environment]: remove all cached module environments, 
                                 or when [environment] is provided, remove the specified environment
    ls: list all cached modules and their current environment
    which <module>: show the active environment for the module
    versions <module>: list all available environments for the module. Active environment is marked by "*"
    help: show this help info`);
}

function saveModule(moduleName, envName) {
    let storePath = path.join(cachePath, moduleName, envName);
    let sourcePath = path.join(modulePath, moduleName);
    return fs.emptyDir(storePath)
    .then(() => {
        return fs.copy(sourcePath, storePath);
    })
    .then(() => {
        return updateConfig(moduleName, ".system.");
    });
}

function loadModule(moduleName, envName) {
    let storePath = path.join(cachePath, moduleName, envName);
    let targetPath = path.join(modulePath, moduleName);
    return whichModuleVersion(moduleName)
    .then(currentVersion => {
        if (currentVersion === envName) {
            console.log(`Not loading ${envName} for ${moduleName} because it is current version`);
            return Promise.resolve();
        }
        else {
            return fs.emptyDir(targetPath)
            .then(() => {
                return fs.copy(storePath, targetPath);
            })
            .then(() => {
                return updateConfig(moduleName, envName);
            })
        }
    })
}

function dropModuleEnvironment(moduleName, envName) {
    let storePath = path.join(cachePath, moduleName, envName);
    return fs.remove(storePath)
    .then(() => {
        return fs.readFile(configPath)
        .then(configRaw => {
            let config = JSON.parse(configRaw);
            let currentEnv = config[moduleName];
            if (currentEnv && currentEnv === envName) {
                config[currentEnv] = '.system.';
            }

            return JSON.stringify(config);
        })
        .then(configRaw => {
            return fs.writeFile(configPath, configRaw);
        });
    });
}

function dropModule(moduleName) {
    return fs.remove(path.join(cachePath, moduleName))
    .then(() => {
        return fs.readFile(configPath)
        .then(configRaw => {
            let config = JSON.parse(configRaw);
            if (config[moduleName]) {
                delete config[moduleName];
            }

            return JSON.stringify(config);
        })
        .then(configRaw => {
            return fs.writeFile(configPath, configRaw);
        });
    })
}

function listModules() {
    return fs.readFile(configPath)
    .then(configRaw => {
        let config = JSON.parse(configRaw);
        Object.keys(config).forEach(moduleName => {
            printModuleVersion(moduleName, config[moduleName]);
        })
    })
}

function printWhichModule(moduleName) {
    return whichModuleVersion(moduleName)
    .then(version => {
        printModuleVersion(moduleName, version);
    });
}

function listModuleVersions(moduleName) {
    let modulePath = path.join(cachePath, moduleName);
    return fs.exists(modulePath)
    .then(exists => {
        if (exists) {
            let currentVersion;
            return whichModuleVersion(moduleName)
            .then(version => currentVersion = version)
            .then(() => fs.readdir(modulePath))
            .then(envNames => {
                envNames.forEach(envName => {
                    if (currentVersion === envName) {
                        console.log('* ' + envName);
                    }
                    else {
                        console.log('  ' + envName);
                    }
                });
            });
        }
        else {
            console.log('not installed');
        }
    })

}

function whichModuleVersion(moduleName) {
    return fs.readFile(configPath)
    .then(configRaw => {
        let config = JSON.parse(configRaw);
        return config[moduleName];
    });
}

function printModuleVersion(moduleName, moduleVersion) {
    console.log(`${moduleName}: ${moduleVersion || 'not installed'}`);
}

function updateConfig(moduleName, envName) {
    return fs.readFile(configPath)
    .then(configRaw => {
        let config = JSON.parse(configRaw);
        config[moduleName] = envName;
        return JSON.stringify(config);
    })
    .then(configRaw => {
        fs.writeFile(configPath, configRaw);
    })
}
 类似资料:
  • 应用程序 SlidingMenu(源文件) SlidingMenu-Maps-Support(源文件) 这里有一个链接,看看我的意思。 这就是我得到的错误。 谢谢! 编辑1:不要紧!我又回到月食了!Android Studio还没有为真正的项目开发做好准备。

  • 当运行命令(如 或 Maven无法解决我的一个模块对另一个模块的依赖关系。 [错误]无法在项目分析器上执行目标-app:无法解析项目的依赖项project_group:a:jar:0.1-snapshot:找不到项目project_group:b:jar:0.1-snapshot 项目结构如下:

  • 让我们创建一个名为的新模块,并在那里定义CounterService。 app/shared/shared.module.ts 现在我们将引入 SharedModule 到AppModule 和中。 app/lazy/lazy.module.ts 使用此配置,两个模块的组件都可以访问CounterService。 我们将以完全相同的方式在EagerComponent和LazyComponent中使

  • 如何在node.js中卸载与dev相关的npm模块?

  • 问题内容: 我有一个简单的节点应用程序,它对github上另一个应用程序具有单一依赖性。使用可以很好地安装依赖项,但是当我尝试在其中安装某些东西时,它说不可用。例如,github应用程序将Mongoose安装为依赖项。我认为该父应用程序可以访问该模块,因为它位于子模块中: 结构看起来像这样: 我是否只需要在父级应用程序中同时包含猫鼬作为依赖项,还是可以通过子级方式访问该模块? 问题答案: 我是否只

  • Velocity 不依赖 jQuery Velocity.js 可以在不引入 jQuery 的情况下单独使用。如果 你需要大部分动画效果能兼容 IE8,就必须引入 jQuery 1×。 它也可以和 Zepto 一起使用,写法和 jQuery 一样: // 无 jQuery 或 Zepto 时,Velocity()方法挂载在 window 对象上 (window.velocity) // ( 第一

  • 问题内容: 我希望有可能在myModuleA中使用Guava-19,在myModuleB中使用guava-20, 因为拼图模块具有自己的类路径。 假设myModuleA使用Iterators.emptyIterator(); -已在guava-20中删除,而myModuleB使用新的静态方法FluentIterable.of(); -番石榴19中没有。不幸的是,我的测试是否定的。在编译时,看起来不