前置阅读 | Pre-reading
PicGo的版本 | PicGo Version
v3.0.1
系统信息 | System Information
Windows
功能请求 | Feature request
以下内容引用我的一篇记录博客
参见: https://github.com/qiaolin-li/dubbo-desktop-manager/blob/master/docs/npm%E6%8F%92%E4%BB%B6%E5%AE%89%E8%A3%85%E5%99%A8.md
大佬,你是我的 Electron 的导师,我看完了你的 Electron 系列博客,之后又研究了 PicGo和 PicGo Core 的源码。它们对我的插件系统帮助很大,感谢大佬,现在轮到我来反哺大佬了,看你的插件系统还依赖外置 nodejs,这体验太差了,我推荐我搞得野路子给你。
我使用的是npm8的包
查看 npm@8.19.4 的源码,npm 8 直接执行 require('npm') 会进入根 index.js,并抛出:
The programmatic API was removed in npm v8.0.0
但继续查看源码可以发现,npm CLI 仍然是运行在 Node.js 上的 JavaScript 程序,核心 Npm 类位于 lib/npm.js。
Electron 主进程就是 Node.js。因此我的最终方案是:把完整的 npm 8 打进应用,绕过根 index.js,直接加载 lib/npm.js,然后调用 load() 和 exec()。
项目固定 npm 版本并通过 Electron Builder 复制完整目录:
{
"dependencies": {
"npm": "8.19.4"
},
"build": {
"extraResources": [
"./node_modules/npm"
]
}
}
NpmUtils 完整实现
NpmUtils 负责加载内置 npm、指定安装目录、选择镜像并转发安装日志:
// 开发和生产环境使用不同的 npm 路径:
const APPLICATION_NPM_PATH_PREFIX = IS_DEVELOPMENT
? path.join(process.cwd(), 'node_modules/npm/')
: path.join(process.resourcesPath, 'node_modules/npm/')
class NpmUtils {
async execCommand (command, args, where){
if (!command) {
throw new Error('command is a must');
}
process.argv[0] = ''
process.argv[1] = 'dist_electron'
process.argv[2] = command
for (let i = 0; i < args.length; i++) {
process.argv.push(args[i]);
}
const Npm = require(`${APPLICATION_NPM_PATH_PREFIX}/lib/npm.js`)
class MyNpm extends Npm {
constructor (localPrefix) {
super()
this.localPrefix = localPrefix;
}
/** 安装依赖时会修改title,可能会影响应用的title,所以重写忽略 */
set title (t) { }
}
const npm = new MyNpm(where)
const stdoutWrite = process.stdout.write;
const stderrWrite = process.stderr.write;
try {
process.stdout.write = (...msg) => {
npm.output(...msg)
}
process.stderr.write = (...msg) => {
npm.outputError(...msg)
}
await npm.load()
// 可以设置更快的仓库
npm.config.set('registry', 'https://registry.npmmirror.com/')
const cmd = npm.argv.shift()
await npm.exec(cmd, npm.argv)
} finally {
process.stdout.write = stdoutWrite;
process.stderr.write = stderrWrite;
}
return npm.message;
}
}
export default new NpmUtils();
使用案例
安装插件:
await npmUtils.execCommand('install', ['ddm-plugin-dubbo-support@1.0.0', '--loglevel', 'info'], pluginDirectory)
卸载插件:
await npmUtils.execCommand('uninstall', ['ddm-plugin-dubbo-support', '--loglevel', 'info'], pluginDirectory)
真实代码参见:
[PluginInstaller.js](https://github.com/qiaolin-li/dubbo-desktop-manager/blob/master/src/main/plugin/PluginInstaller.js)
[NpmUtils.js](
(打个广告)我也是在用 Electron 做一个插件平台,本来是只做 Dubbo客户端的,慢慢的发现不满足了,就好玩做成了现在这个样子,准确是说没有大佬你的博客,就没有这个 app,我看你的博客和源码搞出来的,好几年了,这个插件系统我也搞了两年(是因为不急,反正不图他赚钱),搞着玩
仓库地址:https://github.com/qiaolin-li/dubbo-desktop-manager

前置阅读 | Pre-reading
PicGo的版本 | PicGo Version
v3.0.1
系统信息 | System Information
Windows
功能请求 | Feature request
以下内容引用我的一篇记录博客
大佬,你是我的 Electron 的导师,我看完了你的 Electron 系列博客,之后又研究了 PicGo和 PicGo Core 的源码。它们对我的插件系统帮助很大,感谢大佬,现在轮到我来反哺大佬了,看你的插件系统还依赖外置
nodejs,这体验太差了,我推荐我搞得野路子给你。我使用的是
npm8的包查看
npm@8.19.4的源码,npm 8 直接执行require('npm')会进入根index.js,并抛出:但继续查看源码可以发现,npm CLI 仍然是运行在 Node.js 上的 JavaScript 程序,核心
Npm类位于lib/npm.js。Electron 主进程就是 Node.js。因此我的最终方案是:把完整的 npm 8 打进应用,绕过根
index.js,直接加载lib/npm.js,然后调用load()和exec()。项目固定 npm 版本并通过 Electron Builder 复制完整目录:
{ "dependencies": { "npm": "8.19.4" }, "build": { "extraResources": [ "./node_modules/npm" ] } }NpmUtils 完整实现
NpmUtils负责加载内置 npm、指定安装目录、选择镜像并转发安装日志:使用案例
安装插件:
卸载插件:
真实代码参见:
[PluginInstaller.js](https://github.com/qiaolin-li/dubbo-desktop-manager/blob/master/src/main/plugin/PluginInstaller.js)
[NpmUtils.js](
(打个广告)我也是在用 Electron 做一个插件平台,本来是只做 Dubbo客户端的,慢慢的发现不满足了,就好玩做成了现在这个样子,准确是说没有大佬你的博客,就没有这个 app,我看你的博客和源码搞出来的,好几年了,这个插件系统我也搞了两年(是因为不急,反正不图他赚钱),搞着玩
仓库地址:https://github.com/qiaolin-li/dubbo-desktop-manager