摘要:使用實現(xiàn)桌面應(yīng)用實現(xiàn)離線可用很多方法,比如使用技術(shù)。還有一個好處,因為它完全基于來實現(xiàn)可以使用的一些新功能,那我們理論上可以在做桌面應(yīng)用時順手把應(yīng)用也做了。
本文將會講述一個完整的跨端桌面應(yīng)用?代碼畫板?的構(gòu)建,會涉及到整個軟件開發(fā)流程,從開始的設(shè)計、編碼、到最后產(chǎn)品成型、包裝等。
本文不僅僅是一篇技術(shù)方面的專業(yè)文章,更會有很多產(chǎn)品方面的設(shè)計思想和將技術(shù)轉(zhuǎn)換成生產(chǎn)力的思考,我將結(jié)合我自己的使用場景完全的講解整個開發(fā)流程,當(dāng)然涉及到設(shè)計方面的不一定具有普遍實用性,多數(shù)情況下都是我自己的一些喜好,我只關(guān)心自己的需求。
同時本文只從整體上講思路,也會有個別的技術(shù)細(xì)節(jié)和常規(guī)套路,有興趣的也可以直接去 github 上看 源碼,文章會比較長,如果你只想知道一些拿來即用的「干貨」,或許這篇文章并不是一個好的選擇
一、定位需求事情的起因是這樣的,因為我們內(nèi)部會有一些培訓(xùn)會議。會經(jīng)常現(xiàn)場演示一些代碼片段。比如說我們講到 React 的時候會現(xiàn)場寫一些組件,讓大家能直觀的感受到 React 的一些功能。
但是通常由于條件所所限,會議總會遇到一些意外。比如斷網(wǎng)、投影分辨率低看不清文字等
起初我們用的是在線版的 codepen,但是感覺并不是那么好用。比如不能方便的修改字體大小,必須要在連網(wǎng)的情況下才能使用。另外它的 UI 設(shè)計不是很緊湊,通常我們展示代碼的時候都投影是寸土寸金的,應(yīng)該有一個簡潔又不失功能的 UI 界面,能全屏展示…
于是我解決自己實現(xiàn)一個這樣的輪子,那么大概的需求目標(biāo)是有了:
離線可用
可以改變界面字體大小
更加簡潔的 UI
…
二、整體設(shè)計 應(yīng)用風(fēng)格代碼畫板解決的是?臨時性 的一些?演示代碼?的需求,所以它的本質(zhì)屬性是一個拿來即用的工具,它不應(yīng)該有更復(fù)雜的功能,比如用戶登錄、代碼片段的管理等。這些需求不是它要解決的。代碼畫板會提供一個簡單的導(dǎo)出成 HTML 文件的功能,可以方便用戶存儲整個 HTML 文件。
既然是用來演示代碼的,那么它的界面上應(yīng)該只有兩個東西,一個是 代碼,一個就是?預(yù)覽。像代碼/控制臺切換的功能都做成 tab 的形式,正常情況不需要讓他們展示出來。像 codepen 那樣把所有的代碼編輯器功能都展示出來我認(rèn)為是不對的。
codepen 的界面給人感覺非常復(fù)雜,有很多功能點。當(dāng)然我并不是在批評它,codepen 做為一個需要商業(yè)化運營的軟件,勢必會做的非常復(fù)雜,這樣才能滿足更多用戶的需求。然而程序員寫軟件則可以完全按照自己的想法來,哪怕這個應(yīng)用只給自己一個人用呢。
桌面應(yīng)用的設(shè)計桌面應(yīng)用的設(shè)計和 web 界面的設(shè)計還是有些細(xì)微區(qū)別的,同樣的基于 electron 的應(yīng)用,有的應(yīng)用會讓人感覺很「原生」,有的則一眼就能看出來是用 CSS 畫的。我在設(shè)計代碼畫板的時候也盡量向原生靠近,避免產(chǎn)生落差感。比如禁用鼠標(biāo)手型圖標(biāo)、在按鈕或者非可選元素上禁止用戶選擇:
cursor: default; user-select: none
因為實際上用戶在使用一款應(yīng)用的時候感性的因素影響占很大一部分,比如說有人不喜歡 electron 可能就是因為看到過 electron 里面嵌一個完整的 web 頁面的操作,這就讓人很反感。但是這不是 electron 的問題,而是應(yīng)用設(shè)計者的問題。
應(yīng)用標(biāo)識的設(shè)計說實話應(yīng)用 logo 設(shè)計我也是業(yè)余水平,但是聊勝于無。既然水平不行,那就盡量設(shè)計的不難看就行了。可以參考一些好的設(shè)計。我用 sketch 畫出 logo 的外形,sketch 有很多 macOS 的模塊可以從網(wǎng)上下載下來,直接基于模板修改就可以了。
代碼畫板主要的界面是分割開的兩個面板,左邊是代碼,右邊是預(yù)覽。所以我就大概畫了一個形狀
這個 logo 有個問題就是線條過多,小尺寸的時候看不清楚。這個問題我暫時先忽略了,畢竟我還不是專業(yè)的,后續(xù)有好的創(chuàng)意可以再改
默認(rèn)設(shè)置代碼畫板也 不會有 設(shè)置界面,因為常用的設(shè)置都預(yù)定義好了,你不需要配置。頂多改變下代碼字體的大小。使用編輯器的通用快捷鍵 command++/-?就解決了,或者插入三方庫,直接使用編輯器的通用命令快捷鍵 command+p?調(diào)出。我們的思路就是把復(fù)雜的東西幫用戶隱藏在后臺,觀眾只需要關(guān)注演員臺上的一分鐘,而不必了解其它細(xì)節(jié)。
快捷鍵/可用性由于代碼畫板的界面非常簡單,在一些細(xì)小的必要功能就得添加一些快捷鍵。比如:切換 HTML/CSS/JS/Console 代碼編輯器,我在每個 tab 上加了數(shù)字標(biāo)號,暗示它是有順序有快捷鍵的,而且這個切換方式和 Chrome tab 切換的邏輯一致,使用 command+數(shù)字?就可以實現(xiàn),萬一還是有人不會用的話,可以去看幫助文檔。里面有所有的快捷鍵。
界面中間的分割條可以自定義拖動,雙擊重置平分界面
剛開始的時候我把每個 tab 頁簽都分割成多帶帶的面板,因為我覺得這個能拖動自定義面板大小的交互實在是太爽了,忍不住想去拖動它。但是后來想想,其實并沒有必要,我們寫代碼時應(yīng)該更專注于代碼本身,如果只有兩個面板,那么這個界面無論是認(rèn)知還是使用起來就沒有任何困難。
因為我們并不需要把一堆的功能的界面摔給用戶,讓他們自己去選擇。
三、技術(shù)調(diào)研 實現(xiàn)控制臺通過使用流行的幾款在線代碼運行工具,我發(fā)現(xiàn)他們有一個共同的問題:控制臺很難用。無法像 Chrome Console 那樣展示任意類型的 JS 值。比如我想 log 一段嵌套的 JS 對象:
console.log({ a: { b: 1, c: { d: [1, 2, 3] } }})
大多數(shù)都展示成這樣的:
[object Object] { a: [object Object] { b: 1 } }
Chrome 是這樣的:
顯然 Chrome 控制臺中更直觀。所以我們需要在前面的基礎(chǔ)上加一個需求,即:實現(xiàn)一個基于 DOM 的日志展示界面(無限級聯(lián)選擇)
日志界面應(yīng)該有下面這些功能:
展示任意 JS 類型的數(shù)據(jù)
Primitive 類型的數(shù)據(jù)顯示不同的顏色(number - 藍(lán)色,string - 綠色)
Object 類型默認(rèn)折疊起來,點擊按鈕展示子級,屬性過多需要展示縮略信息
數(shù)組前應(yīng)該有長度標(biāo)記
能展示 JS 運行時的報錯 Error 信息
集成現(xiàn)代化的前端框工作流現(xiàn)代化的前端寫頁面肯定不是 HTML/CSS/JS 一把梭了,至少應(yīng)該有 Sass/Babel 的支持吧。
Sass 嵌套能讓你少寫很多選擇器,當(dāng)然 Less 也可以,但是在我們的這個應(yīng)用里面區(qū)別不大,一般來說臨時性的寫一些代碼很少會用到它們的細(xì)節(jié)功能。有?變量?和?選擇器?嵌套就夠了
Babel 主要是解決了寫 React 的問題,不用再安裝一大堆的構(gòu)建工具了,直接使用 UMD 的 React/ReactDOM 就可以了,而且 electron 內(nèi)嵌的 chromium 也支持了 es6 的 class 寫法,實際上 Babel 主要的目的還是用來轉(zhuǎn)譯 JSX
注意這里是有一個我認(rèn)為是?剛性?的需求,比如臨時忽然有個想法,或者想驗證一段代碼的話,正常情況是使用你的編輯器,新建 demo.html/demo.css/demo.js 等這些操作。但是這些動作太浪費時間了。有了代碼畫板以后,直接打應(yīng)用就可以開始 coding 了,真正能做到開箱即用。
提高程序的擴(kuò)展性我們在寫 demo 頁面時通常是要引用很多第三方類庫的,比如:Bootstrp/jQuery 等。我希望有一種方法可以方便的引用到這些庫,直接把庫文件的 link/script 標(biāo)簽插入到代碼畫板的 HTML 中,但是前端框架真的是太多了,又不能一個個去扣來寫死到頁面,就算是寫死了隨著框架版本的升級,可能就無法滿足我們的需求。
以前寫頁面時經(jīng)常會用到 bootcdn,無意中發(fā)現(xiàn)它提供了相關(guān) API,可以直接拿來使用。接下來就得想辦法讓用戶通過界面選擇即可。
這個 API 有三層數(shù)據(jù)結(jié)構(gòu):庫 - 版本 - 資源鏈接。這個功能要用界面來實現(xiàn)肯定會非常臃腫,界面上可能會放很多按鈕。這就違背了「更簡潔」的需求目標(biāo)。
這時就得參考下我們經(jīng)常使用的一些軟件是如何解決?簡潔性?和 功能性 需求之間的矛盾問題的,我比較喜歡 Sublime Text 的一些界面設(shè)計,Command Palette 是我經(jīng)常使用的,所以我決定再模擬一個?Command Palette 來實現(xiàn)插入第三方庫的需求。而且重要的是這個?Command Palette 并不一定只用來實現(xiàn)這一個功能,或者后期會有一些別的功能需要添加,那這個?Command Palette 也是個很好的入口。
使用 electron 實現(xiàn)桌面應(yīng)用實現(xiàn)離線可用很多方法,比如使用 PWA 技術(shù)。但是 PWA 并不能給我?guī)硪环N原生應(yīng)用的那種可靠感,相反 electron?剛好可以解決我的顧慮。同時它可以把你的應(yīng)用打包成各個平臺(macOS/Window/Linux)的原生應(yīng)用。唯一的缺點就是安裝包確實很大,一般來講一個 electron 應(yīng)用 安裝完 至少要 100 多兆,不過我覺得還能接受,畢竟硬盤存儲現(xiàn)在已經(jīng)很廉價了。
有人可能對 electron 有抗拒,覺得 electron 應(yīng)用太龐大、占系統(tǒng)資源什么的,不過我們做的這個應(yīng)用并不需要常駐系統(tǒng),臨時性的使用一下,用完就關(guān)閉,正常寫生產(chǎn)環(huán)境的代碼肯定還是要換回 編輯器/IDE 的。同時因為 electron 降低了寫桌面應(yīng)用的門檻,確實有很多人把一個完整的在線的網(wǎng)頁直接嵌進(jìn)去,這也是有問題的。
electron 還有一個好處,因為它完全基于 HTML/CSS/JS 來實現(xiàn) UI(可以使用 Chrome only 的一些新功能),那我們理論上可以在做桌面應(yīng)用時順手把 web 應(yīng)用也做了。這就可以同時支持各個系統(tǒng)下的原生應(yīng)用,并且有 web 在線版本。如果你不愿意使用原生應(yīng)用,直接登錄 web.code-sketch.com 使用在線版也沒是一種選擇。這樣就使得我們的應(yīng)用具有真正的?跨端?能力。
由于我們團(tuán)隊都使用了 macbook,所以我優(yōu)先支持 macOS 的開發(fā),另外 macOS Mojave 的系統(tǒng)級別的暗色主題我也比較喜歡,剛好實現(xiàn)支持 mojave 暗色主題這個需求也做上。
三、框架的選擇大方向確定了,像框架選擇這個就簡單了,基于 electron 的應(yīng)用,需要你區(qū)分開 render/main process 來選擇。
Render process渲染進(jìn)程?就是 electron 中界面的實現(xiàn)部分 ,一般來說就是一個 webview,選自己喜歡的框架即可。我使用 React 來實現(xiàn)界面。樣式方面就不再使用框架了,因為我們的界面原則上沒有復(fù)雜的元素,直接手寫 CSS,300 行內(nèi)基本上就可以解決問題。可能有人會覺得這不可能,實際情況是當(dāng)你寫樣式只跑在 Chrome 里面的時候那感覺完全爽到飛起,CSS variable/flex/grid/calc/vh/rem 什么的都可以拿來用,實現(xiàn)一個功能的成本就降低了很多。
我使用 Codemirror 來做為主界面的代碼編輯器,Monaco 也是一個好選擇,但是它有點過于龐大了,而且如果想要自定義功能得自己寫很多實現(xiàn)
主界面上的分割組件,使用了 React-split。
Main process主進(jìn)程 就是 electron 應(yīng)用程序的進(jìn)程,主要的區(qū)別在于主進(jìn)程中可以調(diào)用一些與原生操作系統(tǒng)交互的?API,比如對話框、系統(tǒng)風(fēng)格主題等。并且有 node 的運行時,可以引用 NPM 包。當(dāng)然渲染進(jìn)程也可以有 node 支持,但是我建議渲染進(jìn)程中就只放一些純前端的邏輯,這樣的話方便后期把應(yīng)用分離成 web 版
因為我們要集成 Sass 編譯功能,如果你也經(jīng)歷過 node-sass 的各種問題,那就應(yīng)該果斷選擇 dart-sass?— 使用 dart 實現(xiàn),編譯成了原生的 JS,沒有依賴問題。dart-sass 我放在了 main process 中,因為我試過放在 render process 中會有各種報錯。如果 web 端要實現(xiàn)這個功能就需要其它的解決辦法了,比如做成一個 http 服務(wù),讓 web 調(diào) http 服務(wù)。
Babel 的話我是放在了?渲染進(jìn)程?中以 script 標(biāo)簽的方式調(diào)用,這樣即使在 web 端 Babel 編譯也是可用的。
總之如果你使用 electron 構(gòu)建應(yīng)用并且引入的第三方 NPM 包可以?支持?運行在客戶端(瀏覽器)上,那就盡量把包放在渲染進(jìn)程里面。
構(gòu)建工具我使用 Parcel 來構(gòu)建 React 而不是 Create React App。后者用來寫個小應(yīng)用還可以,稍微大一點的,需要定制化一些東西你就得 eject 出來一大堆 webpack 配置文件,即便是我已經(jīng)用 webpack 開發(fā)過幾個項目了,但是說實話我還是沒用會 webpack。寫 webpack 配置的時間足夠我自己寫 npm script 來滿足自己的需求了。
原生應(yīng)用打使用?electron-builder 來打包到平臺原生應(yīng)用,并且如果你有 Apple 開發(fā)者賬號的話應(yīng)用還可以提交到 AppStore 上去。
我目前的打包參數(shù)是這么配置的:
{ "build": { "productName": "Code Sketch", "extends": null, "directories": { "output": "release" }, "files": [ "icon.icns", "main.js", "src/*.js", "所有需要的文件", "package.json", "node_modules/@babel", "node_modules/sass" ], "mac": { "icon": "icon.icns", "category": "public.app-category.productivity", "target": [ "dmg" ] } } }
在你的 package.json 中添加 build 字段,productName, directories 這些按自己需要更改即可
四、分離開發(fā)環(huán)境 區(qū)分開開發(fā)環(huán)境代碼畫板項目開過過程中涉及兩個關(guān)鍵環(huán)境
Parcel 構(gòu)建環(huán)境(渲染進(jìn)程):Parcel 可以為你提供一些現(xiàn)在 JS 的轉(zhuǎn)譯工作,因此你可以放心使用例如 ES6 的 JS 新特性
Node.JS 運行環(huán)境(主進(jìn)程+渲染進(jìn)程):這個取決于你的 electron 版本中集成的是 node 版本,比如:Node 10 中就沒有 ES Module,這意味著你如果要在 electron 主進(jìn)程?是無法識別 import 這樣的語句的,但是渲染進(jìn)程由于你使用了 Parcel 編譯,則無需考慮
這里溫馨提示下:想要做到 electron 中的 渲染進(jìn)程與主進(jìn)程之間共享 JS 代碼是非常困難的。就算是有辦法也會特別的別扭,我的建議是盡量分離這兩個進(jìn)程中的代碼,主進(jìn)程主要做一些系統(tǒng)級別的 API 調(diào)用、事件分發(fā)等,業(yè)務(wù)邏輯盡量放在渲染進(jìn)程中去做
如果非要共享,那建議多帶帶做成一個 NPM 包分別做為主進(jìn)程運行時依賴,和渲染進(jìn)程的 Parcel 編譯依賴,唯一的缺點就是實際上共享的代碼會有兩份。
渲染進(jìn)程中調(diào)用 node API 可能會和 Parcel 打包工具沖突,一般在調(diào)用比如文件模塊時,可以加上 window.require(‘fs’) 這樣就可以兼容兩個環(huán)境:
get ipc() { if (window.require) { return window.require("electron").ipcRenderer } else { return { on() {}, send() {}, sendToHost() {} } } } this.ipc.send("event", data)
這樣的話你在瀏覽器端調(diào)試也不會產(chǎn)生報錯。一般情況下,建議當(dāng)你用渲染進(jìn)程中的 JS 引用(require)包的時候都加上 window. 前綴就可以了。因為渲染進(jìn)程中 window 是全局變量,調(diào)用 require?和調(diào)用 window.require 是等價的
開發(fā)流程通常在測試的時候應(yīng)用會調(diào)用一些?electron 內(nèi)置的系統(tǒng)級別 API,這部分調(diào)用通常需要啟動 electron,但是有時候只有渲染進(jìn)程中 UI 界面上的改動,就不用再啟動 electron 了,直接在瀏覽器里面測試即可。使用 Parcel 運行一個本地的服務(wù),這樣就可以在瀏覽器里面調(diào)試頁面。整個開發(fā)過程需要兩個命令(NPM Script):
啟動 Parcel 編譯服務(wù)器
"scripts": { "start": "./node_modules/.bin/parcel index.html -p 2044" }
調(diào)試 electron 原生功能,注意設(shè)置?ELECTRON_START_URL
"scripts": { "dev": "ELECTRON_START_URL=http://localhost:2044 yarn electron", }技術(shù)難點
整個應(yīng)用只有兩個功能是需要我們自己寫代碼實現(xiàn)的:日志控制臺,Sublime 命令行。我們分別來分析下這兩個模塊的難點。
日志控制臺 的難點在于,我們需要打印任意類型的 JS 值。如果你對 JS 了解比較多的話自然會想到在 JS 中所有的東西都是 對象,即 Object,那么實際上當(dāng)你想打印一個變量的時候,其實你只要把整個 Object 遞歸的遍歷出來,然后做成一個無限級的下拉菜單就可以了。看起來大概想下面這樣:
Sublime 命令行?實際上開發(fā)起來還是比較簡單的,使用 React 很簡單就實現(xiàn)了功能,比較麻煩的是調(diào)用 bootcdn 的接口,過程中我發(fā)現(xiàn)接口返回數(shù)據(jù)量還是挺大的,有必要做上一層 localStorage 緩存,加快二次打開速度。
然而在使用的過程中你會發(fā)現(xiàn)當(dāng)我想插入一個前端庫需要很多操作,因為有 三級選擇:庫-版本-CDN 鏈接。雖然這個流程解決了?所有用戶 的使用問題,但是卻損害了 大部分 用戶的體驗。這個時候插入一個常用庫的成本就很高了,所以我們就要加上一些快捷入口,來實現(xiàn)一鍵插入流行框架。
我們寫代碼的思路是滿足所有用戶的使用需求,但是一個好產(chǎn)品的思路是先滿足大多數(shù)用戶(80%)的常規(guī)需求,再讓其余的用戶(20%)可以有選擇
還有一個問題比較典型就是 React 這類框架在渲染大列表并且進(jìn)行過濾(關(guān)鍵字查詢)時性能的問題。注意這個性能問題 并不是 引入框架產(chǎn)生的,真正的原因是當(dāng)你渲染的 HTML 節(jié)點數(shù)以千計的時候,批量操作 DOM 會使得 DOM Render 特別慢。
所以說當(dāng)我們遇到性能問題的時候應(yīng)該去查找問題的根源,而不是停留在框架使用上,實際上在 DOM 操作這個層面來講 jQuery 提供了更多的性能優(yōu)化,比如自身的緩存系統(tǒng),以致于當(dāng)你在使用的時候很難發(fā)現(xiàn)有性能問題。但是在類 React 框架中它們框架本身的重點并不在于解決你應(yīng)用的性能問題。
類似我們上面講到的,實際上 jQuery 幫助你屏蔽了很多舞臺背后的東西,以致于你可以不用操心技術(shù)細(xì)節(jié),你甚至可以把 jQuery 當(dāng)做一個 產(chǎn)品 來使用,而類 React 框架你卻要親力親為的用他來設(shè)計你的代碼。
話題再轉(zhuǎn)回性能問題。這時候需要我們?nèi)崿F(xiàn)一個類似于 react-window? 的功能,讓列表元素根據(jù)滾動按需加載。這可能是一種通用的解決大列表加載的方案,但是我的解決方法更粗暴,因為我們的下拉過濾功能使用時用戶只關(guān)注?最佳的匹配項?即可,后面匹配程度不高的項可以直接限制數(shù)量裁剪就行了嘛。很少有用戶會一直滾動到下面去查找某個選項,如果有,那就說明我們這個匹配做的有問題。
slice() { const idx = (this.props.itemsPerPage || 50) * (this.state.activeFrame + 1) return this.props.items.slice(0, idx) }
整個匹配篩選的狀態(tài)大概是這樣的:
this.state = { // 當(dāng)前第N步選擇 step: 0, // 當(dāng)前步驟數(shù)據(jù) items: [], // 是否顯示 active: false, // 當(dāng)前選中項 current: {}, // 過濾關(guān)鍵字 keyword: "" }
這個?items?是當(dāng)前步驟的所有數(shù)據(jù),實際上我們這個組件是支持無限級的擴(kuò)展的,那么我們通過組件的 props 傳入所有層級的數(shù)據(jù),然后持久存儲在內(nèi)存中。這個 所有層級的數(shù)據(jù) 是數(shù)據(jù)結(jié)構(gòu)層面的,實際上它可能是通過異步接口獲取的。
再來看看我們組件提供的所有 props:
static defaultProps = { step: 0, active: false, data: [[]], // 無限層級數(shù)據(jù) [[], [], [], ...] // 數(shù)據(jù)的主鍵,用于鉤子函數(shù)返回用戶選擇的結(jié)果集 pk: "id", autoFocus: true, activeCls: "active", delay: 300, defaultSelected: 0, placeholder: "", async: false, alias: [], done: () => {} }
這些數(shù)據(jù)都可以通過組件的 props 傳入,這就意味著我們的這個組件才是真正的組件,別人也可以使用這樣的功能,而他們并不用在意里面的細(xì)節(jié),使用者只需要做好類似調(diào)用自己接口的這種業(yè)務(wù)邏輯。
組件的調(diào)用大概是這樣的:
async?這個 props 實際上是一個異步調(diào)用的鉤子方法,它會回傳給你組件上當(dāng)前操作的相關(guān)數(shù)據(jù)狀態(tài),通過這些數(shù)據(jù)使用者就可以按自己的需求在不同的步驟上調(diào)用不同的方法
export const injectData = (step, item, results, cb) => { const API = "https://api.bootcdn.cn/libraries" if (step === 0) { fetchData(`${API}.min.json`) .then(processLibraryData) .then(cb) } else if (step === 1) { // ... } else if (step === 2) { // ... } }另外關(guān)于 React 這里安利下自己翻譯過的一個教程:React 模式,里面講到 18 種短小精悍的 React 模式案例,非常簡單易懂。
還有一個小竅門,我們在適配暗色主題時,傳統(tǒng)的方法是直接寫兩套主題 CSS 代碼,實際上我們要使用 CSS Variable 的話完全沒必要生成兩套了,背景色,字體都做成 CSS 變量,切換的時候只需要動態(tài)往頁面插入更新過的 CSS 變量值即可
系統(tǒng)的一些參數(shù)想直接傳給渲染進(jìn)程也是比較麻煩的,我的做法是直接從主進(jìn)程中的 loadUrl 方法上以 queryString 的方式傳到渲染頁面的 URL 上
const query = { theme: osTheme, app_path: app.getAppPath(), home_dir: app.getPath("home") } mainWindow.loadURL(process.env.ELECTRON_START_URL ? url.format({ slashes: true, protocol: "http:", hostname: "localhost", port: 2044, query }) : url.format({ slashes: true, protocol: "file:", pathname: path.resolve(app.getAppPath(), "./dist/index.html"), query }))像程序運行時的一些參數(shù)(比如程序的根目錄)也可以這么動態(tài)傳過去,而且還有一個好處就是你甚至可以在渲染進(jìn)程中測試與這些參數(shù)相關(guān)的功能。
五、宣傳 demo 視頻錄制我會把最終所有功能的使用方法錄制成一個視頻,萬一有人不不想下載你的軟件,只是要了解一下,這就是個很好的方法。我同時上傳到了 Youtube 和 bilibili 這兩個平臺,其它的都有廣告就沒必要了
使用 Quicktime Player 即可,錄制完使用 iMovie 轉(zhuǎn)碼成兩倍速率的 mp4。如果你有興趣還可以加上一段音樂什么的,讓視頻看起來更靈動
域名申請域名是一個能讓用戶記住你產(chǎn)品的方法,如果你做的是一個成型的產(chǎn)品,那就一定要申請個域名。
我總是有這樣的體驗,有的時候看到一個非常不錯的產(chǎn)品但由于當(dāng)時沒需求就忽略了,想起來或者突然有需求的時候缺記不起來名字叫什么了。
事實上代碼畫板最開始我給他起的名字是 code playground,這個更直觀,但是名字太長,而且想用到的一些域名呀、Github 名、NPM 包都被注冊了。
想來想去就換成了 code sketch,這和符合我們的設(shè)計初衷,即:一邊是代碼,一邊是效果/草圖
域名申請我一般會上 Godaddy,不用備案,.com 域名一年 ¥65.00,然后 DNS 服務(wù)器轉(zhuǎn)到了?cloudflare,后續(xù)域名也會直接轉(zhuǎn)到?cloudflare。因為據(jù)說以后在 cloudflare 上續(xù)費域名最便宜
網(wǎng)站搭建宣傳網(wǎng)站直接放在 github pages 上,做個自定義域即可,實在是太方便了。而且還有 SSL 支持,Github 真的是業(yè)界良心
web 版的代碼畫板,由于我們把渲染進(jìn)程中的代碼分離開發(fā),所以直接把 parcel 打包出來的靜態(tài)文件也做成 github pages 就可以了,爽歪歪,網(wǎng)站就等于一分錢不花了。后續(xù)做一些 web 版的增強(qiáng)功能時,可以做成前后端分離的 http 服務(wù),這就是后話了
加入 Google?analytics 代碼GA 可以讓你了解網(wǎng)站的用戶分布情況,清楚的知道網(wǎng)站訪問的波動。比如說你把自己的鏈接放到某個網(wǎng)站上分享了,GA 里面就能看出來所有的推薦來源和波動,對于運營來說是非常有必要的
廣告語這個我還真想了好長時間,基于我對于代碼畫板的定義,我覺得它應(yīng)該是一個我們有一個想法的時候需要快速去實現(xiàn)一個 demo 的地方,想來想去就定了一段看起來文鄒鄒的話,雖然聽名字根本不知道它是干啥用的,但是沒關(guān)系,程序員寫東西就是要有個性,因為我的受眾只有自己。
First place where the code was written...六、匯總使用到的庫與工具
一個你最初寫代碼的地方...麻雀雖小,五臟俱全。我們來看下代碼畫板總共用到了多少東西:
框架/庫
electronjs
react
babeljs
NPM 模塊
codemirror 及其插件
react-split
sublime-command-palette
打包/工具
parceljs
electron-builder
bootcdn
設(shè)計與素材
sketch
Free AppIcon Generator
Inconsolata 字體
Gallary CSS?純 CSS 實現(xiàn)的焦點圖,用于宣傳頁展示
七、結(jié)語總結(jié)實事上我自己的開發(fā)這個應(yīng)用的時候并沒有嚴(yán)格按照這篇文章的順序執(zhí)行,而是想到一些實現(xiàn)一些,可能一個功能實現(xiàn)了后來覺得不好又干掉了,是不斷的取舍、提煉的結(jié)果。
開發(fā)中我也不斷的問自己這個功能是否有必要,如果可有可無那是不是可以去掉,這樣才能使得用戶更加關(guān)注于代碼本身。
整個開發(fā)過程中自己實現(xiàn)的功能模塊并不多,只有控制臺、命令行窗口是自己實現(xiàn)的,其它的功能基本上都是靠社區(qū)現(xiàn)有的工具庫來完成的,從這一點來說前端技術(shù)的生態(tài)還是挺好的。這使得當(dāng)我從整體上構(gòu)思一個產(chǎn)品時我不必在意那些細(xì)節(jié),雖然過程中還是能感覺到前端工具/庫的割裂感,但是整體而言還是向好的,畢竟工具對于開發(fā)者只是一種選擇的。
八、引用
https://github.com/keelii/code-sketch
http://www.tweaknow.com/appicongenerator.php
http://benschwarz.github.io/gallery-css/
https://addyosmani.com/blog/react-window/
https://github.com/keelii/reactpatterns.cn
原文:https://mp.weixin.qq.com/s/Lbnx0aYdRa5iDhOkCgEWjg
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102510.html
摘要:前陣子,有些師弟師妹問我在淘寶,前端開發(fā)主要是在做什么事情作為一個在淘寶已經(jīng)工作年的老兵,我想我有資格來全面地回答一下這個問題,并通過這個機(jī)會向外部介紹一下我們團(tuán)隊的同學(xué)。以上便是我們在淘寶主要在做的事情。 前陣子,有些師弟師妹問我:在淘寶,前端開發(fā)主要是在做什么事情? 作為一個在淘寶已經(jīng)工作 5 年的「老兵」,我想我有資格來全面地回答一下這個問題,并通過這個機(jī)會向外部介紹一下我們團(tuán)隊...
摘要:所以在小程序出現(xiàn)之后,一股框架之風(fēng)也很快的出現(xiàn),微信小程序剛推出之后,就出現(xiàn)了兩個比較出名的小程序開發(fā)框架,。 原文地址:https://ant-move.github.io/we... 這里說的去除小程序框架其實并不嚴(yán)謹(jǐn),因為小程序本身也算是一個框架,而且是一個功能更加完善的框架系統(tǒng)。在前端的概念中,我們一般說一個框架是指一個用來幫助開發(fā)者構(gòu)建用戶界面的框架,而小程序框架本身不僅僅包...
摘要:跨端框架壹個理想主義團(tuán)隊的開源作品歷經(jīng)近個月打磨,滴滴跨端方案終于開源了真正專注于一套代碼運行多端。這時候我們專門成立了一個人的小項目組,完成一個名為的項目,一期目標(biāo)是不影響用戶發(fā)揮,不依賴框架方的原則性實現(xiàn)一套代碼運行和微信小程序。 Chameleon跨端框架——壹個理想主義團(tuán)隊的開源作品 歷經(jīng)近20個月打磨,滴滴跨端方案chameleon終于開源了https://github.co...
摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為新聞熱點、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎關(guān)注【前端之巔】微信公眾號(ID:frontshow),及時獲取前端每周清單;本文則是對于...
閱讀 961·2021-11-24 09:39
閱讀 3383·2021-10-27 14:20
閱讀 2322·2019-08-30 14:08
閱讀 3361·2019-08-29 16:34
閱讀 2176·2019-08-26 12:14
閱讀 2104·2019-08-26 11:54
閱讀 2771·2019-08-26 11:44
閱讀 2474·2019-08-26 11:38