Поддержание собственных зависимостей модуля для node.js и электрона одновременно - PullRequest
1 голос
/ 08 июня 2019

Я пытаюсь создать приложение Electron, которое требует nodegit , который является собственным модулем.Насколько я знаю, нативная библиотека нативного модуля должна предназначаться для того же NODE_MODULE_VERSION, что и движок времени выполнения (я имею в виду Node.js или Electron).

Например, если мой Electron работает с NODE_MODULE_VERSION 64, то мой nodegit должен быть установлен с собственной библиотекой, предназначенной для NODE_MODULE_VERSION 64.

Current У меня есть несколько тестов в моем проектеи я хотел бы запустить их как на Electron, так и на Node.js.Потому что (1) Electron ближе к среде конечного продукта и (2) Node.js гораздо проще отлаживать.

Для достижения этой цели собственный модуль должен быть совместим как с Electron, так и с Node.js одновременно.Тем не менее, это почти невозможно.

Самое смешное, что из диаграмм, которые перечисляют NODE_MODULE_VERSION из версий электронов (на этом графике это называется Chrome версия), и версии Node.js , их NODE_MODULE_VERSION редко совпадают .Трудно найти версию Electron, которая использует Node.js, который также использует тот же NODE_MODULE_VERSION.Как следствие, мне приходится рассчитываться с Electron и Node.js, используя разные NODE_MODULE_VERSION.Другими словами, собственный модуль может быть совместим только с Electron или Node.js, но не с обоими.

Мне любопытно, можно ли отделить собственный модуль, используемый Node.js и Electron, без перестройки модуля или есть функция переключения версий, позволяющая мне быстро переключать версию собственного модуля?

Или было бы лучше, если бы кто-нибудь мог поделиться способом заставить Electron и Node.js использовать один и тот же NODE_MODULE_VERSION.

1 Ответ

0 голосов
/ 09 июня 2019

Не знаю, есть ли лучшее решение, я придумал очень простой скрипт, который копирует и вставляет файлы модулей с выбором среды (см. Ниже). Все равно очень ценю любую хорошую идею о том, как решить эту проблему.

'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);
    })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...