SlideShare a Scribd company logo
1 of 77
Download to read offline
JAVASCRIPT
CODE QUALITY
講者 josephj
關於 JavaScript 品質,我想說的是...
當談到	 JavaScript 品質...
大家心裡的重要性就好像左邊那一本 XD
JavaScript 的興起...
讓開發者覺得 JavaScript 就是要複製貼上
Bad JavaScript = 違章建築
寫程式應該是被維護的,而不是一看就想要拆掉的
6000 ⾏行 JavaScript!
Agenda
・在 Yahoo! 學到的教訓
・需要建立前端團隊的架構
・在 miiiCasa 學到的教訓
・需要先設計、多抽離
・未來可持續努力的方向
・自動化 Plus
成長 = 從過去的錯誤反省!
第 1 課	 from	 Yahoo!
前端⼯工程師必須成為真正的團隊、⽽而⾮非只是資源
中央游泳池
當時「前端⼯工程師」不屬於任何產品線
專案	 1
專案	 2
F2E	 Pool
不會有閒置資源
中央游泳池
當時「前端⼯工程師」不屬於任何產品線
專案	 1
專案	 2
F2E	 Pool
基本上都在專案
任務導向、缺少團隊機制
大家只管自己的眼前的案子
缺少水平的機制去管理品質
久了必會發生慘案
• 由新人負責、跟其他專案成員關在小房間
(沒有其他 F2E)
• View 全部用 JS 組、後端只給 JSON
• 不支援 NoJS、沒法上一頁
• 重複程式碼非常多,沒人敢大改
• 專案結束沒多久,新人離職
• 2012 年底,此服務關閉
永遠在我心裡的一句話
“As a team, F2E	 的價值究竟在哪裡?”
好不容易培訓⼀一個新⼈人、卻⼜又因制度不健全害了他
開始去思考「團隊」這件事
• Code Convention 團隊規範
• Code Review 定期 Review 程式碼
• Checklist 上線前需達成的清單
⾮非常重視⼀一致性、維護性
規範一些最基礎的小事情
一致性、像同一個人寫的
https://github.com/josephj/f2e-styleguide
Code Review
http://programmers.stackexchange.com/questions/170211/php-data-access-layer
程式碼接受所有⼈人檢驗
比	 JSLint	 更傷感情	 XD
https://github.com/miiicasa/youtube-iframe/issues/1
需要比較正面的態度
每次 Code Review 都能學到很多東⻄西!
Pair Programming
http://en.wikipedia.org/wiki/File:Pair_programming_1.jpg
⼀一個⼈人寫程式、⼀一個⼈人當觀察員
導入正確的模式
模組化 (Module) 與觀察者 (Observer) 模式
模組:寫法一致、避免全域變數
welcome/_notification.js
⼀一個模組即有⼀一個 JS 檔
模組:寫法一致、避免全域變數
YUI.add("welcome/_notification",	
  function	
  (Y)	
  {
	
  	
  var	
  trans	
  =	
  {},
	
  	
  	
  	
  	
  	
  module;
	
  	
  module	
  =	
  new	
  Y.Module({
	
  	
  	
  	
  	
  	
  selector:	
  "#notification",
	
  	
  	
  	
  	
  	
  init:	
  function	
  ()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  	
  	
  on:	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  viewload:	
  function	
  (node)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  	
  	
  }
	
  	
  });
},	
  "0.0.1",	
  {"requires":	
  [
	
  	
  	
  	
  	
  	
  "module"
	
  	
  ]
});
welcome/_notification.js
以 CLI ⾃自動從樣板建⽴立模組
⼀一個模組 (Partial) 配⼀一個 JavaScript 檔
好⽤用⽅方法與屬性都圍繞在此 instance
⼀一旦當此模組存在於 DOM 之中
相依模組
此模組的 Selector 或物件參考
模組:寫法一致、避免全域變數
YUI.add("welcome/_notification",	
  function	
  (Y)	
  {
	
  	
  var	
  trans	
  =	
  {},
	
  	
  	
  	
  	
  	
  module;
	
  	
  module	
  =	
  new	
  Y.Module({
	
  	
  	
  	
  	
  	
  selector:	
  "#notification",
	
  	
  	
  	
  	
  	
  init:	
  function	
  ()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  	
  	
  on:	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  viewload:	
  function	
  (node)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  	
  	
  }
	
  	
  });
},	
  "0.0.1",	
  {"requires":	
  [
	
  	
  	
  	
  	
  	
  "module"
	
  	
  ]
});
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  module.broadcast("greeting",	
  trans.greeting);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  module.listen("need-­‐love",	
  function	
  (e)	
  {	
  /*	
  do	
  something	
  */	
  });
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  new	
  Y.ScrollPagination({node:	
  node});
welcome/_notification.js
所有的功能都圍繞著模組化開發
多國語系
送廣播
聽廣播
加上其他相依模組
trans.greeting	
  =	
  module.getTrans("greeting",	
  "Hello	
  World");
,"module-­‐popup",	
  "module-­‐intl",	
  "gallery/scroll-­‐pagination"
模組:寫法一致、避免全域變數
YUI.add("welcome/_notification",	
  function	
  (Y)	
  {
	
  	
  var	
  trans	
  =	
  {},
	
  	
  	
  	
  	
  	
  module;
	
  	
  module	
  =	
  new	
  Y.Module({
	
  	
  	
  	
  	
  	
  selector:	
  "#notification",
	
  	
  	
  	
  	
  	
  init:	
  function	
  ()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  	
  	
  on:	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  viewload:	
  function	
  (node)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  	
  	
  }
	
  	
  });
},	
  "0.0.1",	
  {"requires":	
  [
	
  	
  	
  	
  	
  	
  "module"
	
  	
  ]
});
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  module.alert(trans.greeting);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  module.broadcast("greeting",	
  trans.greeting);
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  module.listen("need-­‐love",	
  function	
  (e)	
  {	
  /*	
  do	
  something	
  */	
  });
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  new	
  Y.ScrollPagination({node:	
  node});
welcome/_notification.js
所有的功能都圍繞著模組化開發
多國語系
共⽤用的 popup
送廣播
聽廣播
加上其他相依模組
trans.greeting	
  =	
  module.getTrans("greeting",	
  "Hello	
  World");
,"module-­‐popup",	
  "module-­‐intl",	
  "gallery/scroll-­‐pagination"
限制團隊成員在沙箱(Sandbox)	 中開發
功能擴充也能有一致介面
只專注開發該模組功能、無法污染外界
不只是	 JavaScript Ninja!
認識軟體⼯工程與持續集成,事半功倍!
需從軟體工程的角度出發
• Lint 自動檢查程式碼
• Combine/Compress 自動合併及壓縮 JS/CSS
• Optimize image 圖檔最佳化
• Compass 用 High Level 的語言讓 CSS 簡化
• Skeleton 自動建立樣板檔案
導⼊入⾃自動化、減少「⼿手⼯工」、才能提昇品質
在	 miiiCasa	 實踐了這些理念
很幸運可以從零開始、擔任前端⼯工程部⾨門主管
這些想法與理念都⼀一⼀一地實踐了
難道就不會有問題了嗎?
http://www.slideshare.net/josephj/ss-7705095
建立前端開發團隊
第	 2	 課 from miiiCasa
必須先設計、並導⼊入更好的 JavaScript Pattern
miiiCasa Space
家庭雲:用單一 URL 存取家中裝置上的資料
• 4	 個不同的媒體:
照片、音樂、影片、文件
• 2	 個不同的類型:
首頁列出 Storage、內頁只列目錄
• 都是檔案列表、但差異很大:
• View 都各自有差異
• 照片要 Slideshow
• 音樂要播放器
• 影片用 VLC / Flowplayer
• 文件要用 Lightbox 顯示照片、同時支援
影片、音樂、Google Drive Preview...
有時程壓⼒力...
該怎麼快速產出?
『coding』=	 複製貼上的工作
http://but.tw/2008/10/programmers_rule/
團隊的每個⼈人都有責任
用「複製、貼上」達成需求與滿足時程
• 一模組約 1,500 行 JS
• 4	 個不同的媒體
• 2	 個不同的類型
• 差異很大 = 修修改改
1,500*4*2 = 12,000 行
後續有新功能都幾乎是「複製貼上 x 8」
Winchester Mystery House
http://www.flickr.com/photos/harshlight/3670192350/
外表富麗堂皇、也確實地達成應有功能與時程
http://www.flickr.com/photos/dalvenjah/33560263/lightbox/
內部的結構...
http://www.flickr.com/photos/skinnylawyer/5570163978/
疊床架屋是軟體開發最常見的問題
在煙囪上架屋頂? ⾛走向屋頂的樓梯?
壓縮開發時程之謎
Stoyan Stefanov
The few man-hours spent writing the code
initially end up in man-weeks spent reading it.
數⼩小時寫出的程式碼、得花數週或更多的時間維護它
要在 8 個 JavaScript 上:
• 增加新功能
• 修改 Bug
• 改變邏輯
• 看不懂、乾脆重寫
⽼老闆跟專案經理永遠無法理解的事...
面對問題
未來要怎麼預防同樣的問題、或避免讓問題繼續蔓延
EDD – 設計文件
圖表
Branch
URLs
檔案結構
Controller
模組詳細說明
預先規劃的假資料
JS 的架構日益複雜
需要跟後端程式一樣先規劃
負責人先仔細思考、撰寫出此文件
所有開發人員一起討論可行性、問題點
把思考不周延之處找出來、了解配合模式
時程預估較為準確、有機會先預防
Refactoring -	 重構
重構	 =	 打掉重寫?
應避免 NIH 綜合症(非我所創、Not Invented Here Syndrome)
NO!
技術人員應該用更客觀的心態面對重構
重構 = 持續且小的改進。
開發 重構 開發 重構
把重構納入產品開發的 Iteration
......
無法⼀一開始寫出完美的程式碼
藉由實作、看到問題與需求,再著⼿手修正
逐步達成理想的程式碼品質
重構案例:Pop-up 視窗
util.showDialog(module,	
  title,	
  message,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  okText,	
  cancelText);
module.broadcast("dialog-­‐show-­‐request",	
  {
	
  	
  	
  	
  title:	
  title,
	
  	
  	
  	
  msg:	
  message,
	
  	
  	
  	
  buttons:	
  {
	
  	
  	
  	
  	
  	
  	
  	
  ok	
  :	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  label:	
  okText,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  callback:	
  okHandler
	
  	
  	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  	
  	
  	
  	
  cancel	
  :	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  label:	
  cancelText
	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  }
});
new	
  Y.Panel({
	
  	
  	
  	
  headerContent:	
  title,
	
  	
  	
  	
  bodyContent:	
  message,
	
  	
  	
  	
  buttons:	
  []
	
  	
  	
  	
  render:	
  true,
	
  	
  	
  	
  visible:	
  true
})
過去⾄至少有三種不同的作法
統⼀一作法、將預設⾏行為確認
module.alert(message);
module.confirm({
	
  	
  	
  	
  title	
  	
  	
  :	
  title
	
  	
  	
  	
  content	
  :	
  message
},	
  okHandler);
module.inform(message);
對程式碼精簡、⾏行為的⼀一致性獲得⼤大幅改善
重構案例:Pop-up 視窗
util.showDialog(module,	
  title,	
  message,	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  okText,	
  cancelText);
module.broadcast("dialog-­‐show-­‐request",	
  {
	
  	
  	
  	
  title:	
  title,
	
  	
  	
  	
  msg:	
  message,
	
  	
  	
  	
  buttons:	
  {
	
  	
  	
  	
  	
  	
  	
  	
  ok	
  :	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  label:	
  okText,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  callback:	
  okHandler
	
  	
  	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  	
  	
  	
  	
  cancel	
  :	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  label:	
  cancelText
	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  }
});
new	
  Y.Panel({
	
  	
  	
  	
  headerContent:	
  title,
	
  	
  	
  	
  bodyContent:	
  message,
	
  	
  	
  	
  buttons:	
  []
	
  	
  	
  	
  render:	
  true,
	
  	
  	
  	
  visible:	
  true
})
過去⾄至少有三種不同的作法
統⼀一作法、將預設⾏行為確認
module.alert(message);
module.confirm({
	
  	
  	
  	
  title	
  	
  	
  :	
  title
	
  	
  	
  	
  content	
  :	
  message
},	
  okHandler);
module.inform(message);
對程式碼精簡、⾏行為的⼀一致性獲得⼤大幅改善
重構的價值
減少程式碼中光怪陸離的現象
未來開發更容易
減少	 UI	 的不一致
Decoupling -	 抽離
避免把所有程式碼都放在一個	 JS	 中
為什麼會產出「一大包」JS?
• 麻煩!JS 載入需考慮「前後順序」
<script/> 有先後順序,例如載入 jQuery UI 的 Tabview.
• JS 本身缺乏「模組」的觀念
直到最近 ECMAScript 才要內建
• 「頁面」眾多、分割不易
不像其他的語言,大多只要 require 就可以使用
• 對 JavaScript 缺乏「軟體工程」的態度
非本科:對程式抽離、正規化概念薄弱。本科:對 JS 不用想這麼多吧!
抽離範例:Space Photo
• 主要功能:列出 Router USB 裡的照片。
• 其他功能:
提供下載檔案、幻燈秀、縮圖產生機制、
檔案描述、LightBox、分享、重新命名等機制。
這才是此程式中最重要的
每一個都可以另開 Module 處理
代碼抽象三原則
• DRY - 不要重複自己
出現重複時就抽象出一個解決方法
• YAGNI - 你不會需要他
快 + 簡單!不要把精力放在抽象化上
• Rule of 3 - 三次原則
當同樣的情況出現三次才進行抽象化
http://www.ruanyifeng.com/blog/2013/01/abstraction_principles.html
功能抽離範例
space-centralize.js (共 103 行)
/**
	
  *	
  @module	
  space-­‐centralize
	
  */
YUI.add("space-­‐centralize",	
  function	
  (Y)	
  {
	
  	
  	
  	
  //	
  Implementation	
  here...
	
  	
  	
  	
  Y.Space.bindCentralize	
  =	
  bindCentralize;
},	
  "0.0.1",	
  {
	
  	
  	
  	
  "requires":	
  [
	
  	
  	
  	
  	
  	
  	
  	
  "space",	
  "node-­‐base",	
  "event-­‐resize"
	
  	
  	
  	
  ]
});
需要讓圖⽚片隨螢幕寬度置中對⿑齊,瀏覽較舒適
原本負擔很重、1500+ ⾏行的 JS 檔
/**
	
  *	
  @module	
  space/photos/_photos_main
	
  */
YUI.add("space/photos/_photos_main",	
  function	
  (Y)	
  
{
	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  Y.Space.bindCentralize();
	
  	
  	
  	
  //	
  ...
},},	
  "0.0.1",	
  {
	
  	
  	
  	
  "requires":	
  [
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  	
  	
  	
  	
  "space-­‐centralize",
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  ]
});
只增加兩行
採用模組化	 Library
解決 HTML 中 JavaScript 缺乏模組機制的問題
define(“editor”, [‘a’,’b’,’c’], function
() {
    function Editor { /* Constructor */ }
    return Editor;
});
require(["editor"], function (Editor) {
    new Editor();
});
editor.js – 定義 editor 模組
demo.js – 使⽤用 editor 模組
任何⼀一個網站都應該要⽤用!
應加入的規範
• 一個 JS 檔案不應超過 500 行
• 一行不應超過 100 個字元
維護一個大雜匯的 JavaScript 有何意義?
會超過 500 行應代表你該抽離功能了
未來還能做些什麼
給自己未來的一些題目
大多是更多工具的整合、讓自動化來提升品質
⼯工具 ⼯工程師
• 無聊
• 重複性的
• 浪費時間的 藉由⼯工具持續回饋
自動偵測重複的原始碼
需要把「避免重複原始碼」變成⼀一個習慣
是很重要的一件事!
大家所熟悉的 JSLint, JSHint 卻沒有 Orz...
都只有「單一檔案內」的語法檢查
PMD	 -	 原始碼分析器
其中 CPD 工具可以分析 JS 的重複
/bin/run.sh	
  cpd	
  -­‐-­‐minimum-­‐tokens	
  50	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐-­‐files	
  ~/project/foo/js	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  -­‐-­‐language	
  ecmascript
跑出來的結果
重複的行數 重複的檔案列表
非常需要納入 Commit 流程或 Auto Build 檢查
Error Log	 管理
JavaScript 錯誤應該被即時記錄並回報
瀏覽器錯誤
window.onerror
try-catch
錯誤發生
程式決定是否要往上丟
程式決定是否要往上丟 把錯誤丟到 Server 做記錄、回報
就不用辛苦地翻程式碼找問題
控管好這兩個時間點
 	
  	
  	
  //	
  Log	
  to	
  server.
	
  	
  	
  	
  window.onerror	
  =	
  function	
  (message,	
  url,	
  line)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  var	
  queryString,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  el;
	
  	
  	
  	
  	
  	
  	
  	
  queryString	
  =	
  location.search.slice(1);
	
  	
  	
  	
  	
  	
  	
  	
  el	
  =	
  document.createElement("img");
	
  	
  	
  	
  	
  	
  	
  	
  el.src	
  =	
  LOG_URL	
  +	
  "?"	
  +	
  [
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "hostname="	
  +	
  encodeURIComponent(location.host),
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "message="	
  +	
  encodeURIComponent(message),
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "line="	
  +	
  encodeURIComponent(line),
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "url="	
  +	
  encodeURIComponent(url),
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "query="	
  +	
  encodeURIComponent(queryString)
	
  	
  	
  	
  	
  	
  	
  	
  ].join("&");
	
  	
  	
  	
  	
  	
  	
  	
  return	
  true;	
  //	
  Avoid	
  browser	
  error.	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
	
  	
  	
  	
  };
把錯誤回報給 Server
常見作法:用假圖片 Request 達成、可跨網域
但是!錯誤需要被 Grouping 才有價值
推薦工具	 - Sentry
接收各種程式語言錯誤、分組、寄通知信
Esprima
http://esprima.org/
最近只要聊到 JavaScript Code 品質,幾乎都會聽到這個工具
Esprima 運行原理
程式碼 抽象語法樹
Source Code Abstract Syntax Tree
var	
  answer	
  =	
  6	
  *	
  7;
{
	
  	
  "type":	
  "Program",
	
  	
  "body":	
  [
	
  	
  	
  	
  {
	
  	
  	
  	
  	
  	
  	
  "type":	
  "VariableDeclaration",
	
  	
  	
  	
  	
  	
  	
  "declarations":	
  [
	
  	
  	
  	
  	
  	
  	
  	
  	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "type":	
  "VariableDeclarator",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "id":	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "type":	
  "Identifier",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "name":	
  "answer"
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "init":	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "type":	
  "BinaryExpression",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "operator":	
  "*",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "left":	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "type":	
  "Literal",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "value":	
  6,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "raw":	
  "6"
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  },
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "right":	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "type":	
  "Literal",
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "value":	
  7,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "raw":	
  "7"
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  }
將程式碼轉成結構⼀一致的 AST 格式,很容易做後續處理
經過 Esprima Parse
Esprima 範例 – CodePainter
問題:每個⼈人寫的空格、引號習慣都不⼀一樣,能否統⼀一?
跑⼀一次⽤用 Esprima 實作的 CodePainter ⼯工具,問題全搞定
https://github.com/fawek/codepainter
Esprima	 的可能應用
• JSHint: 將會改用 Esprima
• 語法高亮
• 塞 Log,協助偵錯:
• 在每個 Method 都放:
console.log("someMethod()	
  is	
  executed.")
http://www.slideshare.net/ariyahidayat/javascript-parser-infrastructure-for-code-quality-analysis
Continuous Integration 持續集成
「所有」⾃自動化檢查,都應該與 CI 整合
中央 Git
個⼈人 Git
git	
  push
post-­‐receive
trigger
git	
  clone
Build
JSHint
Code Duplication
Unit Test
Functional Test
Code Coverage
通知
成功或失敗
Performance
讓檢查像喝⽔水⼀一樣簡單、確保品質
CI 伺服器
推薦服務
CodeShip
懶得⾃自⼰己架⼀一台 CI 伺服器?
市⾯面上有好幾家 SaaS 的服務可⽤用
若你的原始碼是放在 GitHub
CodeShip 與Travis 都只要勾選就可以使⽤用
把團隊更緊密的綁在一起
把所有訊息 (Commit, Wiki, Issue) 都倒進聊天室
不用交談也知道彼此的做了什麼、點選可看詳細內容
文學編程
Literate Programming
寫程式的理想型態
Donald Knuth
現代電腦科學的鼻祖
A style of programming that maximize our
ability to perceive the structure of a complex
piece of software.
文學編程的理念
「是時候了,讓我們的程式碼更好!」
文學編程是一種寫程式的理想形態 :
讓我們對於軟體的每個複雜環節都能
充分地理解
更有組織維護自己的文件
Leo Editor - 依自己的思路撰寫文件、組織代碼
可以是任何的內外部⽂文件、
節點可以任意地被複製搬移
⾃自由地組織、編排節點順序
產出的程式碼可與其他⼈人 Merge、Leo 會幫你追蹤
⽀支援Textile、Web 投影⽚片的輸出
更有組織維護自己的文件
Leo Editor - 依自己的思路撰寫文件、組織代碼
可以是任何的內外部⽂文件、
節點可以任意地被複製搬移
⾃自由地組織、編排節點順序
產出的程式碼可與其他⼈人 Merge、Leo 會幫你追蹤
⽀支援Textile、Web 投影⽚片的輸出
Leo Editor 很強大、也不針對特定語言,但是...
每個人都有自己愛用的編輯器(Vim 或 Sublime)
Leo 在程式碼編輯功能上似乎不怎麼樣...
在一堆編輯器中切換也是件很愚蠢的事
以喜歡的編輯器、⽤用⽂文學編程寫 JavaScript
Leo	 的缺點
https://github.com/jostylr/literate-programming
以	 JavaScript	 實作的文學編程
編譯	 Markdown
產出	 JavaScript
James Taylor
https://gist.github.com/josephj/5580918
Demo
>	
  
File	
  count.js	
  saved
literate-­‐programming	
  ⽂文學編程.md	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
寫程式就像寫部落格⼀一樣!
可重新組合章節
讓別⼈人⾮非常容易理解
Literate CoffeeScript
CoffeeScript 的作者 = 文學編程的大力推廣者
Jeremy Ashkenas
Journo 部落格系統
Docco API 文件產生器
以⽂文學咖啡寫成:
缺點:得依照原始碼的順序寫
Journo 的 README.md
就是部落格系統的完整原始碼 (journo.litcoffee)
$	
  coffee	
  -­‐c	
  journo.litcoffee	
  #output	
  journo.js
文學編程過去不是主流、未來也不會
文學編程小結
但身為一個開發者,應秉持文學編程的精神:
「程式碼是給人閱讀的」
以上兩種作法,似乎也可以稱為「部落格編程」
是我們現今最容易理解技術的一種 Material
Code Review
設計⽂文件 產出 API ⽂文件
模組化
模組架構代碼規範
Pair Programming
檢查清單
⾃自動合併與最⼩小化
Lint
單元測試
物件導向
重構
代碼重複檢查
JS 語法分析、重置
持續整合
品質的 TODO LIST
抽離原則
⽂文學編程
團隊活動 觀念及架構 ⾃自動化
整合訊息
看團隊需求來做導入或整合
Prototyping
寫程式是個良心的事業
過去的評價會⼀一直跟著你,我們應該盡⼒力寫好
程式碼品質,大師們都會強調再強調
2b || !2b
that is a question.
Thank you!
• GitHub - josephj
• Facebook - 蔣定宇
• Slideshare - josephj
• Linkedin - josephj6802
聯繫我

More Related Content

What's hot

程式人雜誌 2015年五月
程式人雜誌 2015年五月程式人雜誌 2015年五月
程式人雜誌 2015年五月鍾誠 陳鍾誠
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練Joseph Chiang
 
前端开发之Js
前端开发之Js前端开发之Js
前端开发之Jsfangdeng
 
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染Sheng-Han Su
 
Debugging - 前端工程開發實務訓練
 Debugging - 前端工程開發實務訓練 Debugging - 前端工程開發實務訓練
Debugging - 前端工程開發實務訓練Joseph Chiang
 
Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1modou li
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoloadjay li
 
JQuery Mobile 框架介紹與使用 20140713
JQuery Mobile 框架介紹與使用 20140713JQuery Mobile 框架介紹與使用 20140713
JQuery Mobile 框架介紹與使用 20140713EZoApp
 
常見設計模式介紹
常見設計模式介紹常見設計模式介紹
常見設計模式介紹Jace Ju
 
Android vs e pub
Android vs e pubAndroid vs e pub
Android vs e pub永昇 陳
 
JQuery Mobile 框架介紹與使用
JQuery Mobile 框架介紹與使用JQuery Mobile 框架介紹與使用
JQuery Mobile 框架介紹與使用EZoApp
 
jQuery 教學 ( 搭配 EZoApp )
jQuery 教學 ( 搭配 EZoApp )jQuery 教學 ( 搭配 EZoApp )
jQuery 教學 ( 搭配 EZoApp )EZoApp
 
advanced introduction to codeigniter
advanced introduction to codeigniteradvanced introduction to codeigniter
advanced introduction to codeigniterBo-Yi Wu
 
J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架wtxidian
 
前端MVC之backbone
前端MVC之backbone前端MVC之backbone
前端MVC之backboneJerry Xie
 
J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架fangdeng
 
2011 JavaTwo JSF 2.0
2011 JavaTwo JSF 2.02011 JavaTwo JSF 2.0
2011 JavaTwo JSF 2.0Anthony Chen
 

What's hot (20)

程式人雜誌 2015年五月
程式人雜誌 2015年五月程式人雜誌 2015年五月
程式人雜誌 2015年五月
 
YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練YUI 教學 - 前端工程開發實務訓練
YUI 教學 - 前端工程開發實務訓練
 
前端开发之Js
前端开发之Js前端开发之Js
前端开发之Js
 
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
從改寫後台 jQuery 開始的 Vue.js 宣告式渲染
 
Debugging - 前端工程開發實務訓練
 Debugging - 前端工程開發實務訓練 Debugging - 前端工程開發實務訓練
Debugging - 前端工程開發實務訓練
 
Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1Uliweb cheat sheet_0.1
Uliweb cheat sheet_0.1
 
Django step0
Django step0Django step0
Django step0
 
Javascript autoload
Javascript autoloadJavascript autoload
Javascript autoload
 
2021laravelconftwslides10
2021laravelconftwslides102021laravelconftwslides10
2021laravelconftwslides10
 
jQuery入門
jQuery入門jQuery入門
jQuery入門
 
JQuery Mobile 框架介紹與使用 20140713
JQuery Mobile 框架介紹與使用 20140713JQuery Mobile 框架介紹與使用 20140713
JQuery Mobile 框架介紹與使用 20140713
 
常見設計模式介紹
常見設計模式介紹常見設計模式介紹
常見設計模式介紹
 
Android vs e pub
Android vs e pubAndroid vs e pub
Android vs e pub
 
JQuery Mobile 框架介紹與使用
JQuery Mobile 框架介紹與使用JQuery Mobile 框架介紹與使用
JQuery Mobile 框架介紹與使用
 
jQuery 教學 ( 搭配 EZoApp )
jQuery 教學 ( 搭配 EZoApp )jQuery 教學 ( 搭配 EZoApp )
jQuery 教學 ( 搭配 EZoApp )
 
advanced introduction to codeigniter
advanced introduction to codeigniteradvanced introduction to codeigniter
advanced introduction to codeigniter
 
J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架
 
前端MVC之backbone
前端MVC之backbone前端MVC之backbone
前端MVC之backbone
 
J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架J engine -构建高性能、可监控的前端应用框架
J engine -构建高性能、可监控的前端应用框架
 
2011 JavaTwo JSF 2.0
2011 JavaTwo JSF 2.02011 JavaTwo JSF 2.0
2011 JavaTwo JSF 2.0
 

Similar to JavaScript Code Quality

Kissy design
Kissy designKissy design
Kissy designyiming he
 
Kissy模块化实践
Kissy模块化实践Kissy模块化实践
Kissy模块化实践yiming he
 
Android 智慧型手機程式設計
Android 智慧型手機程式設計Android 智慧型手機程式設計
Android 智慧型手機程式設計Kyle Lin
 
JavaScript 脚本控件(二)
JavaScript 脚本控件(二)JavaScript 脚本控件(二)
JavaScript 脚本控件(二)RANK LIU
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事Ben Lue
 
180518 ntut js and node
180518 ntut js and node180518 ntut js and node
180518 ntut js and nodePeter Yi
 
用Jquery实现拖拽层
用Jquery实现拖拽层用Jquery实现拖拽层
用Jquery实现拖拽层yiditushe
 
JavaScript Advanced Skill
JavaScript Advanced SkillJavaScript Advanced Skill
JavaScript Advanced Skillfirestoke
 
網站設計100步
網站設計100步網站設計100步
網站設計100步evercislide
 
YUI介绍和使用YUI构建web应用
YUI介绍和使用YUI构建web应用YUI介绍和使用YUI构建web应用
YUI介绍和使用YUI构建web应用Adam Lu
 
旺铺前端设计和实现
旺铺前端设计和实现旺铺前端设计和实现
旺铺前端设计和实现hua qiu
 
前端杂乱分享
前端杂乱分享前端杂乱分享
前端杂乱分享shyboyzk
 
Node getting-started
Node getting-startedNode getting-started
Node getting-startedlylijincheng
 
Javascript之昨是今非
Javascript之昨是今非Javascript之昨是今非
Javascript之昨是今非Tony Deng
 
NodeJS基礎教學&簡介
NodeJS基礎教學&簡介NodeJS基礎教學&簡介
NodeJS基礎教學&簡介GO LL
 
Backbone.js and MVW 101
Backbone.js and MVW 101Backbone.js and MVW 101
Backbone.js and MVW 101Jollen Chen
 
4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程zhang shuren
 

Similar to JavaScript Code Quality (20)

Kissy design
Kissy designKissy design
Kissy design
 
Kissy模块化实践
Kissy模块化实践Kissy模块化实践
Kissy模块化实践
 
Android 智慧型手機程式設計
Android 智慧型手機程式設計Android 智慧型手機程式設計
Android 智慧型手機程式設計
 
JavaScript 脚本控件(二)
JavaScript 脚本控件(二)JavaScript 脚本控件(二)
JavaScript 脚本控件(二)
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事
 
180518 ntut js and node
180518 ntut js and node180518 ntut js and node
180518 ntut js and node
 
用Jquery实现拖拽层
用Jquery实现拖拽层用Jquery实现拖拽层
用Jquery实现拖拽层
 
JavaScript Advanced Skill
JavaScript Advanced SkillJavaScript Advanced Skill
JavaScript Advanced Skill
 
網站設計100步
網站設計100步網站設計100步
網站設計100步
 
YUI介绍和使用YUI构建web应用
YUI介绍和使用YUI构建web应用YUI介绍和使用YUI构建web应用
YUI介绍和使用YUI构建web应用
 
旺铺前端设计和实现
旺铺前端设计和实现旺铺前端设计和实现
旺铺前端设计和实现
 
前端杂乱分享
前端杂乱分享前端杂乱分享
前端杂乱分享
 
Node getting-started
Node getting-startedNode getting-started
Node getting-started
 
Javascript之昨是今非
Javascript之昨是今非Javascript之昨是今非
Javascript之昨是今非
 
I os 07
I os 07I os 07
I os 07
 
Js培训
Js培训Js培训
Js培训
 
NodeJS基礎教學&簡介
NodeJS基礎教學&簡介NodeJS基礎教學&簡介
NodeJS基礎教學&簡介
 
react-zh-hant.pdf
react-zh-hant.pdfreact-zh-hant.pdf
react-zh-hant.pdf
 
Backbone.js and MVW 101
Backbone.js and MVW 101Backbone.js and MVW 101
Backbone.js and MVW 101
 
4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程4.2第四章 swarm代码剖析 可选补充课程
4.2第四章 swarm代码剖析 可选补充课程
 

More from Joseph Chiang

Automatic Functional Testing with Selenium and SauceLabs
Automatic Functional Testing with Selenium and SauceLabsAutomatic Functional Testing with Selenium and SauceLabs
Automatic Functional Testing with Selenium and SauceLabsJoseph Chiang
 
From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)Joseph Chiang
 
前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練Joseph Chiang
 
Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練Joseph Chiang
 
Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Joseph Chiang
 
Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Joseph Chiang
 
前端工程開發實務訓練
前端工程開發實務訓練前端工程開發實務訓練
前端工程開發實務訓練Joseph Chiang
 
CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練Joseph Chiang
 
HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練Joseph Chiang
 
模块加载策略 - 2012 SDCC, 北京
模块加载策略 - 2012 SDCC, 北京模块加载策略 - 2012 SDCC, 北京
模块加载策略 - 2012 SDCC, 北京Joseph Chiang
 
YUI is Sexy (for JSDC.tw)
YUI is Sexy (for JSDC.tw)YUI is Sexy (for JSDC.tw)
YUI is Sexy (for JSDC.tw)Joseph Chiang
 
YUI is Sexy - 使用 YUI 作為開發基礎
YUI is Sexy - 使用 YUI 作為開發基礎YUI is Sexy - 使用 YUI 作為開發基礎
YUI is Sexy - 使用 YUI 作為開發基礎Joseph Chiang
 
Git - The Social Coding System
Git - The Social Coding SystemGit - The Social Coding System
Git - The Social Coding SystemJoseph Chiang
 
分享無名小站 API
分享無名小站 API分享無名小站 API
分享無名小站 APIJoseph Chiang
 
yui3 is Sexy - 使用 YUI 3 的 Sexy Part !
yui3 is Sexy - 使用 YUI 3 的 Sexy Part !yui3 is Sexy - 使用 YUI 3 的 Sexy Part !
yui3 is Sexy - 使用 YUI 3 的 Sexy Part !Joseph Chiang
 

More from Joseph Chiang (20)

Let's Redux!
Let's Redux!Let's Redux!
Let's Redux!
 
Automatic Functional Testing with Selenium and SauceLabs
Automatic Functional Testing with Selenium and SauceLabsAutomatic Functional Testing with Selenium and SauceLabs
Automatic Functional Testing with Selenium and SauceLabs
 
From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)From Hacker to Programmer (w/ Webpack, Babel and React)
From Hacker to Programmer (w/ Webpack, Babel and React)
 
JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
F2E for Enterprise
F2E for EnterpriseF2E for Enterprise
F2E for Enterprise
 
F2E, the Keystone
F2E, the KeystoneF2E, the Keystone
F2E, the Keystone
 
前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練前端的未來 - 前端工程實務訓練
前端的未來 - 前端工程實務訓練
 
Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練Performance 入門 - 前端工程開發實務訓練
Performance 入門 - 前端工程開發實務訓練
 
Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練Javascript 入門 - 前端工程開發實務訓練
Javascript 入門 - 前端工程開發實務訓練
 
Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練Node.js 入門 - 前端工程開發實務訓練
Node.js 入門 - 前端工程開發實務訓練
 
前端工程開發實務訓練
前端工程開發實務訓練前端工程開發實務訓練
前端工程開發實務訓練
 
CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練CSS 入門 - 前端工程開發實務訓練
CSS 入門 - 前端工程開發實務訓練
 
HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練HTML 入門 - 前端工程開發實務訓練
HTML 入門 - 前端工程開發實務訓練
 
模块加载策略 - 2012 SDCC, 北京
模块加载策略 - 2012 SDCC, 北京模块加载策略 - 2012 SDCC, 北京
模块加载策略 - 2012 SDCC, 北京
 
YUI is Sexy (for JSDC.tw)
YUI is Sexy (for JSDC.tw)YUI is Sexy (for JSDC.tw)
YUI is Sexy (for JSDC.tw)
 
YUI is Sexy - 使用 YUI 作為開發基礎
YUI is Sexy - 使用 YUI 作為開發基礎YUI is Sexy - 使用 YUI 作為開發基礎
YUI is Sexy - 使用 YUI 作為開發基礎
 
Git - The Social Coding System
Git - The Social Coding SystemGit - The Social Coding System
Git - The Social Coding System
 
miiiCasa is Fun
miiiCasa is FunmiiiCasa is Fun
miiiCasa is Fun
 
分享無名小站 API
分享無名小站 API分享無名小站 API
分享無名小站 API
 
yui3 is Sexy - 使用 YUI 3 的 Sexy Part !
yui3 is Sexy - 使用 YUI 3 的 Sexy Part !yui3 is Sexy - 使用 YUI 3 的 Sexy Part !
yui3 is Sexy - 使用 YUI 3 的 Sexy Part !
 

JavaScript Code Quality