葉顆顆
Sudo Ninja
Published in
13 min readJun 21, 2016

--

Kalan

flow

第一次聽到,是從 henry 的口中。第二次看到,是從看了 draftjs 的 source code。

當前端的 code 無可避免地增肥之後(尤其是 js 跟 css),我們也應該尋找更有效的代碼管理方式。像是逐漸引入的 eslinter 跟 stylelint 都是。

而 flow 給我的感覺有點像 Typescript,但優點是你可以完全用寫 js 的方式,也不需要改變副檔名(typescript 要寫成 a.ts)。不過還是會害怕抽象化滲透,所以一樣會先觀望一段陣子再套用到主站上吧。

draft

假日閒來無事、天氣燥熱,在咖啡廳喝咖啡、聽音樂、寫 code 也蠻愜意的。所以就趁著假日的時光研究了一下科科所說的draft-js

只有一個字,爽! 所有的骯髒事(selection 兼容、檔案拖曳、編輯器內的樣式)draft-js 幾乎都幫你搞定了。當然因為這個 open source 還非常新(react conf 的時候才推出來),有時候噴錯也不知道從哪邊找起。但這的確是值得令人關注的 editor 解決方案。

目前編輯器會遇到的問題

1. input 跟 textarea 是有極限的

  • 他們只能渲染 plain text,如果想要對文字做加粗、斜體、標記等動作,需要花很大的功實作
  • 當你的文字輸入到下一行時,textarea 高度不足不會自動幫你移位。你可能需要計算下一行文字的位置,然後做相關的操作。這也很費工,而且對使用者的體驗非常糟糕。

2. contenteditable is terrible

因為是將文字內容放在非 input 的 tag 裡面,每種瀏覽器的實作都不太一樣,也很容易就會有意想不到的問題發生。不過 contenteditable 的好處是他活得夠久,瀏覽器也都幾乎實作了,所以反而可以利用這樣的特性來解決當前編輯器遇到的問題。

draft 的概念其實也跟 react 很像,將 editor 跟 content 的狀態存放起來,而非依賴在 DOM 上面。而且他們的狀態不是用純 string 去儲存,而是用 Record(他們實作的資料結構)來代表每個節點。

而 API 文件也寫得挺清楚的,同時也完全實作 immutable 的概念。每次對編輯的內容做操作,就是完全更新狀態。剛開始會覺得很麻煩,我明明只是要一段 text,還要呼叫 getCurrentContent() 回傳的竟然還是一個 Map 在從裡面呼叫 getText();或者我想要更動狀態時,還要做類似這樣的操作:RichUtils.toggleInlineStyle(curState,’BOLD’),然後再把新的 state 傳進去。看似麻煩,不過這樣的方式到後期的開發顯然是有好處的。 容易測試,易讀性高,容易修改、除錯。

facebook 也提供了蠻實用的範例 看完之後可以更瞭解 draft 到底是怎樣運作的。

這邊是我看了官方文件之後實作的範例:draft-example 。還不算太完整,之後會再慢慢補上。

reference

a guide to draftJS

重新思考 rails helper

在逐漸重構 css 跟 html 的過程中,常常會忘記 helper 的存在,最近寫一寫才恍然大悟,對啊!我不是有 helper 嗎?目前對於比較複雜的邏輯判斷已經會習慣性地去使用 helper,但在 view 裡頭,有沒有 helper 可以幫上忙的可能性?

雖然用 partial 也可以做到類似的事情,但跟 helper 做搭配會更強大啊!

而且因為 partial 有時候還要去對應路徑,而 helper 則是全域都可以使用。對高度重複的頁面來說或許用 helper 會更加簡單!

例如我們很常用到的 tags。

當初 sudo tags 改版的時候花了不少時間去更動,因為幾乎每個 tag 裡面都重寫了一次 each,class 命名有時候也不盡相同。

不過使用 partial 又好像太小題大作,畢竟 tag 的架構並沒有如此複雜。

def tag_of_tags(tags, options = {}, html_options)

raw tags.collect { |tag| content_tag(:span,tag.name, options, html_options)}
end

這樣一來,每次我需要用到 tag 的時候就只要

<%= tag_of_tags(@post.tags) %>

當然也可以做一些調整,例如加入 namespace 來符合我們的使用情境。

def tag_of_tags(tags, namespace,options = {}, html_options)
raw tags.collect { |tag| content_tag(:span,tag.name, :class => namespace)
end
<%= tag_of_tags(@post.tags, "sudo") %>

這樣一來每次 tag 要更新的時候,我只要安心修改 helper,其他地方全部都會生效。寫起來自然輕鬆!

以上只是一小部分的例子,舉凡 navbar button dropdown 等,幾乎是每個網站開發必備的元素。我們在新增 partial 的同時,說不定也可以搭配 helper 一起思考更多的可能性!

關於文件,我有話要說

最近因為想要讓 legacy 漸漸減少,會盡量地用重用性的角度來思考。

不過科科給了我一句話「太早談重用性,反而會掉入過度設計的陷阱」。仔細想過之後,的確如此吧!

但我認為,這樣的嘗試是好的,對自己來講是從更寬的角度來看自己的 code,也可以減少一些自己以前的盲點等等。

而想要讓 code review 變得輕鬆的辦法,就是寫文件。不管對 senior 也好對 junior 也好都是有幫助。雖然我的 code 現階段還沒有達到很高的水準,可是透過寫文件這件事情,code reviewer 可以快速理解我的想法,為什麼我要這麼做。

而不是讓 reviewer 從頭看我的 code,揣測我到底在幹嘛?像是 modal 對我來說就是一個很好的嘗試,科科很快地就指出其中的問題跟盲點。

這樣一來,對我來說,我可以從自己的想法裡面寫出品質更好的 code;而 reviewer 因為容易理解我的想法,給予 feedback 的意願也就相對提高了。

當然,可能目前寫得還不夠多,想法也還不夠成熟也說不定,但是從這樣的練習過程中,我想也會慢慢進步吧!

這是我為什麼很用心在寫文件的原因,因為對彼此來講都是節省時間。我省掉以後再看 code 時回想的時間,而 code reviewer 則是省下從頭開始理解的時間。

目前還在磨合期中,希望科科也可以提供建議!

reference

good commit message

javascipt test

how to write test in existing javascript

很多人都是從前任接手 code 的,這篇文章教你如何從現存的 code 當中進行 refactor。裡頭有很多想法值得一提:

  • 不要怪罪前任,要知道代碼的由來通常是有歷史的(每個人都會寫爛 code)
  • 如果沒有 unit test 也沒關係,至少從自己做起
  • 用消極的態度、因為情緒而過度設計,反而會造成更多問題
  • 永遠不要情緒化寫 code
  • don’t use !important with anger

目前也正在找尋適合主站的測試工具中,希望有一天我們可以達到超過…百分之五十的測試率。

日本工作三個月

很棒的工作分享!

Henry

1. React Native 手動關閉螢幕鍵盤

問題

iOS app 雖然會在使用者不再輸入文字時自動隱藏螢幕鍵盤,但鍵盤隱藏時有過場動畫,如果鍵盤的過場動畫與自訂動畫同時發生,就會有螢幕卡頓的情形。

解法

目前 React Native 官方文件還沒有揭露,但 React Native 其實已經有實作手動關閉螢幕鍵盤的 API 了。

import dismissKeyboard from 'dismissKeyboard';
...
dismissKeyboard();

如果螢幕鍵盤目前是開啟的狀態,在呼叫 dismissKeyboard 之後螢幕鍵盤就會被隱藏起來。

結語

React Native 更新的速度非常快,導致文件更新的速度遠遠落後程式碼。最快的方式還是直接 Google 關鍵字,然後回去參考原始碼。之所以要參考原始碼的原因在於有些程式碼可能會被標記為 deprecated,如此就必須另尋方法。

另外,React Native 不要追最新的版本,尤其是 0.24 到 0.25 如果有使用任何第三方程式碼請注意第三方使用者有追上最新版本再進行更新。

2. React Native 動畫初體驗

前言

開發 app,你必須有 總有一天一定要處理轉場動畫 的覺悟。死拖活拖幾個月後,我還是迎來了第一個 React Native 動畫。

Expanding and Collapsing Elements Using Animations in React Native

雖然 *React Native 沒有 CSS*,但它們也不是真的被完全拿掉,而是以另外一種形式借屍還魂。

舉例

在此推薦一項對於 React Native 開發者來說非常好用的服務 React Native Playground,這項服務可以說是 React Native 開發者的 codepen

先來看靜態的例子:React Native Animation (Static)

再來看動態的例子:React Native Animation (Animated)

從結構上看起來一模一樣。兩組程式最大的差別如下:

  1. 動畫版新增了一個 state opacity,值是 Animated.Value。這個 Animated.Value 會隨著不同的動畫函數被呼叫、依據相對應的函數產生不同的數值變動。唯一的參數是動畫函數的起始值。
  2. 在 render callback 中,直接將 opacity state 做為 style 的屬性直接傳入。當 opacity 值一變動就會觸發 render 重新繪製畫面,完成動畫效果。
  3. 適當的時機 呼叫動畫函數以啟動動畫,在我提供的例子中是 componentDidMount callback。React Native 支援 spring、decay、timing 等動畫變數。toValue 指動畫函數的最終數值,另外可以傳入 duration 來控制動畫的長度,至於動畫的函數變動情形 Animated.Value 會自動計算,不需要開發者操心。

結語

動畫效果在數學上的定義就是一個以時間做為參數傳入的函數,輸出是座標值或是對應位置的一個數字。React Native 把開發者最頭痛的動畫函數寫好了,開發者只需要傳入必要的參數剩下的就交給 React Native 去煩惱即可。唯一還要注意的是 app 與網頁最大的不同在於 app 為了增進使用者體驗有許多內建的過場 (transition) 與回饋 (feeback) 動畫,在啟動自訂動畫的同時,必須注意這些過場動畫會不會與自訂動畫同時啟動,造成畫面卡頓。

3. 去除 letter-spacing 行末的多餘空白

問題

letter-spacing 會在 所有字元的尾端 都加上空白以達成字元間隔的效果。但事實上我們需要的只有 在字元與字元間 插入空白即可,最後的字元其實不需要加上空白。因此我們需要做一些 hack 來調整。

解法

善用 margin-right。letter-spacing 設定多少,就以多少的 margin-right 回補。舉個例子,如果 letter-spacing 設定 2rem,margin-right 就設定 -2rem 回補,就可以把文字的位置調整回視覺上應該出現的位置。

letter-spacing on JSFiddle

上面的文字沒有進行調整,整串文字往左邊歪;下面的文字經過調整,看起來就有置中了。

結語

由於這是一個 CSS hack,不排除未來會有任何修正。但在 React Native 中,所有的樣式都會被轉譯成 native 的樣式,如果 native 的 API 沒有被修改,我們就可以確保這樣的 CSS hack 也不會有太劇烈的改變。

Peter

Craft

簡短複習一下 Craft 之前推出的功能有: 1. Duplicate 可以將已經設計好的 component 重複排列。 2. Photos 將網路或是資料夾內的圖片已 fill 的方式置入色塊中(檔案會比較小),也可以自動生成照片的假資料。 3. Styles 將目前的 Sketch 檔案製作成一份 Style 資料,統整了 Sketch 檔案內用到的顏色、字型(大小)。 4. Type 可以自動生成假資料文字,使用者也可以透過 Craft 在網頁上抓取文字。

Craft 1.3.2

介面上的 icon 有更動(其實之前更新就有改變), 變得更加直覺易懂,而非用功能的縮寫作為 icon,就樣就不用每次使用都點點看是什麼功能了。

舊版 icon

image

新版 icon

image

最大的改變大概就是 Styles 的部分, Styles 的功能擴大了,變成 Library。

Library 分成下列兩個面向:

  1. 內部 — Styles
  2. 外部 — Library 在 Library 中使用者可以將自己使用的元件、色票、字型製作成 library 透過雲端共享給他人。 而 Styles 功能依然存在,但最主要專注在產生 Sketch 檔案自身使用的色票、字型等等, Library 則是專注在共享這些色票、字型、元件。

Library 影響了什麼?

當一個團隊變得更大的時候,Guideline 就非常重要, 製作了 guideline 只是讓設計師們有個依循的條目, 但實際上要增加設計的速度,就要建立一個元件庫,那其實就是 Library 的任務。

共享 Library 可以讓團隊中的設計師快速取用元件與正確的色票, Library 可以說是實踐 Guideline 最直接的方式。

Library 的挑戰

目前使用 Library 發現管理功能還不是很好使用, 新增或是取用元件、色票很方便,但刪除與改變順序就比較麻煩。

ocowchun

1.mjml

最近在玩的 email framework,使用 html 寫 email 時,一定都遇過以下這些問題:

  1. 用 table 排版超麻煩
  2. 不能直接使用 css,所以會有一堆重複的code
  3. 用手機開信的時候,版面爆炸了

這些問題 mjml 都幫我們解決了。

mjml 使用 react 將 預先設計好的 mjml element 轉換成 html,你可以用類似 grid 的方式來排版,內建支援 mobile email,透過將重複使用的部分抽離成 custom element 來減少程式碼重複的問題,簡單的說你只要會寫 react ,你就可以無腦設計出長得漂亮,手機瀏覽不跑版的 email 。

有興趣的朋友可以參考我的文章 Introduction To MJML 跟repo lambda-mjml-starter

2. Quip

團隊之前使用 google doc 來討論需求,不過 google doc 在團隊討論上的功能不是很直覺,也不是很顯眼,要花一點時間才找得到,最近回頭看之前玩過一下子的 Quip 發現他很適合作為內部溝通的文件服務。玩了一下就可以發現,這是一個以團隊溝通為核心的文件服務,每個文件都可以輕易地留言討論,可以指定特定人加入溝通,另外還有強大的版本記錄功能,讓使用者可以快速知道每一次的變動有哪些,雖然在文件樣式的調整上相當陽春,不過對於內部溝通來說,文件樣式從來不是重點,另外一個很棒的地方是 Quip 在 Mac,Mobile 都有 native App ,雖然介面設計沒有很美,不過使用體驗屌打 Gooogle doc,推薦給大家。

--

--