Electron 14.x.y 以上頁面加載 node_sqlite3 reload 的時候崩潰的問題

問題產(chǎn)生原因

Electron 14.x.y 開始窟扑,Electron 廢棄了一個接口:app.allowRendererProcessReuse志笼。

根據(jù)其官方文檔描述,當設置了 app.allowRendererProcessReusetrue 時,render 進程在加載 native module 的時候被辑,如果發(fā)生了重新加載代碼的情況會自動復用某些底層的初始化代碼。

因此敬惦,當 Electron 加載 node_sqlite3 的時候盼理,由于加載了舊的結構代碼(稍后會解釋為什么此處是舊的結構),在 reload 的時候就崩潰了俄删。

為什么 node_sqlite3 加載的是舊的結構

分析 node_sqlite3 源代碼宏怔。在 src\database.cc 的代碼中可以發(fā)現(xiàn)如下的代碼:

Napi::Object Database::Init(Napi::Env env, Napi::Object exports) {
    Napi::HandleScope scope(env);

    Napi::Function t = DefineClass(env, "Database", {
        InstanceMethod("close", &Database::Close),
        InstanceMethod("exec", &Database::Exec),
        InstanceMethod("wait", &Database::Wait),
        InstanceMethod("loadExtension", &Database::LoadExtension),
        InstanceMethod("serialize", &Database::Serialize),
        InstanceMethod("parallelize", &Database::Parallelize),
        InstanceMethod("configure", &Database::Configure),
        InstanceMethod("interrupt", &Database::Interrupt),
        InstanceAccessor("open", &Database::OpenGetter, nullptr)
    });

#if NAPI_VERSION < 6
    constructor = Napi::Persistent(t);
    constructor.SuppressDestruct();
#else
    Napi::FunctionReference* constructor = new Napi::FunctionReference();
    *constructor = Napi::Persistent(t);
    env.SetInstanceData<Napi::FunctionReference>(constructor);
#endif

    exports.Set("Database", t);
    return exports;
}

參照 "Class property and descriptor" example crashes in Electron render process on reload 的處置結果可知,node_sqlite3 代碼在底層實際上已經(jīng)修復了該問題畴椰。但是在 reload 的時候仍然出現(xiàn)了錯誤的情況臊诊,說明修改的代碼在預編譯的時候并沒有生效。即斜脂,默認編譯的時候抓艳,NAPI_VERSION 的值小于 6。

繼續(xù)分析 node_sqlite3 源代碼帚戳。發(fā)現(xiàn)它使用的是 node-pre-gyp 的組件來進行本地編譯工作的玷或。在 node-pre-gyp 項目的 readme 中我們發(fā)現(xiàn),在項目中片任,可以設置項目支持的 napi_versions偏友。而在 node_sqlite3package.json 中,napi_versions 為:

"napi_versions": [
    3
]

即蚂踊,限定了當前版本最高支持到 napi 版本 3约谈。修改 package.json 中 napi_versions 如下:

"napi_versions": [
    3,
    4,
    5,
    6,
    7,
    8
]

再次 build,這時候就會發(fā)現(xiàn)編譯的 native module 跟隨本地的 node 版本的 napi 版本相同了(由于 electron 中使用的 electron-builder 或者 electron-rebuild,因此此處在后面繼續(xù)解釋)棱诱。至此泼橘,代碼修改部分就基本結束了。

關于 node_sqlite3 在 electron 上 electron-builder 與 electron-rebuild 的使用問題

electron-builder

electron-builderpackage.json 中需要配置一段 script 腳本:"postinstall": "electron-builder install-app-deps"迈勋,該腳本就是用來安裝 native module 的炬灭。

在安裝的過程中,會根據(jù) electron-builder 的配置靡菇,將 native module 鏈接到指定 electron 的 node 版本重归。

通過跟蹤代碼后發(fā)現(xiàn),其實現(xiàn)原理是調用了 nodejs 的 spawn 函數(shù)厦凤,執(zhí)行了 npm install 命令鼻吮。

追蹤 electron-builder 的代碼,最后確定該命令的代碼位于 app-builder-lib\out\util\yarn.js 中的 installDependencies 方法中较鼓。

由于其在 env 中配置了 electron 相對應的 node 的 lib 路徑椎木,因此會在 native module build 過程中,直接連接使用 electron 相關版本的 lib博烂。因此香椎,此處的本質還是使用 node-sqlite3 自身的配置對 node-sqlite 進行的編譯操作。最多對 node 連接的 lib 做了替換操作禽篱。

electron-rebuild

目前項目中并未有 electron-rebuild 的使用畜伐。因此,并未細究 electron-rebuild 的技術細節(jié)躺率。

根據(jù) electron-rebuild 的文檔簡介玛界,rebuild 過程中,electron-rebuild 會使用 node-gyp 對需要 rebuild 的 native module 進行 rebuild 操作肥照。從結果來看脚仔,rebuild 過程中 napi 版本,連接的 node 版本都是使用的 electron 相應的 node 版本舆绎。

但是鲤脏,編譯產(chǎn)生的文件卻在 napi-v{napi_build_version}-win32-x64 文件夾中,而不是 napi-v8-win32-x64 文件夾中吕朵。這就導致了猎醇,electron 加載 node 模塊的時候,仍舊加載了舊版本的 node 模塊(因為 npm install 的時候就 build 好了該模塊)努溃,仍舊出現(xiàn)問題硫嘶。

當然,如果此時將 napi-v{napi_build_version}-win32-x64 的 node 文件替換掉 napi-v8-win32-x64 文件夾中 node 文件梧税,該問題仍然可以得以解決沦疾。

參考

Electron 重大更改

"Class property and descriptor" example crashes in Electron render process on reload

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末称近,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子哮塞,更是在濱河造成了極大的恐慌刨秆,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件忆畅,死亡現(xiàn)場離奇詭異衡未,居然都是意外死亡,警方通過查閱死者的電腦和手機家凯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門缓醋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绊诲,你說我怎么就攤上這事送粱。” “怎么了驯镊?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵葫督,是天一觀的道長。 經(jīng)常有香客問我板惑,道長,這世上最難降的妖魔是什么偎快? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任冯乘,我火速辦了婚禮,結果婚禮上晒夹,老公的妹妹穿的比我還像新娘裆馒。我一直安慰自己,他們只是感情好丐怯,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布喷好。 她就那樣靜靜地躺著,像睡著了一般读跷。 火紅的嫁衣襯著肌膚如雪梗搅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天效览,我揣著相機與錄音无切,去河邊找鬼。 笑死丐枉,一個胖子當著我的面吹牛哆键,可吹牛的內容都是我干的。 我是一名探鬼主播瘦锹,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼籍嘹,長吁一口氣:“原來是場噩夢啊……” “哼闪盔!你這毒婦竟也來了?” 一聲冷哼從身側響起辱士,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤泪掀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后识补,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體族淮,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年凭涂,在試婚紗的時候發(fā)現(xiàn)自己被綠了祝辣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡切油,死狀恐怖蝙斜,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情澎胡,我是刑警寧澤孕荠,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站攻谁,受9級特大地震影響稚伍,放射性物質發(fā)生泄漏。R本人自食惡果不足惜戚宦,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一个曙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧受楼,春花似錦垦搬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至河狐,卻和暖如春米绕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背甚牲。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工义郑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人丈钙。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓非驮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親雏赦。 傳聞我的和親對象是個殘疾皇子劫笙,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內容