日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

10分钟实现Typora(markdown)编辑器

發(fā)布時間:2023/12/19 综合教程 34 生活家
生活随笔 收集整理的這篇文章主要介紹了 10分钟实现Typora(markdown)编辑器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本章主要內(nèi)容:

介紹我們將在接下來的幾章中構(gòu)建的應(yīng)用程序

配置我們的CSS樣式表,使其看起來更像一個本機(jī)應(yīng)用程序

回顧在Electron中主進(jìn)程和渲染器進(jìn)程之間的關(guān)系

為我們的主進(jìn)程和渲染器進(jìn)程實(shí)現(xiàn)基本功能

在Electron渲染進(jìn)程中訪問Chrome開發(fā)者工具

我們的書簽管理器是一個很好的開始,但它只觸及了我們可以用Electron做什么。

在本章中,我們將更深入地探討,并為與用戶操作系統(tǒng)建立更緊密聯(lián)系的應(yīng)用程序打下基礎(chǔ)。在接下來的幾章中,我們將實(shí)現(xiàn)觸發(fā)操作系統(tǒng)用戶界面,對文件系統(tǒng)進(jìn)行讀寫和訪問剪貼板的功能。

我們正在構(gòu)建一個簡單的Markdown編輯器,它允許我們創(chuàng)建新的或打開現(xiàn)有的Markdown文件,將它們轉(zhuǎn)換為HTML,并將HTML保存到文件系統(tǒng)和剪貼板中。讓我們把這個應(yīng)用程序稱為Fire Sale,因?yàn)樗吘故且粋€廉價編輯器,只是稍微聰明一點(diǎn)而已。

在本章的最后,我們將討論在出現(xiàn)問題時調(diào)試Electron應(yīng)用程序的技術(shù)和工具。

定義我們的應(yīng)用

讓我們從為我們不起眼的小應(yīng)用程序設(shè)置目標(biāo)開始。

對于桌面應(yīng)用程序,我們的許多特性可能看起來有些平庸,這就是重點(diǎn)。它們是桌面應(yīng)用程序的標(biāo)準(zhǔn)配置,但完全超出了傳統(tǒng)web應(yīng)用程序的能力范圍,傳統(tǒng)web應(yīng)用程序無法訪問獨(dú)立瀏覽器選項(xiàng)卡之外的任何內(nèi)容。

我們的應(yīng)用程序?qū)⒂蓛蓚€窗格組成,用戶可以編寫或編輯Markdown和一個右窗格,該窗格以HTML形式呈現(xiàn)用戶的Markdown。在頂部有一系列按鈕,允許用戶從文件系統(tǒng)加載文本文件,并將結(jié)果寫入剪貼板或文件系統(tǒng)。

在應(yīng)用程序的第一階段,我們構(gòu)建了以下的界面。在圖3.1。我們還可以向效果圖(以及隨后的應(yīng)用程序)添加額外的用戶界面元素,但這是一個很好的開始。

圖3.1 我們的應(yīng)用程序的線框顯示,用戶可以在左側(cè)窗格中輸入文本,或者從用戶的文件系統(tǒng)的文件中加載文本。

在這一章中,我們?yōu)槲覀兊膽?yīng)用奠定了基礎(chǔ)。我們創(chuàng)建項(xiàng)目的結(jié)構(gòu),安裝依賴項(xiàng),設(shè)置主進(jìn)程和呈現(xiàn)器進(jìn)程,構(gòu)建用戶界面,并在用戶向左側(cè)窗格輸入文本時實(shí)現(xiàn)markdown到HTML的轉(zhuǎn)換。

我們將在接下來的幾章中分階段構(gòu)建應(yīng)用程序的其余部分。在每一章中,您將下載我們應(yīng)用程序的當(dāng)預(yù)期目標(biāo)代碼。通過這種方式,您可以切換到一個章節(jié),其中包含您感興趣的功能,而不必從頭構(gòu)建整個應(yīng)用程序。

在第一階段,我們的應(yīng)用程序?qū)⒛軌?/p>

打開并保存文件到文件系統(tǒng)

從這些文件獲取Markdown內(nèi)容

將Markdown內(nèi)容呈現(xiàn)為HTML

將生成的HTML保存到文件系統(tǒng)中

將生成的HTML寫入剪貼板

在后面的章節(jié)中,我們的應(yīng)用程序使用本地操作系統(tǒng)接口跟蹤最近打開的文檔。我們可以將Markdown文件從Finder或Windows資源管理器拖放到應(yīng)用程序上,并讓應(yīng)用程序立即打開該Markdown文件。當(dāng)我們右鍵單擊應(yīng)用程序的不同區(qū)域時,應(yīng)用程序?qū)⒂凶约旱淖远x應(yīng)用程序菜單和自定義上下文菜單。

我們還利用了操作系統(tǒng)特有的特性,比如更新應(yīng)用程序的標(biāo)題欄,以顯示當(dāng)前打開的文件,以及自上次保存以來是否已經(jīng)更改。如果計(jì)算機(jī)上的其他應(yīng)用程序在打開文件時更改了文件,我們還實(shí)現(xiàn)了其他功能,比如更新應(yīng)用程序中的內(nèi)容。

奠定基礎(chǔ)

如圖3.2所示的文件結(jié)構(gòu)與我們在前一章中商定并用于書簽管理器的結(jié)構(gòu)非常相似。

為了簡化和清晰,在我們繼續(xù)熟悉Electron時,我們在app/main.js中保存了主進(jìn)程的所有代碼,在app/renderer.js中保存了單渲染器進(jìn)程的所有代碼。我們將app文件夾存儲在基于unix的操作系統(tǒng)上,以便能夠快速生成它,如下面的清單所示?;蛘?,您可以在GitHub上查看這個項(xiàng)目的主分支,網(wǎng)址是https://github.com/electron-in-action/firesale。

圖3.2 我們工程結(jié)構(gòu)

列表3.1 生成應(yīng)用文件結(jié)構(gòu)

mkdir app  && touch app/index.html app/main.js app/renderer.js app/style.css

項(xiàng)目的各個部分是

index.html-包含所有為UI提供結(jié)構(gòu)的HTML標(biāo)記

main.js-包含我們的主進(jìn)程的代碼

renderer.js-包含UI的所有交互代碼

style.css-包含樣式的CSS

package.json-包含所有依賴項(xiàng),并在啟動主進(jìn)程時將Electron指向main.js

為了簡單起見,除了Electron之外,我們還從兩個依賴項(xiàng)開始作為運(yùn)行時。我們使用一個名為marked的庫來處理Markdown到HTML轉(zhuǎn)換的繁重工作。

對于這個項(xiàng)目,通過運(yùn)行npm init --yes生成一個package.json。--yes標(biāo)記允許您跳過前一章中的提示。生成package.json之后,運(yùn)行以下命令安裝必要的依賴項(xiàng):

npm install electron marked --save

圖3.3 Electron首先尋找我們的主進(jìn)程,它負(fù)責(zé)生成一個或多個渲染器進(jìn)程,其負(fù)責(zé)顯示我們的UI。

引導(dǎo)程序

在我們package.json的main條目被配置為加載index.js作為應(yīng)用程序的主進(jìn)程。如圖3.3所示,我們需要將其調(diào)整為app/main.js。我們還需要一個渲染器進(jìn)程,為用戶提供應(yīng)用程序的界面。在app/main.js中,讓我們添加如下代碼。

列表3.2 引導(dǎo)主進(jìn)程: ./app/main.js

 1 const{ app, BrowserWindow } = require('electron')
 2 ?
 3 //在頂層聲明mainWindow,以便在“ready”事件完成后不會將其回收為垃圾
 4 let mainWindow = null;
 5 ?
 6 app.on('ready', () => {
 7     //使用默認(rèn)屬性創(chuàng)建一個新的BrowserWindow
 8     mainWindow = new BrowserWindow({
 9         webPreferences: {
10             // webPreferences中的nodeIntegrationInWorker選項(xiàng)設(shè)置為true,Electron5.x以后,缺省為false
11             nodeIntegration: true
12         }
13     })
14 ?
15     //在剛才創(chuàng)建的BrowserWindow實(shí)例中加載app/index.html
16     mainWindow.loadFile('app/index.html');
17 ?
18     mainWindow.on('closed', () => {
19         //在窗口關(guān)閉時將進(jìn)程設(shè)置為null
20         mainWindow = null;
21     });
22 });

這足以啟動我們的應(yīng)用程序。也就是說,由于我們的主進(jìn)程目前在渲染器進(jìn)程中加載了一個空文件,所以沒有發(fā)生太多事情。

實(shí)現(xiàn)用戶界面

在Electron中要獲得圖3.1中效果圖的可行版本,實(shí)現(xiàn)必要的HTML和CSS是相當(dāng)容易的。因?yàn)槲覀冎恍枰С忠粋€瀏覽器,而這個瀏覽器支持web平臺提供的最新和最強(qiáng)大的特性,如圖3.4所示。

圖3.4 主進(jìn)程將創(chuàng)建一個渲染器程序進(jìn)程并告訴它加載index.html。然后,它將像在瀏覽器中一樣加載CSS和JavaScript。

在index.html,我們添加清單3.3中的標(biāo)記來創(chuàng)建圖3.5中的瀏覽器窗口。

圖3.5 開始我們第一個未樣式化的Electron應(yīng)用

列表3.3 我們應(yīng)用的標(biāo)記:./app/index.html

 1 <!DOCTYPE html>
 2 <html>
 3  <head>
 4  <meta charset="UTF-8">
 5  <meta name="viewport" content="width=device-width,initial-scale=1">
 6  <title>Fire Sale</title>
 7  <link rel="stylesheet" href="style.css" type="text/css">
 8  </head>
 9  <body> 
10      <!--控件部分在頂部添加了用于打開和保存文件的按鈕。稍后我們將向這些按鈕添加功能。-->
11  <section class="controls"> 
12  <button id="new-file">New File</button>  
13  <button id="open-file">Open File</button>
14  <button id="save-markdown" disabled>Save File</button>
15  <button id="revert" disabled>Revert</button>
16  <button id="save-html">Save HTML</button>
17  <button id="show-file" disabled>Show File</button>
18  <button id="open-in-default" disabled>Open in Default Application</button>
19  </section>
20      <!--我們的應(yīng)用程序允許使用.raw-markdown類編寫和編輯文本區(qū)域中的內(nèi)容,并使用.rendered-html類在div元素中呈現(xiàn)該內(nèi)容。-->
21  <section class="content"> 
22      <!--<label>標(biāo)簽是可選的,并且包含了這些標(biāo)簽,以使視障用戶更容易訪問應(yīng)用程序。 -->
23     <label for="markdown" hidden>Markdown Content</label> 
24     <textarea class="raw-markdown" id="markdown"></textarea>
25     <div class="rendered-html" id="html"></div>
26     </section> 
27     </body> 
28     <!--在文件末尾的標(biāo)記中,我們需要渲染進(jìn)程的代碼,它位于同一個目錄中的renderer.js中。 -->
29     <script> 
30     require('./renderer'); 
31     </script>
32    </html>

我們的應(yīng)用程序目前還沒有太多需要查看的地方。

如果您和我一樣,您對我在效果圖中引入的兩列接口有點(diǎn)懷疑。在討論如何使用HTML和CSS實(shí)現(xiàn)列時,很少使用easy這個詞。

幸運(yùn)的是,我們可以自信地使用添加到CSS3的名為Flexbox的新布局模式來快速定義應(yīng)用程序的兩列布局。Flexbox使創(chuàng)建頁面布局變得很容易,可以在各種屏幕大小范圍內(nèi)進(jìn)行可預(yù)測的操作,如清單3.4所示。它對CSS來說是相對較新的,直到最近才得到Internet Explorer的支持。

正如我們在第1章和第2章中討論的,我們的應(yīng)用程序總是跟上Chrome的最新版本,所以我們可以放心地使用Flexbox布局模式,而不用擔(dān)心跨瀏覽器兼容性。

使用Flexbox創(chuàng)建頁面布局:./app/style.css

/*選擇一個更新的CSS框模型,它將正確地設(shè)置元素的寬度和高度*/
html {
    box-sizing: border-box;
}   
?
/* 將此設(shè)置傳遞給頁面上的所有其他元素和偽元素*/
*, *:before, *:after {
    box-sizing: inherit;
}
?
html, body {
    height: 100%;
    width: 100%;
    overflow: hidden;
}
?
body {
    margin: 0;
    padding: 0;
    position: absolute;
}
?
/* 在整個應(yīng)用程序中使用操作系統(tǒng)的默認(rèn)字體 */
body, input {
    font: menu;
}
?
/*移除瀏覽器圍繞活動輸入字段的默認(rèn)突出顯示*/
textarea, input, div, button {
    outline: none; 
    margin: 0; 
 } 
?
.controls {
    background-color: rgb(217, 241, 238);
    padding: 10px 10px 10px 10px;
}
   
button {
    font-size: 14px;
    background-color: rgb(181, 220, 216);
    border: none;
    padding: 0.5em 1em;
   
}
   
button:hover {
    background-color: rgb(156, 198, 192);
}
   
button:active {
    background-color: rgb(144, 182, 177); 
}
?
button:disabled {
    background-color: rgb(196, 204, 202);
}
?
.container {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-width: 100vw;
    position: relative;  
}
   
/* 使用Flexbox對齊應(yīng)用程序的兩個窗格*/
.content { 
    height: 100vh; 
    display: flex; 
}
   
/* 使用Flexbox將兩個窗格設(shè)置為相同的寬度 */
.raw-markdown, .rendered-html {
    min-height: 100%;
    max-width: 50%;
    flex-grow: 1; 
    padding: 1em;
     overflow: scroll; 
      font-size: 16px;
}
?
.raw-markdown {
    border: 5px solid rgb(238, 252, 250);;
    background-color: rgb(238, 252, 250);
    font-family: monospace;
}

樣式表有兩個主要目標(biāo)。首先,我們想利用像Flexbox這樣的現(xiàn)代CSS特性來設(shè)計(jì)我們的UI。其次,我們希望采取一些小步驟,使應(yīng)用程序的外觀和感覺更像一個真實(shí)的web應(yīng)用程序(參見圖3.6)。

圖3.6 我們的應(yīng)用程序已經(jīng)使用CSS的現(xiàn)代特性給出了一些基本的樣式。

box-sizing屬性在CSS中處理一個歷史上的奇怪現(xiàn)象,在一個寬度為200像素的元素中添加50個像素的填充將導(dǎo)致它的寬度為300像素(每邊添加50個像素的填充),對于邊框也是一樣。

當(dāng)box-sizing被設(shè)置為border-box時,我們的元素會考慮到我們設(shè)置它們的高度和寬度。總的來說,這是一件好事。在這個CSS規(guī)則中,我們還讓所有其他元素和偽元素都尊重我們通過將box-sizing設(shè)置為border-box所做的艱苦工作。

我們希望我們的應(yīng)用程序能夠適應(yīng)本地應(yīng)用程序。朝著這個方向邁出的重要一步是使用所有其他應(yīng)用程序都使用的系統(tǒng)字體。例如,盡管macOS在整個操作系統(tǒng)中使用San Francisco作為默認(rèn)字體,但它不能作為常規(guī)字體使用。我們將font屬性設(shè)置為menu,它依賴于操作系統(tǒng)來使用它的默認(rèn)字體——即使我們無法訪問它。

瀏覽器在當(dāng)前活動的UI元素周圍設(shè)置一個邊框。在macOS中,這個邊框是藍(lán)色的輝光。您可能從未過多地考慮過它,因?yàn)槲覀円呀?jīng)習(xí)慣了在web上使用它,但是當(dāng)我們開發(fā)桌面應(yīng)用程序時,它看起來并不合適。在我們的應(yīng)用程序中,它看起來尤其糟糕,其中一半的UI實(shí)際上是一個大型文本輸入。通過將outline設(shè)置為none,我們刪除了活動元素周圍的非自然輝光。

.content.raw-markdown.rendered-html規(guī)則中,我們實(shí)現(xiàn)了一個簡單的Flexbox布局,這將使我們的應(yīng)用程序看起來更像我們在圖3.1中介紹的效果。content類的元素將包含我們的兩列。我們將display屬性設(shè)置為flex,以使用前面討論的Flexbox技術(shù)。下一步,我們設(shè)置flex- growth,它指定flex項(xiàng)的增長因子, 當(dāng)然可以。把它看作元素的尺度相對于它的兄弟元素可能是有幫助的。在本例中,我們使用Flexbox將兩列設(shè)置為相等的比例。

優(yōu)雅地顯示瀏覽器窗口

如果你仔細(xì)觀察你的應(yīng)用程序的啟動,您將注意到,在Electron加載index.html并在窗口中呈現(xiàn)DOM之前,窗口完全為空。用戶不習(xí)慣在本地應(yīng)用程序中看到這種情況,我們可以通過重新思考如何啟動窗口來避免這種情況。

如果您認(rèn)為應(yīng)用程序第一次啟動時的虛無閃光是無意義的,考慮主進(jìn)程中的代碼:它創(chuàng)建一個窗口,然后在其中加載內(nèi)容。如果我們隱藏窗口直到內(nèi)容被加載呢?然后,當(dāng)UI準(zhǔn)備好時,我們顯示窗口,并避免短暫地暴露一個空窗口。

列表3.5 當(dāng)DOM就緒時優(yōu)雅地顯示窗口

 1 app.on('ready', () => {
 2     //使用默認(rèn)屬性創(chuàng)建一個新的BrowserWindow
 3     mainWindow = new BrowserWindow({
 4         show: false,
 5         webPreferences: {
 6             // webPreferences中的nodeIntegrationInWorker選項(xiàng)設(shè)置為true,Electron5.x以后,缺省為false
 7             nodeIntegration: true
 8         }
 9     })
10 ?
11     //在剛才創(chuàng)建的BrowserWindow實(shí)例中加載app/index.html
12     mainWindow.loadFile('app/index.html');
13 ?
14     mainWindow.once('ready-to-show', () => {
15         //當(dāng)DOM就緒時顯示窗口。
16         mainWindow.show();
17     });
18     
19     mainWindow.on('closed', () => {
20         //在窗口關(guān)閉時將進(jìn)程設(shè)置為null
21         mainWindow = null;
22     });
23 });

我們將一個對象傳遞給BrowserWindow構(gòu)造函數(shù),默認(rèn)情況下將其設(shè)置為hidden。當(dāng)BrowserWindow實(shí)例觸發(fā)它的“ready-to-show”事件時,我們將調(diào)用它的show()方法,這將在UI完全準(zhǔn)備好運(yùn)行后使它不再隱藏。當(dāng)應(yīng)用程序通過網(wǎng)絡(luò)加載遠(yuǎn)程資源時,這種方法甚至更有用,因?yàn)槌跏蓟撁婵赡苄枰L的時間。

實(shí)現(xiàn)基本功能

讓我們把一些基本功能放在適當(dāng)?shù)奈恢蒙稀τ诔鯇W(xué)者,我們希望在左窗格中的Markdown發(fā)生更改時更新右窗格中呈現(xiàn)的HTML視圖(參見圖3.7)。這就是我們唯一的依賴—Marked—發(fā)揮作用的地方。

圖3.7 我們將在左側(cè)窗格中添加一個事件監(jiān)聽器,它將以HTML的形式呈現(xiàn)標(biāo)記并顯示在右側(cè)窗格中。

引入依賴項(xiàng)很容易,因?yàn)槲覀兛梢允褂肗ode的require來引入marked。讓我們在app/renderer.js中添加以下內(nèi)容。

列表3.6 引入依賴: ./app/renderer.js

const marked = require('marked');

現(xiàn)在,我們可以通過變量marked使用Marked。鑒于我們在圖3.7中討論了應(yīng)用程序的功能,您可能已經(jīng)開始懷疑,在開發(fā)應(yīng)用程序時,我們將大量使用#markdown文本區(qū)域和#html元素。讓我們使用一對變量來存儲對每個元素的引用,以便更容易地使用它們,如清單3.7所示。在此過程中,我們還將為UI頂部的每個按鈕創(chuàng)建變量。

列表3.7 緩存DOM選擇器: ./app/renderer.js

const markdownView = document.querySelector('#markdown');
const htmlView = document.querySelector('#html');
const newFileButton = document.querySelector('#new-file');
const openFileButton = document.querySelector('#open-file');
const saveMarkdownButton = document.querySelector('#save-markdown');
const revertButton = document.querySelector('#revert');
const saveHtmlButton = document.querySelector('#save-html');
const showFileButton = document.querySelector('#show-file');
const openInDefaultButton = document.querySelector('#open-in-default');

我們還相當(dāng)頻繁地在htmlView中呈現(xiàn)Markdown,所以我們想給自己一個函數(shù),以便將來更容易實(shí)現(xiàn)。

列表3.8 轉(zhuǎn)換markdown到HTML: ./app/renderer.js

marked將我們要呈現(xiàn)的Markdown內(nèi)容作為第一個參數(shù),并將選項(xiàng)的對象作為第二個參數(shù)。我們希望避免意外的腳本注入,因此我們傳入了一個對象,并將sanitize屬性設(shè)置為true。

最后,我們向markdownView添加了一個事件監(jiān)聽器,它將在keyup上讀取它的內(nèi)容(在textarea元素中,內(nèi)容存儲在它的value屬性中),通過marked運(yùn)行它們,然后將它們加載到htmlView中。結(jié)果如圖3.8所示。

列表3.9 當(dāng)Markdown更改時重新呈現(xiàn)HTML: ./app/renderer.js

1 markdownView.addEventListener('keyup', (event) => {
2     const currentContent = event.target.value;
3     renderMarkdownToHtml(currentContent);
4 });

圖3.8 我們的應(yīng)用程序接受用戶在左窗格中鍵入的內(nèi)容,并在右窗格中將其自動呈現(xiàn)為HTML。該內(nèi)容由用戶提供,不屬于我們的應(yīng)用程序。

基本功能已經(jīng)就緒,我們準(zhǔn)備開始研究只有在Electron應(yīng)用程序中才可能實(shí)現(xiàn)的特性,首先從文件系統(tǒng)中讀寫文件開始。當(dāng)所有這些都完成后,應(yīng)用程序的呈現(xiàn)程序流程應(yīng)該是這樣的。

列表3.10 渲染進(jìn)程: ./app/renderer.js

 1 const marked = require('marked');
 2 ?
 3 const markdownView = document.querySelector('#markdown');
 4 const htmlView = document.querySelector('#html');
 5 const newFileButton = document.querySelector('#new-file');
 6 const openFileButton = document.querySelector('#open-file');
 7 const saveMarkdownButton = document.querySelector('#save-markdown');
 8 const revertButton = document.querySelector('#revert');
 9 const saveHtmlButton = document.querySelector('#save-html');
10 const showFileButton = document.querySelector('#show-file');
11 const openInDefaultButton = document.querySelector('#open-in-default');
12 ?
13 const renderMarkdownToHtml = (markdown) => {
14     htmlView.innerHTML = marked(markdown, { sanitize: true });
15 };
16 ?
17 markdownView.addEventListener('keyup', (event) => {
18     const currentContent = event.target.value;
19     renderMarkdownToHtml(currentContent);
20 });

調(diào)試Electron應(yīng)用程序

在理想的世界中,我們在編寫代碼時永遠(yuǎn)不會出錯。

接口和方法永遠(yuǎn)不會在不同的版本之間更改,而且您的作者不必每次發(fā)布本書中應(yīng)用程序使用的依賴項(xiàng)的新版本時都屏住呼吸。

我們并不生活在那個世界上。因此,我們可以使用開發(fā)工具幫助我們跟蹤并有望消除缺陷。

調(diào)試渲染器進(jìn)程

到目前為止,一切都進(jìn)行得相當(dāng)順利,但可能不久之后我們就必須調(diào)試一些棘手的情況。因?yàn)镋lectron應(yīng)用程序是基于Chrome的,所以我們在構(gòu)建Electron應(yīng)用程序時可以使用Chrome開發(fā)者工具就不足為奇了(圖3.9)。

調(diào)試渲染器過程相對簡單。Electron的默認(rèn)應(yīng)用程序菜單提供了一個命令來打開應(yīng)用程序中的Chrome開發(fā)工具。在第6章中,我們將學(xué)習(xí)如何創(chuàng)建我們自己的自定義菜單,并在您不希望將其公開給用戶的情況下消除此功能。

還有另外兩種訪問開發(fā)人員工具的方法。

在任何時候,您都可以按macOS上的Command-Option-IWindowsLinux上的Control-Shift-I打開工具(圖3.10)。此外,您還可以通過編程方式觸發(fā)開發(fā)人員工具。

BrowserWindow實(shí)例上的webcontent屬性有一個名為openDevTools()的方法。如清單3.11所示,這個方法將在調(diào)用它的BrowserWindow中打開開發(fā)工具。

圖3.9 Chrome開發(fā)工具在渲染器過程中可用,就像在基于瀏覽器的應(yīng)用程序中一樣。

圖3.10 該工具可以在Electron提供的默認(rèn)菜單中開或關(guān)。您還可以使用Windows上的Control-Shift-I或macOS上的Command-Option-I來觸發(fā)它們。

列表3.11 從主流程打開開發(fā)者工具: ./app/main.js

 1 app.on('ready', () => {
 2     mainWindow = new BrowserWindow({
 3         show: false,
 4         webPreferences: {
 5             nodeIntegration: true
 6         }
 7     });
 8     
 9     mainWindow.loadFile(`app/index.html`);
10 ?
11 ?
12     mainWindow.once('ready-to-show', () => {
13         mainWindow.show();
14         mainWindow.webContents.openDevTools(); //我們可以通過編程方式在主窗口加載開發(fā)工具時立即打開它。
15       });
16 ?
17     mainWindow.on('closed', () => {
18         mainWindow = null;
19     });
20 });
21  

調(diào)試主進(jìn)程

調(diào)試主進(jìn)程并不容易。Node Inspector是調(diào)試Node.js應(yīng)用程序的常用工具,為了提供一個可以調(diào)試主進(jìn)程的方法,Electron 提供了 --inspect開關(guān)。使用如下的命令行開關(guān)來調(diào)試 Electron 的主進(jìn)程:--insepct=[port] 當(dāng)這個開關(guān)用于 Electron 時,它將會監(jiān)聽 V8 引擎中有關(guān) port 的調(diào)試器協(xié)議信息。 默認(rèn)的port5858。

electron --inspect=5858 your/appCopy

使用VSCode進(jìn)行主進(jìn)程調(diào)試

Visual Studio Code是一個免費(fèi)的開放源碼的IDE,適用于Windows、Linux和macOS,并且是由Microsoft在Electron之上構(gòu)建的。Visual Studio Code提供了一組用于調(diào)試節(jié)點(diǎn)應(yīng)用程序的豐富工具,這使得調(diào)試Electron應(yīng)用程序比前面提到的要容易得多。

設(shè)置構(gòu)建任務(wù)的一種快速方法是讓Visual Studio Code在沒有構(gòu)建任務(wù)的情況下構(gòu)建應(yīng)用程序。 在Windows上按Control-Shift-B或在macOS上按Command-Shift-B,將提示您創(chuàng)建一個構(gòu)建任務(wù),如圖3.11所示。

圖3.11 在沒有適當(dāng)?shù)臉?gòu)建任務(wù)的情況下觸發(fā)構(gòu)建任務(wù),Visual Studio Code將提示為您創(chuàng)建一個。

列表3.12 在Windows的Visual Studio Code中設(shè)置構(gòu)建任務(wù): task.json

 1 {
 2 // 有關(guān) tasks.json 格式的文檔,請參見
 3     // https://go.microsoft.com/fwlink/?LinkId=733558
 4     "version": "2.0.0",
 5     "tasks": [
 6         {
 7             "type": "npm",
 8             "script": "start",
 9             "problemMatcher": []
10         }
11     ]
12 }

現(xiàn)在,當(dāng)您按下Windows上的Control-Shift-B或macOS上的Command-Shift-B時,您的電子應(yīng)用程序?qū)印_@不僅對于在Visual Studio Code中設(shè)置調(diào)試非常重要,而且通常也是啟動應(yīng)用程序的一種方便方法。下一步是設(shè)置Visual Studio Code來啟動應(yīng)用程序,并將其連接到其內(nèi)置調(diào)試器(圖3.12)。

要創(chuàng)建啟動任務(wù),請轉(zhuǎn)到上面的終端選項(xiàng)卡,并單擊配置默認(rèn)生成任務(wù)。Visual Studio Code將詢問您想要創(chuàng)建哪種配置文件。選擇Node并用清單3.13替換文件的內(nèi)容。

圖3.12 在Debug選項(xiàng)卡中,單擊gear, Visual Studio Code將創(chuàng)建一個配置文件,用于代表您啟動調(diào)試器。

列表3.13 為Windows的Visual Studio代碼設(shè)置啟動任務(wù)

{
    "version": "0.2.0",
    "configurations": [
      {
        "name": "Debug Main Process",
        "type": "node",
        "request": "launch",
        "cwd": "${workspaceRoot}",
        "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
        "windows": {
          "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
        },
        "args" : ["."],
        "outputCapture": "std"
      }
    ]
  }

有了這個配置文件,您可以單擊主進(jìn)程中任何一行的左邊緣來設(shè)置斷點(diǎn),然后按F5運(yùn)行應(yīng)用程序。 執(zhí)行將在斷點(diǎn)處暫停,允許您檢查調(diào)用堆棧,確定范圍內(nèi)的變量,并與活動控制臺進(jìn)行交互。斷點(diǎn)并不是調(diào)試代碼的唯一方法。 您還可以監(jiān)視特定的表達(dá)式,或者在拋出未捕獲異常時將其放入調(diào)試器(圖3.13)。

圖3.13 內(nèi)置在Visual Studio Code中的調(diào)試器允許您暫停應(yīng)用程序的執(zhí)行,并順便檢查bug。

您很可能沒有使用Visual Studio Code。這很好。這并不是本書的先決條件,使用您最熟悉的文本編輯器或IDE幾乎肯定沒問題。 此外,Visual Studio Code并不是唯一支持調(diào)試主進(jìn)程。例如,您可以在這里找到配置WebStorm的詳細(xì)信息:http://mng.bz/Y5T6。

總結(jié)

在接下來的幾章中,我們將制做一個markdown到html編輯器。

Flexbox受到現(xiàn)代瀏覽器的支持,允許我們輕松地實(shí)現(xiàn)一個雙窗格界面,當(dāng)用戶改變窗口的大小時,這個界面將進(jìn)行調(diào)整。

Chrome開發(fā)工具在所有渲染器進(jìn)程中都可用,可以從默認(rèn)的電子應(yīng)用程序、鍵盤快捷鍵或主進(jìn)程觸發(fā)。

此時Electron中還沒有完全支持Node Inspector檢查器。

Visual Studio代碼提供了一組豐富的工具,用于調(diào)試應(yīng)用程序主進(jìn)程中的問題。

總結(jié)

以上是生活随笔為你收集整理的10分钟实现Typora(markdown)编辑器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。