關於Electron原生模組編譯的一點總結

Charles0427發表於2019-01-07

Electron是PC端的跨平臺開發框架,我們可以通過nodejs去呼叫其提供的各種底層API。但Electron為了保證自身檔案體積較小和可持續開發,對API的數量進行了控制。好在,Electron同樣支援Nodejs原生模組,只不過,需要用Electron的標頭檔案進行重編譯。

專案原本的npm庫管理很亂,各級目錄下都有package.json,且沒有同步所有用到的,也沒有通過package-lock.json進行版本號管理。因此,之前若想在新的裝置,尤其非mac os上重新配下開發和打包環境,很難。。基本都是靠手動複製node_modules...

出於近期需要在linux上搭建一套開發環境的契機,對整個專案的架構進行重新梳理,重點就是npm庫。因為換了作業系統,專案涉及到的Native庫,需要重新編譯。

配置npmrc

Electron官方文件給出的方案,通過在.npmrc檔案中配置相關環境變數,幫助npm在下載Native模組時,自動下載其對應的Electron版本。

npm config ls -l

.npmrc在不同系統下的路徑不一樣,通過上面的命令找到其位置,手動新增一下內容:

// 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版本號一致。這裡1.7.x,x有差異不影響,否則,可能會報錯:

'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
複製程式碼

手動編譯

Nodejs的Native模組,其根目錄下都有binding.gyp這個檔案,這是Chromium團隊為nodejs跨平臺設計的一種檔案。通過node-gyp或者node-pre-gyp等nodejs命令工具,可以對Native模組進行重編譯。

npm i -g node-gyp

使用node-gyp前,系統需要事先安裝好以下環境:

Mac OS

  1. Xcode, 在Terminal上執行xcode-select --install
  2. Python v2.7, 一般已經預設安裝

Windows

npm i -g production windows-build-tools

Linux

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

node-gyp手動編譯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

若配過.npmrc,直接node-gyp rebuild即可。

實踐

簡單的Native模組,在配置了npmrc後,能直接下載成功,得到需要的.node檔案。也有部分,除了Electron的Headers,還需要本地環境的支援。例如:canvassqlite3

  • canvas

    canvas是基於Cairo的圖片處理庫,該庫的編譯需要本地事先安裝好以下環境:

    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

    以上環境安裝完成後:

    cd node_modules/canvas

    node-gyp rebuild

    可以看到canvas/build/Release/下生成canvas.node檔案

  • sqlite3

    sqlite3本身的編譯不算複雜,麻煩的是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上沒有遇到什麼問題,但在linux上折騰了很久。因為sqlite3加密也需要底層環境的各種支援,如基本的g++,sqlite編譯需要的libsqlite3-devld模組需要的sqlcipher等等。這些問題因為沒什麼普適性,就不展開講,解決辦法也就是根據報錯去Google。

總結

Nodejs的原生模組,Electron本身也有提供electron-rebuild這樣的工具,也介紹瞭如何配置來實現Native模組的自動編譯,目前還沒有去嘗試。考慮到一般情況下,是在一臺機子上打包三個平臺的安裝包,終究是要在不同作業系統下去對Native模組重編譯的,所以,掌握好node-gyp的手動編譯更重要些。。

相關文章