Upload
joseph-chiang
View
14.150
Download
5
Embed Size (px)
DESCRIPTION
WebRebuild.org 北京第四届年会 日期:2010/7/18 (六) 地点:中国航空航天大学学术交流中心 内容: 1. 减少环境差异 2. 模块化开发 3. 让犯错变得困难
Citation preview
前一份工作在
• 2.5 年:前端工程师
• 0.5 年:雅虎开发者社群传教士
• 1 年:雅虎无名小站工程师
嗨!我是啊嗚 / 蒋定宇很开心来到北京!
我的博客热爱分享、认为最好的 Solution 是讨论出来的
跑步环岛在我 29 歲
2008 年 5 月時花了 27 天
跑了 八百多公里達成跑步環島的夢想
没有不可能
身为一个程序员,我实在是非常的幸运非相关科系 (外国语文学系) 出身但却进了别人挤破头也进不去的雅虎见识到大型软件公司的架构与概念
在 D-Link 现有的网路设备上、建立互联网服务,强化与用户的关联性!
D-Link muchiii Team
现任职于
因为超有趣的概念、决定进入 D-Link!当时只觉得要把产品做出来,没预料到的是...
因为 D-Link 过去并没有互联网开发经验,一进去什么都没有、从零开始,我居然就开始建立开发环境、决定软体架构。
这些事情我在 Yahoo! 是没有机会碰的。因为它分工明确、高手多,很多工具甚至有专门负责的团队... 加上各服务大都已决定解决方案了,能够真的改变现有环境、注入自己想法的机会并不多。
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
ChromeOS
Hardware
前端开发环境 - 中心思想
• 减少环境差异代码不判断环境、设定档只有一份
• 模块化开发不管 HTML、CSS、JS 都以模块开发
• 让犯错变得困难Nicholas Zakas 說 “Make it difficult to make mistakes.“
1. 减少环境差异eliminate environment difference
判断环境、我做过的蠢事...在 JavaScript 里判断 Host、决定图档与 AJAX 路径
在 PHP 也判断路径,连接手的 RD 也依样画葫芦
你是否也有类似的判断程式,或不同环境给不同的设定档?
环境差异、开发人员数量增加、不同语言种类让这些判断代码与设定档越来越多!难以维护、也增加除错的困难度...
有没有办法可以做到?代码不判断环境、设定档只写正式环境
问题 1 : 每個環境的 Host Name 都不一樣
Development
Alpha
Staging
Production
devm1.corp.muchiii.com:5002*devm1.corp.muchiii.com:50029
devm1.corp.muchiii.comstatic.devm1.corp.muchiii.com
img[n].staging.bar.tw1.corp.muchiii.comw[n].staging.bar.tw1.corp.muchiii.com
www.muchiii.coma.mimgs.com
凡是需 Commit 至版本控管的代码仅一份组态档、且只写正式环境
对开发的程序员来说只需要做开发机 Host 的对应即可
常见的作法是修改 host 档但切换麻烦、又不支持 Port 及 Protocol 的对应
另有 Proxy PAC 档、FF 或 Chrome 插件可切换但都没办法做到每种浏览器的兼容性
经过一番寻找发现 Fiddler 或 Charles Debugging Proxy这类虚拟代理软件最符合我们的需求
对应正式环境
实际上是不存在的网址被 Charles Debugging Proxy 对应至 devm1.corp.muchiii.com:50020
Fiddler 还能做什么
Fiddler 这类的软体还能在做很多的应用,例如:
1. 协助 AJAX 的除虫。2. 协助开发时本地端切图、不需上传至服务器。3. 安插自己惯用的工具。4. 改变浏览网站不顺眼的地方。5. 模拟速度慢的环境。
身为一个前端工程师,Fiddler 真的是必备的工具!
线上除错 Online Debugging
将百度线上的 CSS 指定到桌面上的 baidu.css
帮自己添加好用的东西
即使在没有 Firebug 的地方也可以用 YUI Console
每页都可以最受台湾宅男欢迎的豆花妹
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/muchiii/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);}
因为要做性能优化、需将多个 CSS 档案最小化且合并届时 CSS 将会在网站根目录下生成
第一种相对路径的方式会造成图档路径错误第三种可行,但过于复杂、容易打错字
所以我们一律规定使用第二种方式、兼容性最好。
1.1 结语:善用一些工具跟规定、尽可能地减少代码在不同环境的差异性,可以让程式维护起来更轻松!
2. 模块化开发Modular Development
不再用「页」作为开发逻辑而是开发一个个可独立运作的 「Div 模块」
有独立的 HTML、CSS、JavaScript、甚至 Controller 档案
Modular Development模块化是网页开发主流
照片显示模块
搜寻模块
列表模块
_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)
独立的 HTML 档案
包含了许多模块档案(CSS)
各自独立的 CSS 档案
包含了许多模块档案(JavaScript)
各自独立的 JS 档案
模块化的困难点
• HTML:很好解决,只要用 include 的方式就可以做到(Performance 影响不大)
• CSS : 用 id 当 namespace 可以做到。但如果每个模组是一个档案,一页 30 个模组就会有 30 个 requests,对性能影响很大!
• JavaScript : 跟 CSS 一样会有 request 造成的性能问题。另外需要一个架构做跨模组的沟通。
$key - PHP Module 名称 or 页面名称
is_top: 放在 </head> 前或 </body> 前
另外还有 is_noscript, media 等属性可以设定
static.php 设定不同页面所要引用的 CSS/JS
但服务器请求量过多、对性能造成冲击
10 个 CSS Request
19 个 JS Request
虽然 static.php 把模块的 CSS/JS 档案都串连起来
Mini Tool
将代码缩小多个 CSS/JS 文档合并的
开发环境工具
档案再多也不用担心效能的问题
http://www.flickr.com/photos/prettypony/2644225789/
Mini 的 XML 设定档,把刚才的设定移往这里
寻找档案的位置,可定义多个。$DEV_ROOT 是在设定 Apache VirtualHost 的环境变数
每个 module 会有自己的 CSS 与 JS 档
module 可以去加入其他的 module,也可以 exclude 某个档案
index 的 CSS/JS 模块档案
经过 Mini 合并及压缩的內容:跟線上一致
ㄙ/mini?module=[Mini 模块名称]&type=[css 或 js]
也可以只观看合并但未压缩的内容
ㄙ&nominify
原本又臭又长的 static.php
29 个 Request
网页的 Request 数量超多
2 个 Request29 个 Request
精简过后的 static.php
网页的 Request 大幅减少
透过 Mini 的设定档,可将各自独立的 CSS/JavaScript 档案合并且最小化,达到效能最佳化的目的!
但需要注意 Mini 并不适用于正式环境、通常放置静态档案的服务器不支持 Server-Side Script、就算有也会对效能造成冲击。
线上的 CSS/JS 在打包后变成一个静态档
s* 用 md5_file() 检查档案内容产生的 stamp
可以减少 CDN 拉取重复的档案
JavaScript 跨模块沟通
JavaScript 若以模块为单位切分通常是独立的 Function 或 Object有系统的跨模塊沟通將會是大挑战
mod A
mod C
mod B
用户提交表单 取得资料
列表完毕
用户点选
用户点选大图
需清空列表
需填满列表
显示第一张图片
显示点选的图片
显示下一张图、选取框移动
用户点选
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/
但是缺乏纪律 (无架构、使用全域变数) 最后必将造成球员 (模块) 之间的冲突
雅虎首页前端架构师 Nicholas Zakas 的启发!
前端工程师一定要看这本跟 PPK on JavaScript 啊!
稳固 JavaScript 应用程式架构
http://www.slideshare.net/nzakas/scalable-javascript-application-architecture
当页面上多了一个模块它将不会破坏其他模组的结构、样式与行为
它将提供新的功能、让其他的模组可以与它沟通互动拿掉它时不需修改、也不会影响与其沟通模组的原有功能
Loose Coupling 鬆散耦合与其他模组的关系是松散的
http://www.thesoftwaredevotional.com/images/coupling_train.jpg
Broadcast & Listen模组沟通的方式类似 Hub 的概念
broadcast:每个 Client 都会广播自己的讯息 listen:其他 Client 只等待听到自己有兴趣的讯息去处理
一台电脑发出任何讯息,所有电脑都会收到但是其他电脑只处理它有兴趣的讯息
某个 Client 消失在内网时,不会造成其他 Client 或网路出错某个模块消失在页面时,不会造成其他模块整页无法使用
Broadcast & Listen模组沟通的方式类似 Hub 的概念
http://www.directsystems.com/support/switchvshub.php
模块是独立运作的,类似插件的概念放在任何页面上都不需修改、即可提供功能
http://www.flickr.com/photos/nadesign/4324782791/
废话少说,来看看怎么实作吧!
先制作一个整个架构的核心
Core
• Y.Core.register() : 让个别模块注册于此架构
• Y.Core._match() :替模组间做信息的对应
• Y.Core._addListener() :提供某个模组登记等待的信息
再制作模块的 API 介面
Core
• oAPI.listen() : 让目前的模块等待一个信息
• oAPI.broadcast()让目前的模块发出一个信息
• oAPI.getNode() :取得目前模块的 DOM 物件参考
API
mod mod mod
_photo_list.js 列表模块的 JavaScriptY.Core.register("photo-list", { // 此模块初始化 init: function (api) { // 这个模块有兴趣听取的两种讯息 api.listen("photo-filter-submit"); api.listen("photo-filter-response"); this.api = api; }, // 此模块在页面上 ContentReady onload: function () { // 告诉 Core 照片列表完毕,并把第一张图片路径一起提供 this.api.broadcast("photo-list-rendered", img.src); }, // 此模块收到讯息 onmessage: function (eventType, callerName, data) { switch (eventType) { case "photo-filter-response" : // 填满列表 break; case "photo-filter-submit" : // 清空列表 break; } }, _updateUI: function (data) { // 告诉 Core 照片列表完毕,并把第一张图片路径一起提供 this.api.broadcast("photo-list-rendered", img.src); }});
需清空列表
需填满列表取得资料
用户提交表单
显示第一张图片列表完毕
结语:模块开发让开发者能更专注于在单一功能的开发上、不需烦恼整页复杂的架构。另外在测试上也可以以模块为单位独立测试、符合 Unit Test 的精神(一个 TestCase 的 Scope 是很小的)。
3. 让犯错变得困难Make it difficult to make mistakes
到从零开始公司的好处就是先抢先赢!
http://www.flickr.com/photos/eye1/3184963395/by Ivan Mlinaric
josephj我第一个来的!老子说了算!
一开始我就制定了许多 Guidelines
在前一家公司时最难忘的一句话:GM Meeting 时一位高级领导对我们的品质提出质疑「As a F2E team,你们的价值究竟在哪里?」
软体开发团队必须要有规范的制定基本框架的设计
代码品质才能得到提升
任何规范与框架都是开发人员的限制但若不设限制的情况就会像...
Winchester Househttp://www.crockford.com/codecamp/quality.ppt
烟囱上盖屋顶?这就是叠床架屋
有 Guideline 不错,但是老祖宗形容地很贴切:「积习难改」、「阳奉阴违」,每个人对于自己的习惯与理念有所不同,有意无意地将 Guideline 放到一旁。
久而久之,当初大家同意的 Guideline 就会被遗忘、整个团队的代码品质开始陷入混乱...
Code Review 是一个好方法,但得花许多时间、没办法常办,即使发现了问题,也只能用妥协的方式做小部分的修改...
软体开发不应该存在著妥协电脑的世界不就是 0 与 1 吗?
作法
• 每次 Commit 会做的检查,没通过就不能过关• 执行 JSLint : JavaScript Good Parts。• 执行 PHP CodeSniffer : 可以自订代码标准检查 PHP,也支援 JavaScript 与 CSS!
• 每次 Packaging 会做的工作• 执行 Image Optimization (Smush.it) ,提醒图片需要最佳化。
• 没有压缩过的 JavaScript 与 CSS 不会被打包。
JSLint
document.write can be form of eval
PHP CodeSniffer (a.k.a phpcs)
.rule { attr: value; }
我们的 Visual Designer 只负责生成 PSD 档案
F2E 得自己处理图档最佳化的问题
PNG8 是目前公认在 Web 最好的格式
但是只有 Fireworks 支援转换成 Alpha Transparency
每次切图都万分痛苦,先打开 VD 的 PSD...
再将 PNG8 转换成索引色透明
生命就这样浪费在没有意义的事物上了
Image Optimization
图档占网站总频宽的 46%
一个指令按下去帮你搞定!
不修改就不给 Commit
打包 pkg_create & 上线 pkg_deploy
合并 JS/CSS 档案与最小化档案合并后、档名也会改变(不再使用 Mini 工具)
修改代码中的 host 名称(www.muchiii.com -> devm1.corp.muchiii.com)
pkg_create
以自动化的方式、让妥协与错误不会重复地发生
Review• 减少环境差异善用工具、制定规定,减少环境产生的差异,代码的品质自然高!
• 模块化开发让每个模块独立出来,用工具减少性能争议、用架构让模组互相沟通。
• 让犯错变得困难透过流程整合自动化机制、减少每天浪费的时间、以及每个人犯错的机率。
今天提到的规范文件、流程、程式代码或基础架构都可以跟我要
希望不同的想法、透过大家整合、能够激荡出更多火花
开发网站: http://josephj.com:50010
线上网站:http://modev.josephj.com
Any Questions?
http://www.flickr.com/photos/phploveme/2847931240/
Thank Youso muchiii