Upload
joseph-chiang
View
6.511
Download
2
Embed Size (px)
DESCRIPTION
Citation preview
Cloud Connected Inc.
Front-EndModular & Automated
Development
蔣定宇 / josephj / 啊嗚
建立前端團隊開發環境
http://tinyurl.com/coscup-josephj
嗨!我是啊嗚 /josephj!很開心來到 sfasdf
• 2.5 年:Yahoo! 前端工程師
• 0.5 年:YDN 傳教士
• 1 年:無名小站工程師
• 1.5 年 ~miiiCasa 前端工程師
•單一網址存取
•分享方便
•私密性高
•容量自己決定
•與家人的 SNS
miiiCasa = WWW + Device = 位於你家裡的雲端
http://josephj.com/entry.php?id=348
miiiCasa Space
不論網內外,以相同介面與網址存取 Device 的檔案 http://www.miiicasa.com/space
miiiCasa Bar
在任何網站皆可存取 miiiCasa 的服務http://*
http://tw.yahoo.com http://www.google.com.tw
而這些事情在前一家公司 (Y!) 是没有機會碰的。因為它分工明確、高手多,且很多工具甚至有專門負責的團隊,加上各個服務大都已經有解決方案了,能够真的大刀闊斧地改變現有環境、或注入自己想法的機會相對較少。
Operation Engineer
Service Engineer
QA EngineerFront-end Engineer
System Architect
Software Engineer
System Analyzer
Project Manager
QA Tester
DBA
而在過程之中,我發現自己非常喜歡做前後端整合的工作。若只是單純 HTML/CSS/JavaScript 的撰寫以不能滿足我。結合其它技術讓前端能夠更好 (開發速度、效能、模組化、維護性) 是我現在熱血的方向。
非常鼓勵前端工程師跨往不同的領域因只有前端工程師才知道前端工程師要的是什麼
Server-side Script
Win32
CMS Apache Module
Flash
Embedded System
Firmware
Objective C
I18N/L10N PEAR
Azure
Android
Hardware
本日大綱
• 減少環境差異代碼不判斷環境、設定檔只有一份Fiddler Debugging Proxy 介紹
• 模組化開發:網站的基本單元不管 HTML, CSS, JavaScript 都以模組開發
• 自動化開發:讓犯錯變得困難Nicholas Zakas, “Make it difficult to make mistakes.“
需要克服的議題
• 每種環境伺服器所連結的資料庫 Host Name、數量不一樣。
• 開發機、Alpha 機、QA 機、Staging 機、Production 機的 Host 都完全不一樣。
• 靜態檔案也會有對應的 Host。• 每個工程師習慣的開發環境不同。• CSS/JS 通常在開發以外的環境須做好壓縮與合併,與開發時不同,必須要有不同設定檔作為區隔。
miiiCasa 的作法
• 修改非正式環境上的 /etc/hosts。• 程式碼内只寫正式環境的 Host Name:
www.miiicasa.com, api.miiicasa.com, a.mimgs.com
• 每個 RD 皆在 Linux 開發機開發。• 每個 RD 安裝 Fiddler。• CSS 内的 URL 皆須以 / 開頭的完整路徑。• 在 Deploy 時用 Shell Script 批次取代 Host。
問題 1 : 每個環境的 Host Name 都不一樣
Development
Alpha
Staging
Production
devm1.corp.miiicasa.com:5002*devm1.corp.miiicasa.com:50029
w1.alpha.corp.miiicasa.comimg1.alpha.corp.miiicasa.com
www.staging.miiicasa.coma.staging.mings.com
www.miiicasa.coma.mimgs.com
凡是需 Commit 至版本控管的代碼僅一份組態檔、且只能寫正式環境
Charles 是付費軟體、在每種平台上都可以跑。Fiddler 是免費軟體、只能在 Windows 上面跑。
Fiddler 的功能相較強大許多可自訂功能與取得多元的擴充套件開發時會碰到問題也較少
今天就針對 Fiddler 來做介紹!
Charles 與 Fiddler 的差別?
Cloud Connected Inc.
Fiddler Debugging Proxy
蔣定宇 / josephj / 啊嗚
不用不可的 Fiddler Debugging Proxy
http://tinyurl.com/josephj-fiddler
CSS 檔案内的背景圖檔路徑寫法
#mod .bd { background: url(bg_empty.png);}
#mod .bd { background: url(/home/bg_empty.png);}
#mod .bd { background: url(http://a.mimgs.com/home/bg_empty.png);}
實際位置在:/var/www/static/home/style.cssHTTP 請求路徑在:http://a.mimgs.com/home/style.css
三種都可行,你用那一種?
CSS 檔案内的背景圖檔路徑寫法#mod .bd { background: url(bg_empty.png);}
#mod .bd { background: url(/home/bg_empty.png);}
#mod .bd { background: url(http://a.mimgs.com/home/bg_empty.png);}
因為 Performance、CSS 檔案必須最小化且合併通常處理過後的 CSS 檔案會在根目錄產生第一種採用相對路徑的方式就會無法存取第三種雖可行,但過於複雜、容易打錯字
所以我們一律規定使用第二種方式、相容性最好。
檔案合併後 CSS 檔案位置有可能改變,需以 / 開頭/var/www/static/miiicasa/miiicasa.css
http://a.mimgs.com/miiicasa/miiicasa.css
或許可以直接寫 sp_ico_misc.png但若 CSS 在不同的路徑合併就有麻煩了
http://a.mimgs.com/combo?miiicasa/miiicasa.css&foo/foo.css
開發以外的環境,因有其他角色需要存取例如 QA 與 Producer 裝 Fiddler 不太適合此時在程式碼中就必須是實際存在的 Host 了
只要在 Package 打包流程中處理掉即可用 Shell Script 動態取代 Host Name
<div id=”nav”> <div class=”hd”> <h2>標題</h2> </div> <div class=”bd”> <p>內文</p> </div> <div class=”ft”> <a href=”...”>更多... </a> </div></div>
<div id=”nav”> <div class=”hd”> <h2>標題</h2> </div> <div class=”bd”> <p>內文</p> </div> <div class=”ft”> <a href=”...”>更多... </a> </div></div>
模組的 HTML 結構
一個 ID 代表一個模組不能重複
.hd, .bd, .ft 分別代表模組的header、body、footer
<div id=”ykpsb”> <div class=”bd clearfix”> <form ...> ... </form> <div class=”extra”> ... </div> </div></div>
form .extra
[HTML]<style>#ykpsb { margin-bottom:10px;}#ykpsb form { float:left;}#ykpsb .extra { float:right;}</style>
[CSS]
因每個模組有 id,所以 CSS 可以寫得很 namespace
好處就是很安全,不同模組不會互相干擾
照片顯示模組
搜尋模組
列表模組
_photo_view.php_photo_view.css_photo_view.js
_photo_list.php_photo_list.css_photo_list.js
_photo_filter.php_photo_filter.css_photo_filter.js
模組化的困難
• HTML:很好解決,只要用 include 即可。效能影響不大。
• CSS : 以 ID Selector 作為 CSS 命名空間可以做到。但若每個模組有一個檔案,一頁 30 個模組就會有 30 個檔案,Request 對性能影響很大。
• JavaScript : 跟 CSS 一樣有檔案數量的問題。另外該如何有效率的做跨模組的溝通?
key - 頁面名稱
is_top: 放在 </head> 前或 </body> 前
另外有 is_noscript, media 等屬性可以設定
static.php - 每個頁面要放置哪些 JS/CSS 的組態檔
Mini Tool
將代碼缩小多個 CSS/JS 檔案合併的
開發環境工具
模組檔再多也不需擔心效能的問題
http://www.flickr.com/photos/prettypony/2644225789/
Mini 的 XML 設定檔,把剛剛的設定移往這吧
尋找檔案的路徑、可定義多個。$DEV_ROOT 是在設定 Apache VirtualHost 的環境變數
每個 Mini module 有自己的 CSS 與 JS 檔
module 可以去加入其他的 module,也可以 exclude 某個檔案
index 的 CSS/JS 模組檔案
但需要注意 Mini 並不適用於正式環境、通常放置 Statif File 的 Web Server 不安裝 PHP、而就算有也會對效能造成影響。
線上的 CSS/JS 在 Deploy 後變成單一檔
s* 用 md5_file() 檢查檔案內容產生的 stamping
可减少 CDN 上有重複內容的檔案
使用者點選
window.mods[“photo-show”] = { showPhoto : function (src) { .... }}
window.mods[“photo-list”] = { init : function () { ... $(“img”).on(“click”, function(e) { window.mods[“photo-show”].showPhoto(this.src); } }
九成的人會用全域變數解決問題
當照片顯示模組没有一起在同一頁時,列表模組就會出現 Bug!
http://www.flickr.com/photos/vincentteeuwen/2816245519/
我們都希望球員 (模組) 們扮演好自己的角色在球場 (頁面) 上合作有場好比賽 (功能)
http://www.flickr.com/photos/acaben/2477822120/
但是缺乏紀律 (無架構、使用全域變數) 最後必將造成 (模組) 之間的衝突
JavaScript 應用程式架構
http://www.slideshare.net/nzakas/scalable-javascript-application-architecture
當頁面上多了一個模組它將不會破壞其他模组的結構、樣式與行為
它將提供新的功能、讓其他的模组可以與它溝通互動拿掉它時不需修改、也不會影響與其溝通模組的原有功能
Loose Coupling 鬆散耦合與其他模組的關係是鬆散的
http://www.thesoftwaredevotional.com/images/coupling_train.jpg
模組是獨立運作的,類似插件的概念放在任何頁面上都不需修改、即可提供功能
http://www.flickr.com/photos/nadesign/4324782791/
Module - 獨立運作的個體
• 模組之間不知道彼此的存在• 模組只在意自己本身的功能
Static
Instance Instance Instance
Module Module ModuleStatic Static Static
Core - 整個架構的核心Core
• 接受模組註冊 (register)
• 控制模組啟動關閉 (start, stop)
• 所有廣播訊息的傳遞與對應 (match)
Static Class
Module Module ModuleStatic Static Static
Static
Sandbox - 模組 API 介面Core
• 以 Instance 的方式讓模組不受污染• 模組與 Core 溝通都需要透過 Sandbox
• 模組只能使用 Sandbox 提供的方法• 提供模組 broadcast 與 listen 功能
Static
Sandbox Sandbox SandboxInstance Instance Instance
Module Module ModuleStatic Static Static
broadcast(“need-love”, object)listen(“need-love”)
match(caller, object)
_photo_list.js 照片列表模組Y.Core.register("photo-list", { // 此模組的初始化 init: function (api) { // 這個模組有興趣聽取的兩種訊息 api.listen("photo-filter-submit"); api.listen("photo-filter-response"); this.api = api; }, // 此模組在頁面上 ContentReady onviewload: function () { // 告訴 Core 照片列表完畢,並且把第一張照片路徑一起提供 this.api.broadcast("photo-list-rendered", img.src); }, // 此模組收到訊息時 onmessage: function (eventType, callerName, data) { switch (eventType) { case "photo-filter-response" : this._updateUI() // 填滿列表 break; case "photo-filter-submit" : // 清空列表 break; } }, _updateUI: function (data) { // 告诉 Core 照片列表完畢,並把第一張照片路徑一起提供 this.api.broadcast("photo-list-rendered", img.src); }});
需清空列表
需填滿列表取得資料
使用者送出表單
顯示第一張照片列表完畢
`
範例 Demo
http://josephj.com/project/javascript-platform-yui-demo
http://www.miiicasa.com/my 我的個人檔案頁
CodeIgniter 應用程式
CodeIgniter 模組
controller
views
~/miiicasa/index/my/controllers/index.php
~/miiicasa/index/my/views/index.php
「共用」頁首模組
「我的」選單模組
「我的」功能列表頁首模組
「共用」頁尾模組
http://www.miiicasa.com/my 裡有哪些模組?
http://www.miiicasa.com/my 的共用頁首模組
Controller
Views
JavaScript
CSS
~/miiicasa/index/common/controllers/_masthead.php
~/miiicasa/index/common/views/_masthead.php
~/miiicasa/static/index/common/_masthead.js
/miiicasa/static/index/common/_masthead.css
有底線 _ 的表示是 div 模組檔也有人叫 partial 或 component
http://www.miiicasa.com/my 的共用頁首模組
Controller
Views
JavaScript
CSS
~/miiicasa/index/common/controllers/_masthead.php
~/miiicasa/index/common/views/_masthead.php
~/miiicasa/static/index/common/_masthead.js
/miiicasa/static/index/common/_masthead.css
模組化會讓檔案變多且分散、要找到檔案變得很麻煩...
我們在開發機提供了好用的 Shell Script $ codeigniter open <CI Module>/_<div Module> #批次開啟$ codeigniter create <CI Module>/_<div Module> #批次建立
vim -p /home/dev/joseph_chiang/miiicasa/index/modules/common/controllers/_masthead.php /home/dev/joseph_chiang/miiicasa/index/modules/common/views/_masthead.php /home/dev/joseph_chiang/miiicasa/static/common/_masthead.js /home/dev/joseph_chiang/miiicasa/static/common/_masthead.css
codeigniter open common/_masthead 等於下面的指令:
好處:模組化開發讓各別團隊成員能專注在單一功能的開發上、不需要煩惱整頁複雜的架構、或共用 API 後面複雜的邏輯 (剛的多國語系不好搞)。另外在測試上也可以以模組為單位單獨測試、符合 Unit Test 的精神
http://www.flickr.com/photos/eye1/3184963395/by Ivan Mlinaric
josephj我第一個來的!老子說了算!
Winchester Househttp://www.crockford.com/codecamp/quality.ppt
煙囪上架屋頂?這就是疊床架屋
1. Commit/Push 時的作法
• 執行 JSLint : 必須符合 JavaScript Good Parts
• 執行 PHP CodeSniffer : 可自訂 Code Convention 檢查 PHP、JavaScript、CSS
• 執行 OptImg:提示圖檔尚未最佳化、是否要用程式自動最佳化?
若沒通過檢查就無法 Commit !
每次 Commit/Push 以 Hook 對變動檔案做檢查
敝公司的 Visual Designer 只負責製作 PSD 檔案
F2E 得自己處理圖檔最佳化的問題
PNG8 是目前公認在 Web 最好的格式
但是只有 Fireworks 支援轉換 Alpha Transparency (索引色透明)
2. Packaging 時的作法我深深認為...
F2E 寫程式最重要的就是 Maintenance你的程式必須很容易地被其它成員看懂
其它像是 Performance 或 Security 的議題大多有機會交由工具或架構處理掉
打包 (Packaging) 就是一個很好的機會
2. Packaging 時的作法• 執行 JS/CSS 的最小化與合併 例如:miii_index_d38eba51136ed0bf6d159770853b393b.css 是首頁所有 CSS 合併最小化產生的
• 執行 Static 設定檔的取代是首頁所有 CSS 合併最小化產生的
• 執行 CSS 背景圖檔取代為 DataURI/MHTML不再使用超手工的 CSS Sprites
2. Packaging 時的作法
版本控制中不應該有無法維護的檔案,例如:
合併或最小化的 CSS/JSCSS Sprites 圖檔
DataURI/MHTML 字串
就讓打包流程去產生、以其它環境做驗證
Review• 減少環境差異善用工具、制定規定,減少環境產生的差異,代碼的品質自然高!
• 模組化開發將每個模組檔案獨立、用工具減少 Performance 爭議、用架構讓模組相互溝通。
• 自動化開發透過流程整合自動化機制、減少每天浪費的時間、及每個人犯錯的機率、提昇 Performance。
相關連結
• JavaScript Module Platform @ GitHubhttp://github.com/josephj/javascript-platform-yui
• Online Demo http://josephj.com/project/javascript-platform-yui-demo
• Demo Source @ GitHub http://github.com/josephj/javascript-plaform-yui-demo
Any Questions?
http://www.flickr.com/photos/phploveme/2847931240/
Thank Youso muchiii