關(guān)于Electron原生模塊編譯的一點(diǎn)總結(jié)

Electron是PC端的跨平臺(tái)開(kāi)發(fā)框架,我們可以通過(guò)nodejs去調(diào)用其提供的各種底層API。但Electron為了保證自身文件體積較小和可持續(xù)開(kāi)發(fā),對(duì)API的數(shù)量進(jìn)行了控制。好在,Electron同樣支持Nodejs原生模塊,只不過(guò),需要用Electron的頭文件進(jìn)行重編譯。

項(xiàng)目原本的npm庫(kù)管理很亂,各級(jí)目錄下都有package.json,且沒(méi)有同步所有用到的,也沒(méi)有通過(guò)package-lock.json進(jìn)行版本號(hào)管理。因此,之前若想在新的設(shè)備,尤其非mac os上重新配下開(kāi)發(fā)和打包環(huán)境,很難。?;径际强渴謩?dòng)復(fù)制node_modules...

出于近期需要在linux上搭建一套開(kāi)發(fā)環(huán)境的契機(jī),對(duì)整個(gè)項(xiàng)目的架構(gòu)進(jìn)行重新梳理,重點(diǎn)就是npm庫(kù)。因?yàn)閾Q了操作系統(tǒng),項(xiàng)目涉及到的Native庫(kù),需要重新編譯。這里,我們以兩個(gè)Native庫(kù)為例,具體介紹下如何在不同系統(tǒng)下重編譯Electron的Native庫(kù):canvassqlite3

配置npmrc

只是Electron官方文檔給出的方案,通過(guò)在.npmrc文件中配置相關(guān)環(huán)境變量,幫助npm在下載Native模塊時(shí),自動(dòng)下載其對(duì)應(yīng)的Electron版本。

npm config ls -l

.npmrc在不同系統(tǒng)下的路徑不一樣,通過(guò)上面的命令找到其位置,手動(dòng)添加一下內(nèi)容:

// Electron
target=1.7.11
arch=x64
target_arch=x64
disturl=https://atom.io/download/electron
runtime=electron
build_from_source=true
//target_platform=darwin

target表示要編譯的Electron版本,需要與你本地的Electron版本號(hào)一致。這里1.7.x,x有差異不影響,否則,可能會(huì)報(bào)錯(cuò):

'xx.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 57. This version of Node.js requires
NODE_MODULE_VERSION 54. Please try re-compiling or re-installing

手動(dòng)編譯

Nodejs的Native模塊,其根目錄下都有binding.gyp這個(gè)文件,這是Chromium團(tuán)隊(duì)為nodejs跨平臺(tái)設(shè)計(jì)的一種文件。通過(guò)node-gyp或者node-pre-gyp等nodejs命令工具,可以對(duì)Native模塊進(jìn)行重編譯。

npm i -g node-gyp

使用node-gyp前,系統(tǒng)需要事先安裝好以下環(huán)境:

Mac OS

  1. Xcode, 在Terminal上運(yùn)行xcode-select --install
  2. Python v2.7, 一般已經(jīng)默認(rèn)安裝

Windows

npm i -g production windows-build-tools

Linux

  1. C/C++工具,例如GCC
  2. python v2.7

node-gyp手動(dòng)編譯Electron模塊:

cd node_modules/addon

node-gyp rebuild --target=1.7.11 --arch=x64 --target_platform=darwin --dist-url=https://atom.io/download/atom-shell

若配過(guò).npmrc,直接node-gyp rebuild即可。

實(shí)踐

簡(jiǎn)單的Native庫(kù),在配置了npmrc后,能直接下載成功,得到需要的.node文件。也有部分,除了Electron的Headers,還需要本地環(huán)境的支持。例如:canvassqlite3

  • canvas

    canvas是基于Cairo的圖片處理庫(kù),該庫(kù)的編譯需要本地事先安裝好以下環(huán)境:

    OS Command
    OS X Using Homebrew: brew install pkg-config cairo pango libpng jpeg giflib librsvg
    Ubuntu sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
    Fedora sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel
    Solaris pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto
    Windows See the wiki

    以上環(huán)境安裝完成后:

    cd node_modules/canvas

    node-gyp rebuild

    可以看到canvas/build/Release/下生成canvas.node文件

  • sqlite3

    sqlite3本身的編譯不算復(fù)雜,麻煩的是building for sqlcipher。編譯加密的sqlite3版本。

    MacOS

    npm install sqlite3 --build-from-source --sqlite_libname=sqlcipher --sqlite=`brew --prefix` --runtime=electron --target=1.7.11 --dist-url=https://atom.io/download/electron
    

    或者:

    cd node_modules/sqlite3

    node-gyp rebuild --sqlite_libname=sqlcipher --sqlite=`brew --prefix` --runtime=electron --target=1.7.11 --dist-url=https://atom.io/download/electron --module_path=../lib/binding/electron-v1.7-darwin-x64  --module_name=node-sqlite3
    

    macos上沒(méi)有遇到什么問(wèn)題,但在linux上折騰了很久。因?yàn)閟qlite3加密也需要底層環(huán)境的各種支持,如基本的g++,sqlite編譯需要的libsqlite3-devld模塊需要的sqlcipher等等。這些問(wèn)題因?yàn)闆](méi)什么普適性,就不展開(kāi)講,解決辦法也就是根據(jù)報(bào)錯(cuò)去Google。

總結(jié)

Nodejs的原生模塊,Electron本身也有提供electron-rebuild這樣的工具,也介紹了如何配置來(lái)實(shí)現(xiàn)Native模塊的自動(dòng)編譯,目前還沒(méi)有去嘗試??紤]到一般情況下,是在一臺(tái)機(jī)子上打包三個(gè)平臺(tái)的安裝包,終究是要在不同操作系統(tǒng)下去對(duì)Native模塊重編譯的,所以,掌握好node-gyp的手動(dòng)編譯更重要些。。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容