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