顯示具有 Javascript 標籤的文章。 顯示所有文章
顯示具有 Javascript 標籤的文章。 顯示所有文章

f2e-interview

最近面試好多前端,就來寫下這面試的感覺吧,不得不說前端這領域相對其他領域還是個新的領域,百家爭鳴,不像後端一樣,幾乎已經在各觸最佳實踐(又或者我接觸還不夠深)。

框架

但就我自己的看法來看目前所有的框架,到最後還是圍繞著幾個點: 1. 架構是否足夠彈性、有結構、組件化 2. 學習成本 3. 活躍社區

我認為一個好的架構不是能夠讓你少寫多少行 code,而是更結構化的幫你快速切入,讓整個團隊協同開發同時能有個中心思想,別讓樓越蓋越歪。常在面試聽到我之前用 XXX 框架開發結果性能很差,現在換了 XXX 後變好快(考試都考 100 分了 ^.<~* 啾)。其實不管什麼框架,只要你能夠有時間重構一次幾乎都會比原來更快,很簡單的道理,當你熟悉當前的業務邏輯後當然可以比起剛開始設想的更加周全,各方面自然就好起來了。

但框架不是一切,更重要的是了解這框架的實際運作方式以及前端所在容器的特性,例如在 PC 瀏覽器、手機瀏覽器、webview、各種 webkit 抽象出來的容器…等,能夠完美跟容器結合的就是最好的框架,能夠摸透框架、容器運作原理就能夠寫出做完美的結構。當前也是有許多優秀的框架,如 Reactjs, Angularjs, polymer, vuejs, … 等,每個框架設計上自然有他適合的場景,也會有他不適合的場景,能夠依照當前的需求做出最完美的配合自然是好框架。

近來如 Reactjs 發展出了 React Native,阿里造的 WEEX,也是框架上的另一種突破,讓除了熟知的 web 容器外更延伸到了 Native 重新打造一個容器,但說這個真的有未來市場在這我還是保持懷疑的態度,回想起幾年前的手機瀏覽器也是如此的不堪,近來硬體運算能力越來越強,手機瀏覽器的問題也少了。你說 React Native 是用 Native 渲染,速度很快,比起 Web 體驗好很多,接近 Native 體驗,就我目前看來都是個階段性產物,最終還是會回歸到 Web。但你說這些嘗試都沒意義嗎?其實不盡然,沒有這些創新的演進還是無法解決當前手機瀏覽器內的效能不佳問題。

專案管理、開發、測試、發佈

專案管理這邊應該指的是如何管理你的 source code,很多人或許會說直接用 git 不就好了,git 確實解決了本地開發、團隊協同開發上的問題,但在多人開發同時該如何用 git 控制好品質才是這根本問題,團隊人多,每個人的開發習慣也不同,是否在 pre-commit 進行 lint 就能夠把持?pre-commit 要跑的 lint 該如何即時同步?是否有 CI 機制保障穩定性?是不是該每個需求都切分支出來開發?是否養成送 PR 的好習慣?任何小改變該如何同步給所有人?該如何自動化?git, svn, perforce 這些都是工具,幫助開發、多人協做的工具,絕對命令行多會幾個考試就會考一百分。

管理好 source code 下一步就是該如何同步、自動化的本地開發環境,在這很多人會說用 gulp, grunt, npm, make … 等,但這又回到了工具問題,這些工具很棒,隨便 google 也可以知道很多 plugin,但我更想知道的其實是你如何用這些工具,做了哪些事情?JS 是否 lint, minify, 去除 debug 訊息…等?CSS 用什麼 preprocessor?進行了什麼處理?html 有沒有做什麼樣的處理?用了什麼模版引擎?本地模擬 API 還是統一的測試 server 模擬 API?每次 build 是如何管理版本?圖片是否壓縮?圖片以什麼方式壓縮?哪時候壓縮?…… 等等等的一堆事情,這其實才是這核心所在,絕對不是我用 gulp 管理本地環境一句化就結束。

測試應該是目前遇過最少有經驗的,10 個裡面大概有 8 個沒經驗 1 個瞎掰 1 個有簡單的經驗,這邊要特別感謝過去在趨勢有龐大又有經驗的測試陪伴著我成長,測試絕對是必要的,一個好的 RD 必須能完成三件事才算是優秀,開發完專案、高覆蓋率的測試、線上監控,能夠把視覺搞完美還原這頂多是 60 分,也就是一個入門程度,做到測試再加20,做到監控再加20。詳細測試還有很多細節就不再一一贅述,基本如果能做到 TDD…這我只能膜拜了,因為你做的事情應該跟業務已經脫節或產品週期很長。但坦白在我心中團隊中是不需要有 ”測試” 這角色,養成良好的寫測試習慣絕對有助於增加品質減少測試人力。

發佈這就又是另一門大問題,現在基本聽過的是 FTP 直接上傳 server,git/svn 直接傳,有轉職人員幫忙(好耳熟…閃開!讓專業的來!)等,其實比較想了解是整個出 build 的流程,是否用 build server 打包?打包完是人肉發還是自動發?出完 build 發上線後是如何運作?直接放上 CDN 做靜態資源還是透過模版引擎解析?

效能、兼容性

這應該是整體來說非常重要的一環,尤其在體驗上更是致命的重要,基本的 js/css/html 要 minify,減少請求數量,圖片要壓縮,icon 可以用 iconfont 或 image sprites,進階一點大概到圖片要針對不同環境載入不同壓縮品質、尺寸,打開頁面後有多少請求,總共多少 k,dom 數量如何最簡化並且控制數量,圖片不在畫面中的不要提前載入,適時使用 loader 來載入 script,該如何有效控制記憶體避免 app crash,長 list 該如何做到最好的效能,css3 的新需求要小心使用減少 render 層,cache 該如何有效應用,app 內的 webview 該如何有效利用 app 特性來 cache,預載 …等,這些東西講起來都很簡單,但就目前為止所有收到的履歷上沒有一個做到好,很多人會說這些我都知道都會,但是該如何讓大團隊也能運行起來就是能否從 junior 到 senior 的關鍵。

AMD, CMD, Commonjs 這也是我常問的一個問題,雖然也是很基礎,但我覺得蠻重要的,因為搞清楚著些組件化的方式對於整體架構上非常有幫助,在按需載入上也是重要的一環。

判斷在不同裝置、容器下做出最好的體驗,在 ie6 等較舊的瀏覽器該如何做最好的降級處理,使用哪一種寫法可以有效的兼容不同平台,用上最少的 hack,不斷使用 hack 方式只會造成越來越難以維護。

網路、安全

網路方面最重要就是跨域問題,問到很多人都回答用 jsonp 就好啦,但卻不知道 jsonp 實際上是如何運作,以及 CORS 在 http response header 該加上些什麼?http preflight 用途是什麼?200, 204, 301, 302, 400, 500, … 這些 error code 用途是什麼?哪些點可能有安全風險?該如何避免 XSS 攻擊…等。

open source

開源也是我常問的點,我相信喜歡參與開源專案的小孩不會變壞(誤,常參與開源的人大多有幾種狀況,喜歡分享,喜歡與人討論、協做,我認為這部分對於在企業內是非常加分的,分享不但可以知識沈澱還可以推廣給更多人,對於團隊長期來看是非常重要的要素,唯一要小心的就是怕把公司內部的資產也 open source 出去…

未來、新技術、設計

對於未來的眼光、敏銳度,關心 W3C 標準或更深入參與 W3C 標準定義,看到未來的技術走向並且能夠提前帶領團隊移動到這條軌道上。保持新技術的探索,就算不能參與也要保持觀望,別讓自己成為最後被通知的人,不然當你需要時永遠處於被動。對於設計、體驗要能夠感同身受,試想用戶使用的場景,不是一昧的把視覺搞、產品需求拿到就開始做,前端就是產品到用戶的最後一哩,你掌握著用戶看到這產品後的體驗,每個字大小、間距、行高或許你會比設計師更有感覺,API 慢了也要做點過場掩蓋掉,千萬別小看自己所在的這位置的重要性。

總結

剛好想到什麼就寫了什麼,簡單羅列一下,當然還有很多細節魔鬼在其中,這些是我做前端以來的一些簡單心得,也是小魯我認為身為前端該有的部分,想當年小魯我也是被老闆說了一句「你如果還想待在這家公司就轉前端吧,這邊沒有 iOS 的缺了」一個誤闖誤入,現在是相當感動當時這句話讓我更開拓新的一條路出來。

最後想說的就是…歡迎加入 天貓前端,看我們在 2015 雙11的 912 億人民幣背後做了多少準備,歡迎把履歷寄到 taicheng.htc@alibaba-inc.com

IE6,7 calc 解決方案 expressions

過去支援 IE6, 7, 8 在 CSS 上少了 calc 這個好用的功能實在很不方便,今天才知道原來在 IE7 以前的版本其實是有類似的東西可以解決「expressions」

微軟官方已經表示不再支援 expressions,但在 IE7 前還是可以使用 http://msdn.microsoft.com/en-us/library/ie/dn384050(v=vs.85).aspx

使用方式也與 calc 不太相同,在 expressions 寫的是 javascript,官方給的範例如下: <DIV ID="oDiv" STYLE="background-color: #CFCFCF; position: absolute; left:expression(document.body.clientWidth/2-oDiv.offsetWidth/2); top:expression(document.body.clientHeight/2-oDiv.offsetHeight/2)"> Example DIV </DIV>

詳細範例可以參考: http://msdn.microsoft.com/en-us/library/ms537634%28v=vs.85%29.aspx

相關連結 http://msdn.microsoft.com/en-us/library/ie/dn384050(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/ms537634%28v=vs.85%29.aspx

nodejs run coffeescript via javascript

CoffeeScript 一直都是我很愛用的語言,但使用上常常需要先 compile 成 javascript 才可以執行,如果是 F2E 的還好,畢竟在出 build 過程中直接 compile 就可以,但 nodejs 上這樣感覺有點怪,能夠直接跑 coffee 當然是最好,好在 CoffeeScript 1.7 後有了這項功能。

首先必須在專案中安裝 CoffeeScript

npm install coffee-script --save

安裝完後在程式進入點如下,其中 './lib/main' 就是 './lib/main.coffee',之後的檔案也就直接使用 CoffeeScript 來撰寫就好
require('coffee-script').register();
require('./lib/main');

相關連結
CoffeeScript

javascript 強轉 boolean,數學運算

一些小小的 javascript 數學運算,第一個是快速的無條件設去的方式,但是用 "~~" 開頭會在 jslint 被擋下,雖然是較為快速,但使用時還是必須考量一下整體的 coding style,下面的是把變數強轉為 boolean,這也是個更快速的方式,但一樣會被 jslint 擋下,斟酌使用。


web 小觀念, id 自動會變為 global 變數

如同標題,只要用加上 id,基本上都可以直接 console.log 出來 dom element,除非你用其他變數覆蓋過去,小觀念。



Javascript URL parsing

這也忘記是從哪來的,沒記錯應該是 stackoverflow.com 上找到(有發現記得告訴我),這是個快速 parsing url 的方式,使用了 html 本身的功能來做 parser,效能上當然不用多說。



Log 變為模糊

此方式可將 inspect 打開後所看到的 log 變模糊,但不是每個瀏覽器都適用,目前測試 Chrome, Safair, Opera 可以正常運作。



Javascript random string

這段真的忘記從哪來的,但相當實用,幫你產出亂碼字串,用的方式相當棒,先直接產生亂數再轉為 36 進位,其中帶入參數為想要產生幾位數的亂數。



禁止使用 iframe 讀取你的頁面

算是個小技巧,幫自己筆記一下,加上這行後別的網站就無法使用 iframe 的方式把你的網站 load 進來。

if (window.location != window.parent.location) window.parent.location = window.location;

ubuntu install phantomjs

先前在 ubuntu 上安裝 phantomjs 屢屢失敗,第一次安裝立馬使用 "apt-get" 搜尋,找到後就很放心的安裝,沒想到裝完後還是沒辦法正常使用,後來去 phantom 官方找,官方也提供了一套安裝方式,但還是有問題,還好我有個好朋友叫 google

下面這段 script 的 3-7 行其實是在反安裝 phantomjs 從 apt-get 的版本, 9-15 行為重新安裝 phantomjs 並設定位置,17 行為確認目前 phantom 版本、安裝狀況


其中特別要注意的就是 phantomjs 以及 ubuntu 的版本,必須依照所需來調整

32-bit: phantomjs-1.9.0-linux-i686.tar.bz2
64-bit: phantomjs-1.9.0-linux-x86_64.tar.bz2

togetherjs inject to your web

Togetherjs 是一個 Mozilla 所開發的讓網站多人共同協做的工具,只要瀏覽器有支援立馬就可以開始協做。

只要在下面這段 scripts 加入書籤,之後之要按下書籤就立馬可以開始使用



相關連結
Togetherjs
Mozilla
完整 scripts

Backbone solve IE ajax cache result

一般來說 Backbone 在針對 model 送 ajax 到後端時使用方法如下:


但在 IE 會針對相同的 ajax request 做 cache,所以必須將 ajax 的 cache 設定為 false,在 backbone 必須要這樣設定:


相關連結
http://stackoverflow.com/questions/6178366/backbone-js-fetch-results-cached

grunt-contrib-connect fake api with yeoman

依照現在 F2E 正夯的狀況,很多 front-end 都會希望不需要等 backend 先寫完 api 才可以接資料,或者要等 backend 先開出假的 api 後才能動工,最好的方法就是先確定好資料結構後雙方就可以開工,也可以減少 api 寫完後才發現沒辦法接好的問題。 yeoman 是個相當好用的前端開發輔助工具,尤其 liveboard 大量增加 f5/ctrl + R 的壽命,如果能再結合假資料 api 拿來測試那就再完美不過了。

立馬下載
git clone https://gist.github.com/7210042.git

使用方式 (好讀版
Step1. 下載 redirect.js 到專案根目錄.
Step2. 編輯 Gruntfile.js
var redirect = require('./redirect');

...
...


connect: {
options: {
port: 9000,
// change this to '0.0.0.0' to access the server from outside
hostname: '0.0.0.0'
},
livereload: {
options: {
middleware: function(connect) {
return [
lrSnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, 'app'),
redirect('api')
];
}
}
}
},

Step3. redirect 有三個參數. rootDir 是假 api 根目錄. indexFile 是預設連結的檔案. headers 是 http response 的 header,範例:
/app
...

/api
/user
index.json
list.json
...

/Gruntfile.js
...

Step4. run "grunt server"
當讀取 url "/user" 會自動導到根目錄的 "/api/user/index.json"
當讀取 url "/user/list.json" 會自動導到根目錄的 "/api/user/list.json"


相關連結
https://gist.github.com/IskenHuang/7210042
yeoman

node-hipchat

Hipchat 是一套相當好用的 Log system,還可以與 Github, Bitbucket, jenkins......等服務整合,團隊中打屁的同時還可以看到系統狀況,因為 Hipchat 官方給 nodejs 的不知道在寫啥鬼,所以就自己寫了一個簡單的版本

使用起來相當簡單,詳細可以參考如下,完成後就會看到你的 room 中噴出兩筆 log

var hipchat = require('./lib/hipchat');

// log warn
hipchat.logger('Hello hipchat logger - warn', 'warn');

// log error
hipchat.logger('Hello hipchat logger - error', 'error');

這麼好用的東西當然要立馬 clone
git clone git@github.com:IskenHuang/node-hipchat.git


相關連結
Hipchat
IskenHuang/node-hipchat

sailsjs differentiate api and view controller

Sails 是一套我相當喜歡的 Node.js web framework,底層仍然是使用 Express.js,另外整合了很多常用的 web 套件:grunt, socket.io, RESTful API, ......等。

由於 sails 的架構與 codeigniter 相當類似,Controller 對應到 View,並且對應到 route,在 config 中有個 controller.js 還可以對所有的 controller 做設定,如自動產生 restful api 等,以及這次的重點「prefix」,prefix 設定後在 route 上就會自動改變如下

使用 prefix 前
http://localhost/CONTROLLER_NAME/ACTION_NAME

使用 prefix 後( prefix 設定為 '/api/')
http://localhost/api/CONTROLLER_NAME/ACTION_NAME

如果只是要做 api server 相信這會是個很棒的設計,還可以作為 api 的版本區分(例如「/api/v1/」),但要做「網站」在 view 與 api 之間就必須做些區分,以下的作法就是將 view 與 api 切開,view 統一由 ViewController 控制,其他的 api 交由一般的 controller 控制,從 route 看起來如下
// ViewController
// Get user or user's view
http://localhost/user

// UserController
// Get user '1' api
http://localhost/api/user/1

資料夾目錄如下


接下來開始實作把 api 與 view 切開
首先是設定好 api 的 prefix,修改 「/config/controllers.js」


再來是設定 route 把 view 改為 '/',修改「/config/routes.js」
routes.js


最後是產生 ViewController,在 terminal 輸入
sails generate controller view

並修改 「/api/controllers/ViewController.js」



ps. 或許也可以直接做 single page design,但某些狀況下透過 controller 可以從 server side 將其他訊息一併回給前端

完整的 code 可至 Gist 查看

相關連結
Sails
Node.js
grunt
socket.io
Express.js
codeigniter

Insert CSS style into html head in build process

網頁速度慢除目前看起來最大問題就是 http request 數量太多,因為每次的 request 都需要一定的時間,如果能夠壓縮在同一個 request 是最棒的狀況,前面幾篇有把 Javascript 用 uglify 把檔案壓成一支,以及把小的圖片轉換為 data uri 隨著 html/css 一同載入,這次要做的是把 CSS 直接以 <style> tag 直接塞入 html 的 head 中,讓 CSS 的隨著 html 一起載入,請小心使用

這次的 script 一樣是由 coffeeScript 寫成,以及使用 cheerio 來作 dom select


立馬下載使用



相關連結
image in csshtml from url to uri
html script tags combined a js flie
uglify
coffeeScript
cheerio

image in css/html from url to uri

上次寫了一個單獨一個檔案轉換為 data uri ,但在網站圖片尚未完全確定前這樣做事相當花費時間而且難以驗證檔案,所以再寫了一個 script 夾帶再出 build 流程中,方便的把圖片轉換為 data uri,當然 data uri 沒辦法適用所有的圖片,所以 script 中的 minSize 就是設定要轉換的圖片尺寸上限,單位為 pixel (大約計算出檔案大小),由於 html parse 重寫一次比較麻煩,所以使用了 cheerio 方便做 dom selector

由於許久沒寫 coffeeScript 決定用這 script 快速複習一下



相關連結
cheerio
nodejs image to Data uri
coffeeScript

html script tags combined a js flie

最近每天都在做網頁效能優化,過去 javascript 可能因為很多 plugin 增加了很多 request 次數,或許可以使用 parallel 方式來加速,但始終沒解決浪費頻寬問題,使用 uglify 可以方變得解決需要壓多個 javascript ,但如果網站有一堆頁面都要這樣做一次,每次出 build 都要做一次是非常累人的事,因此寫了一個 script 來處理這個累人的問題。之後再找時間來處理些 error handle 以及,包成一個完整的 module

使用方法很簡單,下載檔案後要先設定好幾個重要的路徑

// javascript 資料夾路徑(相對路徑,相對於 uglify.js這檔案)
JSRootUrl = __dirname + '/js/',

// html 資料夾路徑(相對路徑,相對於 uglify.js這檔案)
viewRoot = __dirname+ '/../application/views',

// 要略過的檔案名稱( html 資料夾)
skipFiles = ['.DS_Store', 'mail'],

// 壓縮完的檔案名稱後需要加上哪些文字,例如 main.min.js
suffix = '.min',

// 要壓縮哪些 scripts 設定( html 資料夾的 tag 名稱)
jsTagRegex = /\\<\/script\>/ig,
設定完後只要下簡單的一行,就會進行兩件事 1. 把 html files 符合 "jsTagRegex" 這規則的 javascript 拿掉,取代為 <script src="XXXXX.min.js"></scrips> 2. 把 html 頁面中會需要用到的 javascript 壓成一支
node uglify


相關連結
uglify

Quick launch nodejs expressjs web server

Expressjs 是一套 nodejs 上非常熱門的 web framework ,提供了相當彈性的功能,豐富的社群支持,是個很棒的 nodejs web framework 選擇,但身為前端工程師常常需求只是 "想要建立一個單純的 web server ",這需求達成方法有很多, apache, nginx 等都可以達到想要的功能,但如果是同時間需要多開幾台 servser 模擬,或好多個專案在不同資料夾中透過 apache, nginx 設定可能不是這麼快速(好吧...應該是我手殘)

立馬下載

使用方法
Step1. 安裝 nodejs & npm (download: http://nodejs.org/download/)

Step2. 安裝 expressjs (http://expressjs.com/) 在 global
$ sudo npm install express -g

Step3. 立馬開始使用
$ node app

預設的 PORT 為 3000,根目錄路徑為 與 app.js 相同路徑,如果還要再多開一個呢?請多開一個 terminal ,然後再下一次" $ node app ",這時候應該會遇到錯誤訊息告訴你 server 已經開啟,所以提供了另一個功能,可以自訂 PORT 以及根目錄

開啟在 web server 在 8000 PORT 根目錄為 web1
$ node app 8000 ../web1

開啟在 web server 在 9000 PORT 根目錄為 web2
$ node app ../web2 9000


* PORT, 根目錄兩個參數前後順序可以自訂




相關連結
Expressjs
apache
nginx

nodejs image to Data uri

前端為了減少 request 數量可以說是用盡各種方式, Javascript 壓成一支, css 壓成一支,圖片用 image sprite 壓成一張大圖,用盡各種方式把 request 數量減少,讓使用者體驗變得更好。

對於圖片來說 image sprite 是一種很好的方法,但是總會問一下自已「能不能更好?」於是找到了 Data uri 的方式,把圖片轉換為字串,跟著 html, css 一起載入, HTML 的img tag 的 src ,或者 CSS 的 backbround-image 一並載入。產生 Data uri 有些線上工具可以使用,但基於懶人精神 懶得按滑鼠、懶得選取檔案、懶得連上網路(那你做 web 幹嘛!?) 所以就寫了一個簡單的工具,目的當然很簡單,不用上網( local 可以解決),不用使用滑鼠( command line 就可以執行),產生完自動幫我複製到剪貼簿(立馬可使用 ctrl + v)

根據 Caniuse 表示 Data uri 在 IE8+, firefox 2.0+, chrome 4.0+, safari 3.1+, opera 9.0+, 以及所有的 mobile browser 都有支援,所以網站如果是支援 IE8 以上的網頁應該是可以安心服用。

Gist - https://gist.github.com/IskenHuang/6434813

使用方法很簡單在下載後的檔案同目錄下輸入

node img YOUR_IMAGE_PATH

馬上就產出 data uri 並且複製到剪貼簿中,立馬享有 ctrl + v 快速產出的快感( Mac only ),產生出來的字串包含了 data:image/png;base64, 所以直接貼入 HTML img 的 src="PASTE_HERE" ,或 CSS background-image 的 url( PASTE_HERE ) 中。

source


相關連結
Caniuse - datauri
Gist - https://gist.github.com/IskenHuang/6434813