1. 程式人生 > >electron打包web專案之stackedit實戰——反面教材

electron打包web專案之stackedit實戰——反面教材

很抱歉,誤導大家了。electron只支援客戶端web專案,package.json裡的scripts欄位太誤導人了。讓我傻傻地以為真的可以在裡面寫一個 node server.js呢。辛虧我照著自己寫的部落格重新試了一遍,我發現我之所以能成功是因為我事先已經執行過一次node server.js,electron內部就是一個webkit,有快取,所以能成功。stackedit快取太厲害了,只要你用瀏覽器開啟過一次,下次就能在瀏覽器上繼續使用(即使沒有開啟node服務!)。除非你手動清空快取。大家要以我為戒,不要在一知半解地情況下碰巧成功了就草草寫部落格,很容易誤導人的!本文是個反面教材,反面教材,反面教材!

引子

如果您不感興趣,直接跳過這一段。

幾年前我上大學那會兒,自學了一下MFC和windows程式設計,當時傻傻地以為要在windows上編寫一個程式給別人用,只能用MFC呢。然後就去學了,然後畢業就搞Java了。現在回想起來,其實那時候MFC已經沒落了,如今MFC應該是徹底退出歷史舞臺了吧。誰要是還在用MFC,請過來打一下我的臉。說實話MFC是個好東西,速度快,編譯出來的exe也非常小。我雖然沒趕上MFC風光的年代,卻也勉強算見證了MFC被淘汰的過程。
之前想找一個C++的IDE。然後找了2款軟體,一個是微軟的VSCode,另一個是Code::Blocks。VSCode啟動速度的確很快,然後有人就說了,微軟一出手,讓你們看看什麼叫專業!然後我試了一下,結論就一個字:垃圾,文件也爛到家。你用VSCode開發其他的還好,搞C++就算了吧,要麼乖乖的用龐大的VS,要麼用codeblocks吧。如果您不信,儘管去折騰。我一直以為VSCode是用MFC之類的庫寫的呢,直到我在electron官網上看到VSCode後,我更加確信MFC真的淘汰了,就像IE一樣的隱退了——雖然它們曾經是王者。傳統MFC,swing開發桌面程式效率太低。大名鼎鼎的Atom也用了electron,顯然用Web來開發桌面程式已經走上歷史舞臺。Java裡的swing也被JavaFx取代(不知道有沒人用這個)。

緣由

最近想找一個開源趁手的markdown工具,看到有同事用的是typora,這個軟體確實挺好,可惜將來要收費的。於是我找到了stackedit這個工具,可惜是web版的,必須要用瀏覽器開啟,不能alt+tab來切換應用略微不爽。而且本地使用還必須把node服務開起來,就更不爽了。既然這樣何不把stackedit打包成一個exe程式呢,這樣別人也可以方便使用啊。網上搜了一下,打包web程式的主要有兩款工具,一個是node-webkit(現在叫nw),一個是electron。選擇electron是因為社群活躍,而且有成功的例子。

最終效果

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

本地執行stackedit

週末花了兩天時間,終於搞定了。看完本文後你也可以輕鬆打造屬於你自己的桌面應用了。本文就是用自己打包的stackedit.exe寫的。
事實上我是先在csdn上寫的,中間出問題了,加上font標籤後它不給我回車了。有的程式碼片段我只用了2個反引號,不知道是不是跟這樣有關係。

1.下載stackedit分發包。

2.準備構建環境

開啟doc資料夾下的developer-guide.md檔案。看到 Pre-requisites:

  • [Git][1]
  • [node.js/npm][2]
  • [Gulp][3]
  • [Bower][4]

2.1安裝git

下載後一路next安裝就可以了。不會使用git也沒關係,這裡只是讓構建通過。
注意:裝好之後一定要把git的安裝目錄加入到環境變數,否則npm install的時候會報找不到git的錯誤:

npm ERR! No git binary found in $PATH
npm ERR! Failed using git.
npm ERR! Please check if you have git installed and in your PATH.

2.2安裝node.js

新版的node.js自帶了npm(相當於maven的一個東西),直接安裝新版的node.js就好了。如果您不熟悉,直接一路next預設安裝就好了。
注意: 為了您安裝方便,建議您給Nodejs加一個淘寶的映象源,網上很多教程這裡不再贅述。
注意:安裝完之後一定要將npm全域性包目錄新增到環境變數裡。否則執行bower install時會報沒有許可權的錯誤:

Errno::EPERM (Operation not permitted @ unlink_internal - /Users/James/Desktop/appname/public):

npm預設的全域性包目錄是:C:\Users\使用者名稱\AppData\Roaming\npm。把這個新增到環境變數即可。

2.3安裝gulp

gulp是一個壓縮工具,可以壓縮.js,.css等檔案。
先安裝到全域性
npm install -g gulp
然後安裝到本地,–save表示安裝到當前目錄並且在package.json裡新增依賴。
npm install gulp --save

2.4安裝bower

Bower是一個客戶端技術的軟體包管理器,它可用於搜尋、安裝和解除安裝如JavaScript、HTML、CSS之類的網路資源。
先安裝到全域性
npm install -g bower
再安裝到本地
npm install bower --save

3.構建stackedit

進入到stackedit

cd stackedit-4.3.14
npm install
bower install

本地執行stackedit

cd stackedit-4.3.14
node server.js

瀏覽器位址列輸入http://localhost:3000/ 就可以使用stackedit了。這個跟csdn上的很像哦。

使用electron打包stackedit

4.安裝electron

使用npm install -g electron 安裝不了,我們使用淘寶的cnpm
//首先安裝cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org

//使用cnpm安裝electron,使用方法和npm相同
cnpm install -g electron

5.新建一個electron的app

5.1在D盤下新建一個資料夾app

據說electron要求必須放在app目錄下,所以我就這樣做了。

5.2在D:\app下新建兩個檔案:

package.json

{
"name"    : "stackedit",
"version" : "0.1.0",
"main"    : "main.js",
"scripts": {
        "start": "node stackedit-4.3.14/server.js"
    }
}

這裡的name就是electron app的名字。
main.js,主要負責建立一個視窗。
scripts就是electron啟動時要執行的指令碼,我們這裡是開啟nodejs服務。stackedit是個web專案,不是個靜態的html專案,所以這裡開啟服務至關重要。

main.js

const electron = require('electron'); 
// 控制應用生命週期的模組
const {app} = electron; 
// 建立本地瀏覽器視窗的模組
const {BrowserWindow} = electron; 

// 指向視窗物件的一個全域性引用,如果沒有這個引用,那麼當該javascript物件被垃圾回收的
// 時候該視窗將會自動關閉
let win; 

function createWindow() { 
  // 建立一個新的瀏覽器視窗
  win = new BrowserWindow({width: 1920, height: 1080, webPreferences: {nodeIntegration: false}}); 

  // 並且裝載應用的index.html頁面
  // win.loadURL(`file://${__dirname}/index.html`);
  win.loadURL("http://localhost:3000/"); 


  // 開啟開發工具頁面
  // win.webContents.openDevTools();

  // 當視窗關閉時呼叫的方法
  win.on('closed', () => { 
    // 解除視窗物件的引用,通常而言如果應用支援多個視窗的話,你會在一個數組裡
    // 存放視窗物件,在視窗關閉的時候應當刪除相應的元素。
    win = null; 
  }); 
} 

// 當Electron完成初始化並且已經建立了瀏覽器視窗,則該方法將會被呼叫。
// 有些API只能在該事件發生後才能被使用。
app.on('ready', createWindow); 
/*
 * var mainWindow = new BrowserWindow({ webPreferences: { nodeIntegration: false }
 * });
 */
// 當所有的視窗被關閉後退出應用
app.on('window-all-closed', () => { 
  // 對於OS X系統,應用和相應的選單欄會一直啟用直到使用者通過Cmd + Q顯式退出
  if (process.platform !== 'darwin') { 
    app.quit(); 
  } 
}); 

app.on('activate', () => { 
  // 對於OS X系統,當dock圖示被點選後會重新建立一個app視窗,並且不會有其他
  // 視窗開啟
  if (win === null) { 
    createWindow(); 
  } 
}); 

// 在這個檔案後面你可以直接包含你應用特定的由主程序執行的程式碼。
// 也可以把這些程式碼放在另一個檔案中然後在這裡匯入。

stackedit原始碼里根本沒有index.html。它的首頁是http://localhost:3000
所以你可以看到win.loadURL(“http://localhost:3000/“)這一句,寫的不是index.html!
注意:如果這裡寫的是http,那麼
win = new BrowserWindow({width: 1920, height: 1080, webPreferences: {nodeIntegration: false}});
這裡就要加一個nodeIntegration:false,否則,後面打包後頁面不能跳轉!

5.3新增web專案

將之前構建好的stackedit-4.3.14資料夾拷貝到D:\app目錄下。

5.4嘗試使用electron啟動stackedit

先別急著打包,因為打包要相當長的一段時間,而且打包完成之後,會生成很多的資料夾,層級很多導致刪除不了。血淋淋的教訓啊,所以一定要先測試一下:

cd /d D:\app
electron .

如果成功了,開始匯出,不成功一定是哪個地方出錯了,修改後再來過。

5.5正式打包

我們使用electron-packager打包,所以要安裝一下

cnpm install -g electron-packager

electron-packager D:\app stackedit --platform=win32 --arch=x64 --electron-version=1.6.11 --out D:\Mystackedit --icon=D:\stackedit.ico

D:\app是electron的應用所在的目錄,stackedit是這個應用的名字。
注意: 以前指定版本用–version,現在要用–electron-version了。
–out指定打包後輸出目錄,
–icon是給咱們的桌面程式新增一個圖示,不然預設的圖示就是electron的圖示。
注意:electron好像只支援.ico檔案。我試過了,用.png沒成功。
等待約10分鐘,程式就打包好了。在D:\Mystackedit4\stackedit-win32-x64目錄下會有一個stackedit.exe檔案。

題外話

刪除electron打包後的資料夾太深了刪除不了怎麼辦?

1.管理員身份開啟C:\Windows\System32\cmd.exe
2.cd D:\Mystackedit
3.在這個目錄下新建一個aa資料夾
4.Robocopy /MIR aa stackedit-win32-x64
5.然後就可以刪除D:\Mystackedit這個空檔案夾了

圖示怎麼做的?

1.把stackedit官網的圖片下載下來,是一個logo.svg檔案
2.線上把logo.svg圖片轉成logo.png檔案
3.美圖秀秀把logo.png剪裁一下,並且去除背景色(或者叫底色,我也不知道怎麼稱呼,反正背景弄成透明的就行了),生成logo2.png
4.線上把logo2.png轉成ico檔案,生成stackedit.ico。把它放在D盤根目錄下,打包時加上–icon=D:\stackedit.ico。