electron 加载谷歌应用应用商店的插件方法
electron 加载 chrome line 插件
成功的效果演示
代码地址
- electron BrowerView 加载 chrome line 插件:https://gitee.com/fe521/electron-plugin-line
- electron webview 加载 chrome line 插件:https://gitee.com/fe521/electron-plugin-line-webview
提示
例子使用 electron-vite 编写,"electron": "^31.0.2",支持 Windows10/Windows11/Mac/Linux(Windows7 需要修改 electron 为 22 版本)
Electron 中加载插件的三种方式
在 Electron 中,您可以通过三种主要方式加载插件,分别是:
方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
BrowserWindow | 1.创建独立的应用窗口 2.需要加载插件或外部网页的独立窗口 | 1.完整的独立窗口,支持最大化、最小化、关闭等操作 2.独立渲染进程,资源隔离好 | 1.资源开销较大 2.不适合在一个窗口中嵌入多个页面 |
BrowserView | 1.在主窗口内嵌入多个独立操作的网页内容 2.更灵活的窗口布局控制 | 1.资源开销小,共享同一渲染进程 2.布局灵活,可嵌入多个视图 | 1.不具备完整的窗口操作功能 2.布局需要手动管理 3.其他的窗口 DOM 不能覆盖 |
WebView | 1.嵌入外部网页并与内容进行深度交互 2.在同一窗口中显示多个独立 Web 内容 | 1.提供高级交互能力 2.支持沙盒模式,提高安全性 3.像 iframe 一样引入内容 | 1.性能较差,尤其是在大量嵌入时 2.需额外管理安全风险 |
electron-vite WebView 的方式引入 line 插件
1. 引入@electron/remote 模块
具体添加代码如下:
electron-vite-添加-electron-remote-模块
2. 主进程定义加载插件
src/main/index.js
import { app, shell, BrowserWindow, ipcMain, session } from "electron";
import { join } from "path";
import { electronApp, optimizer, is } from "@electron-toolkit/utils";
import icon from "../../resources/icon.png?asset";
import "./titlebar";
require("@electron/remote/main").initialize();
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
frame: false,
autoHideMenuBar: true,
...(process.platform === "linux" ? { icon } : {}),
webPreferences: {
preload: join(__dirname, "../preload/index.js"),
sandbox: false,
webviewTag: true,
webSecurity: false,
nodeIntegration: true,
contextIsolation: false,
},
});
require("@electron/remote/main").enable(mainWindow.webContents);
mainWindow.on("ready-to-show", () => {
mainWindow.show();
});
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url);
return { action: "deny" };
});
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env["ELECTRON_RENDERER_URL"]) {
console.log(
"process.env['ELECTRON_RENDERER_URL']",
process.env["ELECTRON_RENDERER_URL"] + "/index.html"
);
mainWindow.loadURL(process.env["ELECTRON_RENDERER_URL"]);
} else {
mainWindow.loadFile(join(__dirname, "../renderer/index.html"));
}
if (is.dev) {
mainWindow.webContents.openDevTools();
}
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
ipcMain.handle("isDev", () => {
return is.dev;
});
ipcMain.handle("get-preload-js-path", async () => {
let extensionPath;
if (is.dev) {
extensionPath = join(__dirname, "../preload/fillChromeAPI.js");
} else {
extensionPath = join(
process.resourcesPath,
"app.asar/out/preload/fillChromeAPI.js"
);
}
return extensionPath;
});
ipcMain.handle("load-plugin", async () => {
let extensionPath;
if (is.dev) {
extensionPath = join(
__dirname,
"../../line/ophjlpahpchlmihnnnihgmmeilfjmjjc/3.3.0_0"
);
} else {
extensionPath = join(
process.resourcesPath,
"./line/ophjlpahpchlmihnnnihgmmeilfjmjjc/3.3.0_0"
);
}
// persist:electron:line:extension 字符串中的内容不同,就会创建或获取不同的会话(session)分区
const current_session = session.fromPartition(
`persist:electron:line:extension`
);
// 清除所有存储数据
await current_session.clearStorageData().then(() => {
console.log("Storage data cleared");
});
console.log("extensionPath", extensionPath);
return current_session.loadExtension(extensionPath);
});
createWindow();
});
这个 session 会自动删除吗?还是需要手动处理
在 Electron 中,通过 session.fromPartition('persist:...')
创建的持久化会话(即带有 persist:
前缀的分区)是不会自动删除的。它们的生命周期与应用程序相同,数据会一直保存在分区中,即使你关闭并重新打开应用程序,该分区的数据仍然会被保留。
如果你需要删除这个持久化会话的缓存、cookie 或其他存储数据,你需要手动处理。你可以使用 session
对象的相关方法来清除数据,例如:
const current_session = session.fromPartition(
"persist:electron:line:extension"
);
// 清除缓存
current_session.clearCache().then(() => {
console.log("Cache cleared");
});
// 清除所有cookies
current_session.clearStorageData({ storages: ["cookies"] }).then(() => {
console.log("Cookies cleared");
});
// 清除所有存储数据
current_session.clearStorageData().then(() => {
console.log("Storage data cleared");
});
如果你希望完全删除这个分区的数据,包括所有的存储内容,你需要显式调用这些清除方法。否则,该分区的数据将一直保留,直到你手动清除或者用户手动删除应用数据。
persist:electron:line:extension
这个字符不一样就是不一样的 session 吗?
是的,persist:electron:line:extension
字符串中的内容不同,就会创建或获取不同的会话(session
)分区。
在 Electron 中,session.fromPartition('partition_name')
方法的 partition_name
参数用于区分不同的会话分区:
- 如果
partition_name
以persist:
为前缀,它将创建或获取一个持久化的会话分区。不同的partition_name
(即使只有一点点不同)会创建或获取完全独立的会话分区。 - 如果
partition_name
没有persist:
前缀,它将创建或获取一个非持久化的会话分区,这样的会话分区在应用程序关闭后会被自动删除。
例如:
session.fromPartition('persist:electron:line:extension')
和session.fromPartition('persist:electron:line:extension-v2')
将会创建或获取两个不同的持久化会话分区。- 每个会话分区都独立保存其缓存、cookie 和其他存储数据,互不干扰。
因此,如果你希望在应用中使用不同的会话上下文,只需要改变 partition_name
即可创建或获取不同的 session
对象。
3. 渲染进程加载 webview 插件
src/renderer/index/App.vue
<template>
<div>
<Titlebar />
<div id="mainbox" style="width: 100vw; height: calc(100vh - 60px)"></div>
</div>
</template>
<script setup>
import { onMounted } from "vue";
import Titlebar from "./components/Titlebar.vue";
onMounted(async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
await window.api.loadPlugin();
// 创建webview
const webview = document.createElement("webview");
webview.id = "myWebview";
webview.allowpopups = "true";
webview.src =
"chrome-extension://ophjlpahpchlmihnnnihgmmeilfjmjjc/index.html";
const preloadPath = await window.api.getPreloadJsPath();
const isDev = await window.api.isDev();
console.log("[preloadPath]", preloadPath);
// 注入 preload.js
webview.setAttribute(
"preload",
// `file://C:/Users/Administrator/Desktop/electron-line-plugin-app/src/preload/fillChromeAPI.js`,
`file://${preloadPath}`
);
webview.setAttribute("partition", `persist:electron:line:extension`);
webview.setAttribute("nodeintegration", true);
webview.setAttribute("nodeintegrationinsubframes", true);
webview.setAttribute(
"webpreferences",
"allowRunningInsecureContent,contextIsolation=false"
);
webview.style.width = "100%";
webview.style.height = "100%";
document.getElementById("mainbox").append(webview);
console.log(webview.partition);
// 等待 dom-ready 事件触发后调用 loadURL
webview.addEventListener("dom-ready", () => {
console.log("Webview is ready");
console.log(webview.partition);
// 打开开发者工具
isDev && webview.openDevTools();
});
});
</script>
<style scoped></style>
提示
上面代码可以优化 使用 will-attach-webview 进行加载 preload.js
const preloadPath = await window.api.getPreloadJsPath();
const isDev = await window.api.isDev();
console.log("[preloadPath]", preloadPath);
// 注入 preload.js
webview.setAttribute(
"preload",
// `file://C:/Users/Administrator/Desktop/electron-line-plugin-app/src/preload/fillChromeAPI.js`,
`file://${preloadPath}`
);
https://cn.electron-vite.org/guide/dev#webview
将预加载脚本附加到 webview 的最简单方法是通过 webContents 的 will-attach-webview 事件处理。
mainWindow.webContents.on("will-attach-webview", (e, webPreferences) => {
webPreferences.preload = join(__dirname, "../preload/index.js");
});
获取 chrome 插件源码
1. 引入Chrome extension source viewer
插件详情页面
https://chromewebstore.google.com/detail/chrome-extension-source-v/jifpbeccnghkjeaalbbjmodiffmgedin
2. 添加至Chrome
扩展
3. 打开你的插件列表,然后打开 CRX 的详情
浏览器地址栏输入:
chrome://extensions/
4. 把 Chrome extension source viewer 插件固定到工具栏
5. 添加 line 插件
https://chrome.google.com/webstore/detail/ophjlpahpchlmihnnnihgmmeilfjmjjc
6. 打开 line 插件的详情页面,并且固定到工具栏
chrome://extensions/?id=ophjlpahpchlmihnnnihgmmeilfjmjjc
7. 下载 line 插件源码
- 点击工具栏的
CRX图标
- 点击工具栏的
Download as zip