Quantcast
Channel: 小惡魔 – 電腦技術 – 工作筆記 – AppleBOY
Viewing all 325 articles
Browse latest View live

6to5 JavaScript Transpiler 重新命名為 Babel

$
0
0
es6-logo

先前寫了一篇 CoffeeScript 轉 ES6,裡面有提到 6to5 專案,此專案幫助開發者可以直接寫 JavaScript ECMAScript 6,該專案則會將 ES6 轉成 ES5,但是目前瀏覽器對於 ES6 的支援度還沒有很高,可以直接參考 ECMAScript 6 compatibility table,但是看到專案名稱 6to5,就會覺得如果之後 ES7 出來,不就要多開一個 7to6 專案,果然官方在 Blog 宣佈將名稱正式轉為 BabeljsBabel 也會持續使用最新 JavaScript Standard 開發 JavaScript transpiler 相關工具,讓各種平台程式都可以使用。

現在就可以透過 Babel 來開發 ES6

$ npm install --global babel

ES6 轉 ES5

$ babel script.js

一些來自 Mozilla, Esprima, jQuery Foundation, Acorn, 6to5, ESLint 組織成員,也合力開了 ESTree,而 Babel 以 ESTree 為基底來開發相關 Tool,所以最新的 Standard 也可以直接參考 ESTree。


透過 https 下載套件,取代 git protocol

$
0
0
Git-Logo-2Color

現在前端套件幾乎都會透過 Bower 來下載,而 Bower 預設使用 git protocol 來下載原始檔案,如果遇到 timeout 逾時,也就是無法透過 git:// 方式,就必須要切換成 https:// 下載,蠻多人遇到此問題,網路上找到這篇 bower install – github.com connection timed out 解答。在 Console 視窗噴出底下錯誤訊息,就請改用 https 方式。

Additional error details: fatal: unable to connect to github.com: github.com[0: 192.30.252.130]: errno=Connection timed out

切換方式很容易,請在 Console 鍵入底下指令

$ git config --global url."https://".insteadOf git://

遇到 bower install 卡卡的也可以用這招 XD

Ruby Deploy With Capistrano 碰到 SSH Connection Closed

$
0
0
CapistranoLogo

Ruby 開發環境最常用的 Deploy 工具就是 Capistrano,讓開發者可以快速部署程式碼,在部署進行中,由於大量的 js 及 css 需要處理,所以花最長的時間就是 assets:precompile,執行 cap deploy 就會發現卡在底下錯誤訊息

** [whenever:update_crontab] exception while rolling back: Net::SSH::Disconnect, connection closed by remote host *** [deploy:update_code] rolling back * executing “rm -rf /home/deploy/nami/releases/20150317135422; true” servers: [“xxxxx.tw”] ** [deploy:update_code] exception while rolling back: Net::SSH::Disconnect, connection closed by remote host

遇到這問題顧名思義就是 ssh timeout,造成原因就是由於 assets:precompile 執行時間過長,所以 Client 端的 ssh 就斷線,要解決這其實不難,請在 Server 端的 sshd 設定檔加入底下參數

ClientAliveInterval 120
ClientAliveCountMax 3

我們來看看 ClientAliveInterval 跟 ClientAliveCountMax 分別代表什麼意思,ClientAliveInterval 以上面例子來說,就是如果 120 秒內沒有收到 Client 端任何訊息,則 Server 會透過加密通道發送 Requerst 並且等待 Client 回應,而 ClientAliveCountMax 的用途就是,如果 120 秒沒收到回應,則繼續發送 Request 的次數,所以看到上面設定,就可以知道 120 * 3 秒後都沒有收到 Client 回應,則 SSH Server 就會強迫斷線,也就是會看到 Net::SSH::Disconnect。SSH 的設定檔位置為 /etc/ssh/sshd_config,完成後請記得重新啟動 sshd。

伺服器設定完成後,我們來看看 Client 端也要設定,請打開 /etc/ssh/ssh_config 輸入底下參數

ServerAliveInterval 120

讓 Client 端,每 120 秒可以送 response 給 Server 端,這樣就可以保持 ssh 連線。

參考:SSH Connection Closed While Deploying With Capistrano

Amazon 推出無限儲存空間方案 一年只要 60 美元

$
0
0

Wird 網站上看到這篇 Amazon’s New Unlimited Cloud Storage Is Absurdly Cheap,也就是說 Amazon 正式加入儲存空間競爭者,在儲存空間方案來說 Amazon 推出一年只要 $60 美金就可以無限制儲存任何檔案,這消息實在是太驚豔了,過去各大公司不曾有這樣的服務啊,像是 Google 每年 $120 美金只有 1 TB 儲存空間,Dropbox 一年 $100 也是只有 1 TB 封頂,而 iCloud 也是需要 $240 美金,從來都沒有人推過一年只要 $60 美金然後無限制空間啊,這真的是好殺啊,底下來看看 Amazon 推出的這兩個方案

Amazon Cloud Drive

如果大家覺得一年 $60 美金太貴,而你只需要上傳照片而已,還可以選擇一年只要 $12 美金的無限照片儲存空間,這價錢比 Yahoo Flickr 還要殺啊,Flickr 目前沒有免費空間方案了,但是在以前的會員還是可以用每年 $24.5 的價格持續購買無限空間方案,所以以目前所有的儲存空間服務來說,Amazon 已經是最好的了,可以先試用三個月,三個月後才開始付費沒關係。剛剛上去體驗看看,發現只能儲存以及透過 email 分享照片,並無像 Flickr 一樣可以透過 http 連結方式放到 Blog 上面,看來我還是繼續買 Flickr 比較適合,因為我幾乎都是用在寫部落格啊。

CodeIgniter 3.0 Release 終於釋出啦

$
0
0
CodeIgniter

從 2.2.x 版本到現在的 3.0 Release,終於等到釋出大家所期待的 3.0,此版本跟 2.2.x 版本差距極大,修正很多 bugs 重構很多程式碼,官網列出底下重大修正,要嘗鮮的請直接下載

  • CodeIgniter 使用 MIT 版權宣告
  • 重構各種 Database Driver library
  • 支援 PDO 所有函數
  • 重新撰寫 Session Library,支援 Native Session
  • 重新撰寫 Encryption library
  • 已加強單元測試部分,以及改善程式碼覆蓋率
  • 官方建議使用 PHP 5.4 或更新版本,但是官方仍繼續支援 PHP 5.2.4

詳細資料,可以參考官方的 ChangeLog,如果要升級 CodeIgniter 2 到 3,請詳細參考升級文件

PS:台灣官網部分近期內會修正

Git Flow and JavaScript Coding Style

$
0
0
github-logo

Git 已經是每日必備使用的指令,在平常工作上常常使用到 git rebasegit merge,發現很多工程師不知道什麼時候該用 rebase 什麼時候該用 merge,所以做了底下投影片來清楚描述 git rebase 及 merge 的優缺點及使用時機。

此投影片最主要的目的是要讓工程師善用 git rebase 而不是濫用 git merge,無意義的 merge 會讓整個分支線看起來非常亂,以我在 github 跟其他 open source project 上面 review 看到的問題,只要是 PR 內有任何衝突,一律會請開發者 rebase 主分支,並進行 squash commit,所以對我而言,開發新功能或解 bug 會用到的都是 git rebase,幾乎很少的情況會使用到 git merge。附上兩個比較的線圖,清爽度看起來就是有所不同。

git merge

git_merge

git rebase

git_rebase

如上圖比較發現如果自行開發的 branch 常用 git merge 方式合併主分支,就會多出很多無意義的分支。投影片最後討論到 JavaScript Coding Style 問題,相信在團隊合作之間,務必要制定 Coding Style 規範,透過 JSCS 來制定,而常用的 JSCS Rule 可以在 node-jscs 找到像是 Google jQuery Grunt Airbnb .. 等規範,而我個人比較推崇 Airbnb JavaScript Style Guide,因為新進人員可以快速看完整個 Style Guide 文件,非常完整,團隊可以不用再額外寫任何範例,只要針對文件增加或減少條件即可。

Mac iTerm2 + tmux 搭配 Mouse mode

$
0
0

Screen Shot 2015-05-02 at 10.17.10 AM

在 Mac 上必裝 iTerm2 終端機軟體搭配 copy mode 相當好用,只要用滑鼠選擇了一段文字,系統就會自動幫忙 copy,接著在任何地方就可以直接使用 command + v 貼上,如果要多視窗操作,可以安裝 tmux 多視窗軟體,如果使用了 tmux 你會發現滾輪滑鼠無法使用了,也就是看不到執行過的畫面跟指令,這時候就要調整 tmux 設定檔,補上 Mouse mode 設定檔

# Mouse mode

set -g mode-mouse on
set -g mouse-resize-pane on
set -g mouse-select-pane on
set -g mouse-select-window on

使用上述的 mouse mode 後會發現原本 copy mode 又不能使用了,這時候我想到的解法就是透過 tmux bind key 功能,隨時可以將 mouse mode 關掉,讓原本的滑鼠可以使用 copy mode,底下是 bind key 做法

# Toggle mouse on
bind m \
  set -g mode-mouse on \;\
  set -g mouse-resize-pane on \;\
  set -g mouse-select-pane on \;\
  set -g mouse-select-window on \;\
  display 'Mouse: ON'

# Toggle mouse off
bind M \
  set -g mode-mouse off \;\
  set -g mouse-resize-pane off \;\
  set -g mouse-select-pane off \;\
  set -g mouse-select-window off \;\
  display 'Mouse: OFF'

這時候使用者可以透過 ctrl + a + M 來關閉 mouse mode,但是總覺得這方式還是有點麻煩,所以找了一下 stackoverflow 的解法,發現有快速鍵可以解決此問題,在 tmux 底下使用 mouse mode 如果要複製文字,可以先按下 option 鍵 + 滑鼠選取文字,這樣就可以了,終於可以不用透過 bind key 來關閉 mouse mode 了。

在我的 dotfiles Github repo 內有 .tmux.conf 設定檔可以給大家參考,tmux 快速鍵可以直接參考網路上整理好的 tmux shortcuts & cheatsheet

Node.js Mocha 延遲測試

$
0
0
687474703a2f2f662e636c2e6c792f6974656d732f336c316b306e32413155334d3149314c323130702f53637265656e25323053686f74253230323031322d30322d32342532306174253230322e32312e3433253230504d2e706e67

如果大家有在寫 Node.js Express Framework,一定對 Mocha Unit Testing 不陌生,各位工程師不要太相信自己寫的程式碼,產品上線前,務必要把 Unit Test 寫完整,如果是要 Code Refactor,那測試的重要性更是大。網站架構越來越大,功能越來越多,每寫一個新功能,都會產生 side effect,造成其他程式或邏輯出錯,這時候就需要 Unit Test 來驗證邏輯的正確性。使用 Express 寫 API 我個人會建議使用 Supertest + Should.js 來驗證後端程式碼即可,這幾套框架都是由 TJ Holowaychuk 完成。使用 supertest 也可以讓 express 不用 listen port 就可以測試。

在 Express 內如果有寫 Async 程式,在測試過程中,這時候測試最後會先拿到 response,Async 部分尚未處理完,這時就會驗證失敗,要避免錯誤驗證,解決方式就是在測試過程中使用 delay time,延遲幾秒後才開始測試。底下範例可以在測試內延遲幾秒再繼續測試。

it('enable device mobile if post same data again.', function(done) {
  DeviceMobileRels.scope('deleted').find({
    where: {
      deviceId: deviceId,
      mobileId: mobileId
    }
  }).then(function(mobile){
    should.exist(mobile);
    return request(mcs)
      .post('/xxxxxx/xxxxxxxx')
      .set('Accept', 'application/json')
      .expect(200)
      .expect('Content-Type', /json/);
  }).then(function() {
    // delay 900ms to test
    setTimeout(function () {
      return DeviceMobileRels.find({
        where: {
          deviceId: deviceId,
          mobileId: mobileId
        }
      }).then(function(mobile){
        should.exist(mobile);
        done();
      });
    }, 900);
  });
});

每一個測試時間都必須在 2000ms 內完成,如果測試 delay 時間需要延遲超過兩秒,請務必在最前面補上 this.timeout(1000); 單位是毫秒。


Laravel 5.1 is released

$
0
0

很高興昨天收到 Laravel 釋出 5.1 版本,此版本在 Laravel 發展過程中第一個長期支援的版本,底下我們就來看看 Taylor Otwell 作者在此版本釋出有什麼新功能或變化。

長期支援 5.1 版本 (第一個 LTS 版本)

自從 Laravel 在 2011 年釋出第一個版本以來,作者都採用 “release early, release often” 的方式讓開發者享有最新的功能,所以在全世界各大 PHP Framework 評比底下,Laravel 始終擁有第一名的頭銜,這時間點要開始規劃一個長期使用的版本,讓大型專案可以專注於安全性修正,而並非快速升級版本。所以 Laravel 5.1 官方打算支援 3 年的安全性修正

長期支援是 5.1 的新功能之一,當然 5.1 也有更多新功能。

新文件

Laravel 作者將文件整個翻過一遍,讓開發者可以更清楚地閱讀,這是一個非常艱鉅的任務,花了無數個小時來微調每一頁。Taylor 說他寧用延遲釋出的時間,也不要是出一個不好閱讀的文件,花這麼多的時間是值得的,因為新版文件支援快速搜尋,讓開發者可以快速找到您要的關鍵字文件

PSR-2

很高興聽到作者終於將整個專案支援 PSR-2 Coding Style,其實最主要是將 tabs 全部轉換成 spaces,另外將 control structures 全部改成在同一行,例如底下

if (....)
{
}

改成

if (....) {
}

Resolve a service from blade

現在可以直接在 Blade Template 內 resolve a service

@extends('layouts.app')
@inject('stats', 'StatisticsService')
<div>{{ $stats->getCustomerCount() }}</div>

Broadcasting Events 廣播事件

Laravel 已經支援強大的事件系統,現在更支援 Broadcasting Events,讓開發者可以透過 websocket 方式將資料傳給 client 端,此功能讓您簡單地開發一套 real-time 系統。

Better Application Unit Testing 更強大的測試

導入 laracasts 的測試套件讓開發者可以更簡單的寫測試程式

public function testNewUserRegistration()
{
    $this->visit('/register')
         ->type('Taylor', 'name')
         ->check('terms')
         ->press('Register')
         ->seePageIs('/dashboard');
}

如果想了解更多 5.1 新功能,請參考 Everything we know about Laravel 5.1 – Updated,另外可以到 Laracasts video series 觀看 5.1 功能,或者是 Matt Stauffer 寫了一系列 5.1 文章

參考: Laravel 5.1 is released

優化 Percona XtraDB Cluster for write hotspots

$
0
0
percona

Percona Blog 上看到這篇 Optimizing Percona XtraDB Cluster for write hotspots 優化多重寫入 MySQL 的狀況,舉例來說,要計算 global counter 的時候,就會遇到很頻繁的寫入 (write hotspot),目前是不能同時寫入資料到同一個 record,會造成 performance 降低,所以大家開始導入 Percona XtraDB Cluster 來解決同時間寫入到同一個 record,大家都認為,搞了三台 Percona Server,可以將寫入的動作分散到其他兩台,就不會遇到 Lock 問題,但是實際上根本就不是這樣。

在獨立 Server 同時執行 SQL 語法

簡單舉例,底下有三個 SQL 語法

# T1
UPDATE t SET ... WHERE id = 100
 
# T2
UPDATE t SET ... WHERE id = 100
 
# T3
UPDATE t SET ... WHERE id = 101

我們執行上述語法,會發現產生 row lock 在 T1 或 T2,而 T3 則會同時間執行完畢,因為 T3 不是存取同一筆資料,讓我們假設 InnoDB 先執行 T1,這時候 T2 就要等到 T1 執行完畢,才可以接著執行 T2。

同時執行寫入到 multiple nodes (PXC)

Screen Shot 2015-06-20 at 2.48.56 PM

看到上述圖,我們先假設 T1 先在 Node 1 執行,T1 會同步執行到 Node 2 和 Node 3,在這同時,T2 在 Node 2 執行就會碰到 certification test fail,這時後,T2 執行失敗,就會執行 roll back,這時候解法就是變成 T2 要 retry。結論就是 PXC 架構多台寫入解決方案不適合的。

結論

如果需要大量寫入,正確的解決方式就是將寫入寫到同一台 server,這樣全部的 Lock 都會發生在同一台,但是 PXC 架構跟獨立一台 server 效能上來比,後者還是會比較好。另外的解法就是減少寫入,將計算 counter 這狀況先寫到 redis server,等到一段時間再同步到 MySQL Server。

簡介 JavaScript ES6 物件及陣列

$
0
0
es6-logo

今年 2015 六月 17 號 Ecma International 已經同意 ECMA-262 6th edition 版本,這是在 ECMAScript 2015 Has Been Approved 看到的消息,而現在主流就是以 Babeljs 為主,將 ES2015 語法直接轉換成 ES5,讓各大瀏覽器可以繼續支援 ES2015 寫法。今天來介紹 ES2015 內如何使用物件 (Object) 或陣列 (Array)。

陣列 Array Destructuring

直接舉例子來說明,假設有一個 Array [1, 2, 3, 4, 5],我們需要三個變數分別對應到 1, 2, 3 這時候在 ES5 答案會是底下

var value = [1, 2, 3, 4, 5];
var el1 = value[0];
var el2 = value[1];
var el3 = value[2];

這時候可以發現 [el1, el2, el3] 就是 [1, 2, 3] 了,但是在 ES6 寫法內,可以直接宣告 Array 變數來直接對應 value

var value = [1, 2, 3, 4, 5];
var [el1, el2, el3] = value;

上述語法轉換成 ES5,就會是最上面的程式碼,ES6 可以不必宣告 el1, el2, el3 等變數,當然你也可以宣告後再做對應

var el1, el2, el3;
[el1, el2, el3] = [1, 2, 3, 4, 5];

在 ES6 內要怎麼寫 swapping values 呢,請看底下

[el1, el2] = [el2, el1];

上述結果就是將 el1 及 el2 的值互相對調。陣列裡面還可以有陣列對應

var value = [1, 2, [3, 4, 5]];
var [el1, el2, [el3, el4]] = value;

這時 el3 = 3, el4 = 4,非常簡單,如果是 function return array value 也可以直接對應

function tuple() {
  return [1, 2];
}
 
var [first, second] = tuple();

如果要跳過陣列內其中一個值,可以直接寫成底下

var value = [1, 2, 3, 4, 5];
var [el1, , el3, , el5] = value;

這時 el3 就是 3,正規語法就需要此功能

var [, firstName, lastName] = "John Doe".match(/^(w+) (w+)$/);

// firstName = John, lastName = Doe

還有在 ES5 我們常常要寫 default value 功能,現在可以用簡短程式碼取代

var [firstName = "John", lastName = "Doe"] = [];

這時候由於 firstName 跟 lastName 都是 undefined,所以可以使用預設 values,如果是 null 就會是 null 值喔

var [firstName = "John", lastName = "Doe"] = [null, null];

上述程式碼結果會是 firstName = lastName = null,最後還有 Spread operator 的功能

var value = [1, 2, 3, 4, 5];
var [el1, el2, el3, ...tail] = value;

可以發現 tail 的值會是 [4, 5],但是目前只有支援剩餘 Array 的寫法,底下寫法是不支援的

var value = [1, 2, 3, 4, 5];
var [...rest, lastElement] = value;
var [firstElement, ...rest, lastElement] = value;

物件 Object Destructuring

物件的寫法其實跟陣列沒有很大的差異,一樣是用物件包變數的方式宣告

var person = {firstName: "John", lastName: "Doe"};
var {firstName, lastName} = person;

物件內還有物件寫法

var person = {name: {firstName: "John", lastName: "Doe"}};
var {name: {firstName, lastName}} = person;

物件內有 Array 寫法

var person = {dateOfBirth: [1, 1, 1980]};
var {dateOfBirth: [day, month, year]} = person;

或者是 Array 包物件都支援

var person = [{dateOfBirth: [1, 1, 1980]}];
var [{dateOfBirth}] = person;

看看物件預設值寫法

var {firstName = "John", lastName: userLastName = "Doe"} = {};

如果是 null 跟陣列一樣都會是 null

var {firstName = "John", lastName = "Doe"} = {firstName: null, lastName: null};

函示宣告 Destructuring Function Arguments

一般開發者在寫 ES5 function 時,最後帶的參數一定會是物件 options,用來判斷此函示是否有其他特定需求變數

function findUser(userId, options) {
  if (options.includeProfile) ...
  if (options.includeHistory) ...
}

現在 ES6 可以直接寫成

function findUser(userId, {includeProfile, includeHistory}) {
  if (includeProfile) ...
  if (includeHistory) ...
}

這樣可以更清楚了解此函示的功能,而不用看程式碼了 XD,想開始嘗試寫 ES6 嗎?這時候就要強烈推薦 Babel.js 了,參考文章:Getting Started with JavaScript ES6 Destructuring

用一張圖學習 JavaScript

$
0
0
javascript-logo

GitHub 上的 javascript-in-one-pic 作者將 JavaScript 一些基本用法整理成 PDF, PNG .. 等版本,讓開發者可以一目了然學習基本 JavaScript 用法,這專案啟動沒多久就一堆人 Star 了,看到作者是參考之前我有參與翻譯的 JavaScript GardenProfessional JavaScript for Web Developers 這本書,目前尚未全部整理完整,已經整理的目錄如下

  • Identifier
  • Data Type
  • Operators
  • Reference Type
  • Flow Control

大家可以印出來,放在座位前面,好像是個不錯的方法。

js in one pic

Awesome List

$
0
0
Screen Shot 2015-07-01 at 9.03.44 AM

@sindresorhus 建立一個強大的專案叫做 awesome,裡面收集了各式各樣的 Awesome List,包含 Programming Languages, Front-end Development, Back-end Development 等等,只要可以收集到非常 Awesome 的 Project List,經過大家認證,認為收集此列表非常俱有價值性,而不是把一堆教學文件集合在一起,程式開發者必定參考到這裡面列表。看到有人提出加入 Regular Expression 列表@arthurvr 就回覆底下

That’s not what an awesome list should be. It should be a curated list of the best things. Not a “collection of everything”

原發問者不了解 curated list of the best things,最後 @sindresorhus 拿了 w3schools 來回答為什麼 w3schools 總是能在搜尋排行榜第一名

Because they use sleazy and spammy SEO optimizations to get there.

有夠好笑的,原來大家都是很討厭 w3schools,難怪會有 W3Schools Hider 外掛

git tips 找尋遺失的 commit 紀錄

$
0
0
github-logo

個人每天常用的常用的三大 Git 指令分別是 git reset, git pull, git rebase,但是呢有時候手殘,常常把 git reset --soft 打成 git reset --hard 造成不可預期的錯誤,朋友圈內也有人常常問我該如何救不見的 commit,其實很容易,git 對於每隔操作後產生的 commit 都會存放在 Local 端,所以基本上不用擔心 commit 記錄會不見,有一種狀況會永遠消失,那就是假設尚未 commit 目前修正過的檔案,然後下 git reset --hard HEAD,這樣的話我想誰都無法幫忙把已修正過的檔案找回來了,原因是連 git 都不知道你改了什麼啊。所以為了避免這情況方生,個人建議開發者,只要開發到一定的階段,務必要下一個 commit 當作記錄,但是你會說,這樣功能開發完後,就會有很多個 commit 非常不好看,這時候可以嘗試 git rebase 將整個功能合併成一個 commit,這樣其他開發者 review 時就會非常清楚。

現在的問題是如果開發者不小心下了 git reset --hard HEAD^,上一個 commit 就會消失了,這時候該如何救回來呢?答案可以使用 git reflog 指令然觀看開發者全部 git 的操作記錄,裡面詳細記載你曾經下過的 git 指令

$ git reflog
794be8b HEAD@{0}: reset: moving to HEAD^
5e2be6f HEAD@{1}: commit (amend): update
bfa593c HEAD@{2}: cherry-pick: update
794be8b HEAD@{3}: reset: moving to 649c658
794be8b HEAD@{4}: reset: moving to HEAD^
649c658 HEAD@{5}: commit: update
794be8b HEAD@{6}: commit (initial): addd

上面可以看到之前 commit 的記錄,接著可以透過 git reset --hard xxxxx,或者是用 git cherry-pick xxxxx 將上一個 commit ID 記錄抓回來即可。

Laravel Homestead 2.1.5 版本將不再刪除舊有資料庫

$
0
0
Laravel PHP Framework

Laravel Homestead 提供一套虛擬機器,讓開發者可以快速將 Laravel 環境架設起來。在 2.1.5 版本以前,要新增新的 Site 都會透過修改 yaml 設定檔後,直接下 homestead provision 來重新啟動 VM,問題就來了,此指令會將現有的 Database 全部刪除,重先建立一次,這樣開發者就要重新跑 DB Migration 才有資料。此問題作者聽到了,所以在 2.1.5 版本作者拿掉 Drop Database 指令,而是透過 CREATE DATABASE IF NOT EXISTS 來取代原有指令 (下面程式碼),這樣開發者就不用擔心資料會被刪除。當然作者也很貼心,如果開發者想要清除整個資料庫,一樣可以透過指令 homestead destroy 來將整個 VM 刪除即可。

// 取代原有 mysql -uhomestead -psecret -e "DROP DATABASE IF EXISTS \`$DB\`";
mysql -uhomestead -psecret -e "CREATE DATABASE IF NOT EXISTS \`$DB\` DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci";

詳細的資訊可以參考 official documentation,或參考最近修改的 commit 內容


Facebook React Jest 搭配 Webpack 測試

$
0
0
logo_og

Facebook React 就是要搭配 Webpack,Webpack 已經是前端開發的必備工具,要測試 React Component 就是要用 Facebook 開發的 Jest 框架,使用 Webpack 也許會搭配 Less or Sass Loader 讓每個 component 都可以獨立有 CSS 檔案。要在 JS 內直接引入 CSS 檔案寫法如下

import '!style!css!less!./Schedule.less';
import React, { Component } from 'react';

透過 webpack 就可以把這些 header 檔案 build 成單一檔案,但是遇到的問題是,如果搭配 Jest 測試,我們使用了 babel-jest 來做 script preprocessor 如下

{
  "devDependencies": {
    "babel-jest": "*",
    "jest-cli": "*"
  },
  "scripts": {
    "test": "jest"
  },
  "jest": {
    "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
    "testFileExtensions": ["es6", "js"],
    "moduleFileExtensions": ["js", "json", "es6"]
  }
}

接著執行 npm test,可以看到會噴出 !style!css!less!./Schedule.less not found,原因就是 babel 看不懂 !style!css!less!,這是 webpack loader 特有的寫法,要解決這問題有兩種方式

  • 所有 Less 檔案全部寫在 Top 目錄內的 app.js
  • 改寫 script preprocessor

第一種方法就是把 less 檔案都獨立寫到最外層的 app.js 檔案,因為通常 app.js 幾乎不用寫測試,裡面只是單純的 initial component 而已,這是一種方法,但是我覺得不是很好,第二種做法是直接將 babel-jest 轉出來的程式碼將 less 部分抽掉,再跑測試。首先在主目錄建立 jest-script-preprocessor.js 內容如下,透過 Regular expression 將 .less 模組去掉。

var babelJest = require('babel-jest');

module.exports = {
  process: function(src, filename) {
    return babelJest.process(src, filename)
      .replace(/require\(\'[^\']+\.less\'\);/gm, '');
  }
};

然後修改 scriptPreprocessor

"jest": {
  "scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
  "unmockedModulePathPatterns": [
    "<rootDir>/node_modules/react",
    "<rootDir>/node_modules/react-tools"
  ],
  "testFileExtensions": [
    "js",
    "jsx"
  ],
  "moduleFileExtensions": [
    "js",
    "json",
    "jsx"
  ]
}

最後建立 __tests__ 目錄,寫下第一個測試檔案

jest.dontMock('../index');

import React from 'react/addons';
let TestUtils = React.addons.TestUtils;
let About;

describe('About Test', () => {

  beforeEach(function() {
    About = require('../index');
  });

  it('should exists', function() {
    // Render into document
    let about = TestUtils.renderIntoDocument(<About />);
    expect(TestUtils.isCompositeComponent(about)).toBeTruthy();
  });
});

現在 Jest 也內建產生 coverage report 只要加上 --coverage 參數即可

Using Jest CLI v0.4.18
 PASS  src/components/About/__tests__/About.js (2.109s)
1 test passed (1 total)
Run time: 2.381s
------------|----------|----------|----------|----------|----------------|
File        |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
------------|----------|----------|----------|----------|----------------|
 About/     |      100 |      100 |      100 |      100 |                |
  index.jsx |      100 |      100 |      100 |      100 |                |
------------|----------|----------|----------|----------|----------------|
All files   |      100 |      100 |      100 |      100 |                |
------------|----------|----------|----------|----------|----------------|

All reports generated

詳細資訊可以參考 Jest Issue 有網友發了 How to test with Jest when I’m using webpack 問題,有興趣的朋友們可以參考看看。

Laravel Presenter 在 Controller 的使用

$
0
0
Laravel PHP Framework

Laravel Auto Presenter 是一套用在 view 裡的 decorates objects,搭配資料庫時,如果有需要組合或整合欄位來顯示相關資訊,這套就非常適合使用在 Laravel View 裡,如果不是透過 Laravel Auto Presenter,開發者也可以利用 Laravel Accessors & Mutators 來實現這方法,只是這要寫在 Model 層,寫法如下,此做法寫起來蠻亂的,而且也並不是每個地方都需要擴充這些欄位。

/**
 * The accessors to append to the model's array form.
 *
 * @var array
 */
protected $appends = [
    'is_twitter',
];

/**
 * Get the user's is_twitter flag.
 *
 * @param  string  $value
 * @return string
 */
public function getIsTwitterAttribute()
{
    return (bool) ($this->attributes['options'] & self::$OPTIONS['is_twitter']);
}

如果是使用 Laravel Auto Presenter 則寫法如下

<?php  namespace App\Models\Presenters;

use App\Models\User;
use Illuminate\Contracts\Support\Arrayable;
use McCool\LaravelAutoPresenter\BasePresenter;

class UserPresenter extends BasePresenter implements Arrayable
{
    public function __construct(User $resource)
    {
        $this->wrappedObject = $resource;
    }

    public function isTwitter()
    {
        return (bool) ($this->wrappedObject->info->options & self::$OPTIONS['is_twitter']);
    }

    /**
     * Get the instance as an array.
     *
     * @return array
     */
    public function toArray()
    {
        return [
            'id'        => $this->wrappedObject->id,
            'isTwitter' => $this->isTwitter(),
            'avatarUrl' => $this->avatarUrl(),
        ];
    }
}

但是使用在 Laravel View 裡面都可以正確拿到 isTwitter 欄位沒問題,如果要用在 RESTFul + 前端 ReactJS 的話,則要透過 Laravel Facades 來實現,加上 AutoPresenter::decorate 就可以在 Controller 內使用 AutoPresenter 了。

<?php

use McCool\LaravelAutoPresenter\Facades\AutoPresenter;

class MessageController extends Controller
{
    /**
     * @var Repository
     */
    private $user;

    public function __construct(UserRepository $user)
    {
        $this->user = $user;
    }

    public function index(Request $request)
    {
        $user = $this->user->with('info')->find(\Auth::id());
        $state = collect([
            'user' => AutoPresenter::decorate($user),
        ]);

        return $state;
    }
}

JavaScript in 2015

$
0
0
Screen Shot 2015-09-09 at 2.03.34 PM

在這幾年的趨勢看來,JavaScript 已經環繞在各領域了,不管在 Web 前端或後端,上層或下層,都充滿了 JavaScript,其實都是托 Node.js 的福,網路上看到這篇 JavaScript in 2015,裡面講到 JavaScript 所有的工具,不管前端到後端,每一年都有新的工具跟新的 Framework,從以前寫 BackboneAngular.js 到現在 React.js 改變了整個 JavaScript View 的生態,工具流程整合從 Grunt.jsGulp.js 的出現,整個生態又轉換了,大家陸續將工具全都轉到 Gulp,最後又出來一套 Webpack,Webpack 出現基本上不會影響 gulp 發展,因為 Webpack 還是有很多限制,在前端或後端在上 Production 前的一些流程像是 copy 檔案等,這些是 webpack 無法整合的,看到這些工具一一出現,也不知道明年或現在會不會又跑出一套新的玩具,讓整個 JavaScript 生態整個改變。寫上層的同時,看到同事在寫底層,同事就會跑過來拍拍我肩膀說:『好險我是搞 Kernel,搞上層就要跟你們一樣天天追新技術,永遠沒有停止的一天』。看一下全世界 Job Trends

Screen Shot 2015-09-09 at 2.28.21 PM Screen Shot 2015-09-09 at 2.28.28 PM

結論就是,大家快邁向全端工程師,活到老學到老。對於 Grunt 或 Gulp 的基礎介紹可以參考我分享的 Slide:

PS. 圖片來源:JavaScript in 2015

該如何寫好 git commit message

$
0
0
github-logo

Git 已經是每天必用的工具,也是團隊間互相合作的重要角色。要寫好 Git commit message,讓團隊成員可以知道每一個 Commit 代表什麼意思,這是非常重要的。網路上看到一篇教您如何寫好 Git commit message,好的 Commit Log 可以讓其他同事快速知道這個 Pull Request 包含了哪些異動,該作者寫了七點,分別如下

  1. 將標題與內容中間多一行空白
  2. 標題限制 50 字元
  3. 標題第一個字必須為大寫
  4. 標題最後不要帶上句號
  5. 標題內容可以使用強烈的語氣
  6. 內容請用 72 字元來斷行
  7. 內容可以解釋 what and why vs. how

要強制大家有共通的 commit format 其實很難,所以團隊內會使用 issue track 系統,大家把 issue 或 feature 都開好,在標題列裡面就要強制將 issue number 寫入,然後在 issue 那邊把內容及作法詳細寫清楚,方便追蹤,這樣也是可以的。

PS. 該是強迫自己把 commit log 寫好會比較好,通常在追問題,也時候也會發現自己寫的 Log 不是很清楚。

Pingdom 升級支援亞洲區服務

$
0
0
74c50c2938accf866de4cf41fefd3b9c_400x400

Pingdom 是一套偵測伺服器是否存在的工具,網站如果出問題掛點,Pingdom 會用 Email 及手機簡訊通知管理者。強大的地方不只這裡,還可以偵測 TCP, DNS, SMTP 只要是網路的 protocol 幾乎都有支援,個人買的是標準方案 (Standard),之前一直讓我很困擾的是,Pingdom 只有支援美國及歐洲伺服器,所以如果要偵測亞洲區像是新加坡等地方,ping 的 latency 幾乎都飆到 1000 ms 以上,所以變成只能讓客戶看 up time。但是昨天收到 Pingdom 升級全部方案的資訊,令人振奮的是 Pingdom 開始有亞洲區服務,底下是 Standard 升級過後的方案:

  • 支援選擇 Test 所在地 (原本 Standard 並無此服務)
  • 支援亞洲區機房 (墨爾本, 雪梨, 香港, 新加坡, or 漢城.)
  • 可以透過 IPv6 來偵測網站
  • 提供新版後台服務

以上會統一在 11/2 升級全面服務,所以目前還不能看到上述功能,另外 10 月也有優惠方案

  • 將目前訂訂閱方式由月改成年,這樣可以給 10% 折扣
  • 將目前訂訂閱方式由月改成年,別且把目前方案升級成年繳,這樣可以給 20% 折扣
Viewing all 325 articles
Browse latest View live