Denny Ku
Front-end Developer
1. 喜歡做很有趣的東西
2. 有用 JavaScript 統治世界的野心
對我來說,有趣指的不只是好玩,還包括好維護
和可能性
3. 學東西快、喜歡解決問題
4. 樂於分享
- Codedata: 前端工程師入門心得( PTT_SOFT_JOB )
專注在非英文的媒體上,
因為不只有英美媒體才是我們該知道的國際
Quick Summay
- 我做的第一個網站
- Platform for translaters
Rails
MySQL
JavaScript
EC2
- URL: united-issue.com
Detail
- 串接 Facebook 登入 API ( omniauth 2 )
- 了解 DB 的 Schema 設計(做到3NF)
- 部署到 AWS EC2 (Capistrano)
Result
- Facebook粉絲人數: 8000 +
- 總計參與翻譯譯者數:30 +
- 翻譯語言數:11
- IT 鐵人幫佳作(記錄 30 天的開發過程)
當初瞭解的不夠深入,所以文中寫 Rails 是 MVC ,
事實上 Rails 應該是屬於 Model 2 模式
學校選課系統在選課剩兩天結束前掛了
丟了一個 Excel 檔案讓我們選課
因為實在太難用(甚至看不到課綱)
所以在一個晚上趕完,是一個「靜態」的 Web App
Quick Summay
- 學習 Regular Expression 來做搜尋
- 靜態頁面:資料量少(1500+)、快速上線( github page)
CSS
JavaScript
- URL: link
- Node.js 清理資料 (使用 underscore 幫忙)
因為學校給的 Excel 資料裡有很多 \t 和其他奇怪的亂碼
Detail - 清理資料
- 清理資料,很多欄位跑掉,所以需要處理例外
if (data[i][k].match(/^[A-Za-z].*/) !== null) {
// 有許多欄位出現英文課名跑到中文課名的錯誤,需要做處理
// 但有些是中英文夾雜的課名。
// Ref. Note NA、UNIX 就是例外
if (data[i][k] !== "UNIX系統程式設計" &&
data[i][k] !== "SAS/R商業資料分析" &&
data[i][k].match(/WTO專題研究/) === null) {
if (data[i][k].match(/Python程式/) === null &&
data[i][k].match(/XML技術/ === null &&
data[i][k].match(/Java 程式設計/ === null))) {
data[i][k] = '';
}
}
}
Detail - 搜尋
- 使用 Regular Expression
- 程式碼連結
Detail - Render
- 直接使用 jQuery 操作 DOM
- 程式碼連結
- 使用 underscore 的 sortBy 來省掉自己處理排序問題
- 分頁功能
Result
- 成為學校的備用選課查詢系統
Result
- 與學校洽談後,開放了查詢課表的 API
- 學弟也做出了對應的網站
- 學到如何在有限的技術力和時限內解決問題
Refine - 現在的我會怎麼做
- 使用 webpack 將所有 ASSETS 打包
- 將 render 的邏輯跟其他部分程式碼分開
可以使用 React 及 Redux ,
讓前端的 State 更容易被管理和 Trace,
但不是一定要引入這兩個 packages
- 更模組化的去思考所有的功能
省略不必要的細節,
只需要關注 UI 還有與資料打交道的 Interface
讓合作的設計師也能夠簡單使用
Quick Summay
- Hot Module Reload
- 簡單的製作 demo page ( github page)
webpack
- 可以使用 ES6 語法
Yeoman
Detail - Config
- webpack config 檔案,加入 hmr plugin、babel loader
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'eval',
entry: [
'webpack-hot-middleware/client',
'./src/main'
],
output: {
path: path.join(__dirname, 'dist/'),
filename: "bundle.js",
publicPath: '/static/'
},
module: {
loaders: [{
test: /\.scss$/,
loader: 'style!css!sass'
}, {
test: /\.js$/,
loaders: ['babel'],
include: path.join(__dirname, 'src')
}, {
test: /\.png$/,
loader: "url-loader?limit=100000"
}, {
test: /\.jpg$/,
loader: "file-loader"
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
}
Detail - Import style
- 將 style import 進來當成 js 一部分,就可以支援 hmr
import style from '../static/stylesheets/style.scss';
import React from 'react';
import {render} from 'react-dom';
import Hello from './components/Hello';
render(<Hello />,
document.getElementsByClassName('container')[0]
);
Result
- 一個簡易並且 DRY 的開發環境建置
Refine - 現在的我會怎麼做
- 讓發布自動化,用 npm install 就能引入套件
第一個與其他人共同協作打造的網站
Quick Summay
- 將重複用到的 UI 做成 Component
- Mobile web 的頁面及功能發想 => 實作
- 從 jQuery => React 的轉變
- 負責前端頁面的實作、RWD 的設計
CSS
JavaScript
- CSS 的命名
Detail - jQuery 製作 Component
- 呼叫方法:
// 使用時機:
// 原生的 select tag 不好用 CSS 去操作,
// 當需要對 select tag 做客製化外觀,
// 並且不需要進行太複雜的互動時。
let $custom1 = $("#custom1").customizeSelect();
// or
let $custom2 = customSelect.call($("#custom2"));
// 可以設定預設值
$custom1.set("defaultValue")
- 宣告會用到的樣板,並在 DOM 裡面加入他們
Detail - jQuery 製作 Component
- 解決 jquery val 不會觸發 change 事件的monkey patching、運用 Observable ( rx.js ) 來綁定事件
Detail - jQuery 製作 Component
- Implement 上一步需要的 function
- 只列出最主要的更新 select 和 view 狀態的 function
function updateSelectedOption(value) {
if (value) {
let $selectedTarget = $select.children(`option[value=${value}]`);
$selectedTarget.siblings().attr("selected", false);
$selectedTarget.attr("selected", true);
let text = $select.children("option[selected=selected]").text();
$input.html(text + postLabel);
} else {
$select.children("option").attr("selected", false);
$input.html(defaultText + postLabel);
}
}
Detail - jQuery 製作 Component
- 優點:
呼叫容易
- 缺點:
無法處理有太多 state 的 UI
程式碼容易變得無法維護
不好測試
Detail - jQuery 製作 Component
Detail - React + Redux
- 規劃複雜 UI 的 State Tree
- 實作單向資料流的 Web App
- 應用在需要較多互動的頁面上
Quick Summay
- CSS Modules
- 了解一個製作靜態頁面產生器所需要的前端技術
- 更深入了解 webpack 的運作
- 頁面設計、手機頁面設計
CSS
JavaScript
- URL:abalone0204.github.io
- Repo
Detail - 使用 React Router + Redux
- 讓每一次走過的 Route 都能被存在 store 中紀錄
render((
<Provider store={store}>
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path="about" component={About} />
<Route path="posts/:title" component={Post} />
</Route>
</Router>
</Provider>
),
document.getElementsByClassName('container')[0]
);
Detail - React + CSS Modules
- 將 Style 直接包在 Component 中
src/components
├── About
│ └── SkillsList.js
├── ContentBlock
│ ├── index.js
│ └── index.scss
├── LoadingAnimation
│ ├── index.js
│ └── index.scss
├── Nav
│ ├── index.js
│ └── index.scss
├── PostItem
│ ├── index.js
│ └── index.scss
├── PostList
│ ├── index.js
│ └── index.scss
├── SkillsList
│ └── index.js
└── container
├── index.css
└── index.js
Detail - 標頭檔的設計和讀取
{{{
"title": "CSS Modules: 模組化 CSS",
"intro": "「如果你覺得 CSS 寫起來很亂的話,那代表你心中沒有架構。」",
"date":"2016/1/9",
"tags": ["CSS Modules", "PostCSS"]
}}}
(文章內容)...
- 標頭檔的樣子(一個 JavaScript 的 Object)
Detail - 標頭檔的設計和讀取
function getPostsTree(posts) {
var result = posts.map(
fileName => {
var t = fs.readFileSync(fileName).toString();
var parsedString = t.replace(/\n/g, '');
var matcher = parsedString.match(/^\{{3}([^\{|^\}]+)\}{3}/)[1]
var object = JSON.parse(`{${matcher}}`);
Object.assign(object, {
fileName: path.basename(fileName)
})
return object
})
result.sort((a, b) => {
var keyA = new Date(a.date);
var keyB = new Date(b.date);
if (keyA < keyB) return 1;
if (keyA > keyB) return -1;
return 0;
})
return result;
}
- 先拿到所有文章的名稱後,讀取每個 md 檔案的標頭檔,並依時間先後排序
Detail - 標頭檔的設計和讀取
export const postsTree = [
{
"title": "我的前端工程師之路",
"date": "2016/1/15",
"intro": "「這個畫面幫我稍微調一下應該沒有很難吧?」",
"tags": [
"career",
"front-end"
],
"fileName": "way-to-fed.md"
},
{
"title": "CSS Modules: 模組化 CSS",
"intro": "「如果你覺得 CSS 寫起來很亂的話,那代表你心中沒有架構。」",
"date": "2016/1/9",
"tags": [
"CSS Modules",
"PostCSS"
],
"fileName": "css-modules.md"
},
{
"title": "自動化發布",
"date": "2016/1/6",
"tags": [
"auto-realease",
"JavaScript",
"CI"
],
"fileName": "auto-release.md"
},
{
"title": "Change Logs",
"date": "2016/1/1",
"intro": "紀錄一下這個小網站",
"tags": [
"JavaScript"
],
"fileName": "change-logs.md"
}
]
- 讀取後的成果
Result
- 有一個網頁可以實驗新的前端工具
- 可以不用再登入後台才能寫部落格了
Quick Summay
- 了解被抽象化前的複雜
- 用 Node.js 實作了一個組譯器
- 初探 CPU 和記憶體的運作
JavaScript
- URL:hack_assembler
- 非本科系、「前端」不是藉口,基礎學問要再更扎實
Result
- 等待 Coursera 後續課程出來
- 對畫面底下的東西產生更多興趣
- React Native : 寫跨平台的 JavaScript
- Node.js :
用更謙卑的態度去學習後端的處理,
雖然都是 JavaScript,對後端的專業是需要重新學習的
- Others:
Haskell => 深入 functional 的思維方式
Golang => Interface、併發的思維對寫後端有幫助
Rx.js => 研究 Scheduler 如何處理併發