IOSC 第一週讀書會

LHUIOSC / @jhen

LHUIOSC

facebook group: http://facebook.com/groups/lhuiosc

Information

Open Source

Community

資訊開源社

目的

  • 在校園深耕開源的概念
  • 建立一個好的資訊技術交流環境
  • 期望能以資訊技術改善學校環境

讀書會?

  • 其實就是社課
  • 每週三 6:00 ~ 9:00 PM
  • 讀書會形式
    • 30min: 回顧上週
    • 30min ~ 1hours: 社員分享最近學習現況、技術分享
    • 90min ~ 2hours: 教學

About me

今天?

  • 花點時間來介紹 Hackpad, Slack

  • 主要來教 JavaScript

  • 最後有時間來教如何使用 git & Github

Hackpad

http://hackpad.com

LHUIOSC workspace: http://lhuiosc.hackpad.com

JavaScript

about JS

  • 1995 年由 Netscape 工程師 Brendan Eich
  • 原本叫 LiveScript
  • 直譯式語言

不限於瀏覽器

  • 你眼中的 JS 「很有可能」只是在 browser 上面跑的 JS
  • JS 的宿主是一個解譯器
    • Google 做的 v8
    • WebKit 的 JavaScriptCore
    • Gecko 的 SpiderMonkey
    • ...
    • 它們也被使用在很多其他平台上,做各種事情

Server side?

CLI tool?

Other program?

有一個好選擇叫 Node.js

現在建議你來用 io.js

Desktop Application

 

  • nw.js (node-webkit)
  • atom-shell
  • XULRunner
  • ...

Mobile App

 

  • Cordova (PhoneGap)
  • Titanium
  • NativeScript
  • React Native (coming)
  • ...

基礎教學

MDN

Node.js

Install

  • Linux & OS X 的好選擇: nvm
    • 直接照 readme 安裝即可
    • OS X 也可以 brew install nvm
  • nvm 安裝 node.js & io.js
    • nvm install v0.12.0
    • nvm install iojs-v1.6.2
  • nvm 好處是可以自由切換版本
  • nvm for windows

CommonJS - 模組化

  • JS 本身沒有模組化的機制
    • 像是 java 的 package, import
  • CommonJS 是一套標準,來解決模組化的問題
  • Node.js 實作了一部分的 CommonJS 標準
    • 使用 module.exports 成為模組
    • 使用 require() 載入模組

NPM

  • package manager for javascript
  • npmjs.org
  • 目前有 13 萬個 module 在上面
  • 之於如此的概念
    • python 有 pip
    • ruby 有 gem

Node.js example

Hello World

var http = require('http');

http.createServer(function (req, res) {

  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

Hello World

直接來寫個基本的網頁

var http = require('http');

http.createServer(function (req, res) {

  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end('<!doctype html>' + 
        '<html>' + 
        '<head><title>Hello World</title></head>' + 
        '<body>' + 
        '<h1>Hello World</h1>' + 
        '<p>This is a Node.js example.</p>' + 
        '</body>' +
        '</html>');
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

Hello World

印出 url, method, useragent 資訊

var http = require('http');

http.createServer(function (req, res) {

  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end('<!doctype html>' + 
        '<html>' + 
        '<head><title>Hello World</title></head>' + 
        '<body>' + 
        '<h1>Hello World</h1>' + 
        '<p>This is a Node.js example.</p>' + 
        '<p>request url: ' + req.url + '</p>' +
        '<p>http method: ' + req.method + '</p>' +
        '<p>useragent: ' + req.headers['user-agent'] + '</p>' +
        '</body>' +
        '</html>');
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');
  • url
    • http://localhost/index.html
  • method
    • HTTP 定義的請求方法
    • GET, POST, PUT, DELETE, HEAD, ...
  • user-agent
    • 代表著一個軟體(browser)的識別字串
    • chrome
      • chrome://version

接下來要做的事

  • 解析 user-agent, 判斷請求是否為 mobile 發送
  • 根據 method 做不同的事情
  • 解析 url path, 根據 path 讀取不同 html 檔案
    • require('url'), require('fs')
    • 使用 url.parse 解析 url
    • 使用 fs 讀取
    • 先不考慮 '..' 的安全問題

mobile user-agnet

var isMobile = {
  Android: function() {
    return /Android/i.test(req.headers['user-agent']);
  },
  BlackBerry: function() {
    return /BlackBerry/i.test(req.headers['user-agent']);
  },
  iOS: function() {
    return /iPhone|iPad|iPod/i.test(req.headers['user-agent']);
  },
  Windows: function() {
    return /IEMobile/i.test(req.headers['user-agent']);
  },
  any: function() {
    return (isMobile.Android() || isMobile.BlackBerry()
        || isMobile.iOS() || isMobile.Windows());
  }
};
var message = isMobile.any() ? 'is mobile' : 'not mobile';

Method

var http = require('http');
var qs = require('querystring');

http.createServer(function (req, res) {
  var method = req.method;
  var content = '';

  res.writeHead(200, {'Content-Type': 'text/html'});
  if (method === 'GET') {
    content = '<form action="/" method="POST">' + 
            '<input type="text" name="msg" />' +
            '<button type="submit">Submit</button>' + 
            '</form>';
    res.end(content);
  }
  else if (method === 'POST') {
    var formData = '';
    req.on('data', function(data) {
      formData += data;
    });
    req.on('end', function() {
      var querys = qs.parse(formData);
      res.end('input ' + querys.msg);
    });
  }
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

read file

var fs = require('fs');

fs.readFile('read-file.js', 'utf8', function(err, data) {
  if (err) {
    return console.log(err);
  }
  console.log(data);
});

http server + read file

var http = require('http');
var fs = require('fs');
var url = require('url');

http.createServer(function (req, res) {
  var pathname = url.parse(req.url).pathname;
  if (pathname === '/') {
    pathname = '/index.html';
  }
  pathname = pathname.replace('/', '');

  fs.readFile(pathname, 'utf8', function(err, data) {
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'});
      res.end('Not Found\n');
      return;
    }
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(data);
  });
}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

小結

  • 以幾個簡單的例子來看 web server
  • 當然有很多 framework 做掉這些事了
    • express
    • koa
    • sails
    • ...

Express

  • Middleware
  • Template engine
    • EJS
    • Jade
  • RESTful API
  • 下週教學

git & Github

多人協作遇到的問題

 

  • 出 bug,是誰讓它發生的?到底改了什麼?
  • 出 bug,想比對以前的 code,但是找不回來了
  • 開發時的 code 不同步,最後需要手動整合

 

我想同儕很多早期都會遇到這種問題

然後浪費很多時間在上面

git

 

  • 分散式版本控制系統
  • Linus Torvalds 為了更好管理 Linux kernel 而開發
  • 保存修改檔案的狀態為歷史記錄,方便追蹤
  • 配合 Github 這類的程式碼託管服務,與夥伴們用一個好的方式協作專案

Install

  • Linux
    • yum install git-core
    • apt-get install git
  • OS X (install XCode)
  • Windows

設定 & 初始化專案

$ git config --global user.name "Jhen"
$ git config --global user.email jhen@jhen.me

config (只需設定一次)

init project

$ git init project_name
// or
$ cd project_name && git init 

追蹤 & 提交檔案

 

  • 追蹤檔案
    • git add <filename>  (追蹤某個檔案
    • git add .  (追蹤所有檔案
  • 取消追蹤
    • git rm <filename>  (同時刪除檔案
    • git rm <filename> --cached  (不刪除檔案
  • 提交
    • git commit
    • git commit -m 'your message'

檢查狀態

 

  • 檢查目前狀態
    • git status
    • 三種檔案狀態
      • Changes to be committed
      • Changes not staged for commit
      • Untracked files
  • 檢查 commit 歷史記錄
    • git log

回溯版本 - checkout

  • git checkout
    • git checkout <commit id>
      回到某個 commit id 狀態,branch 會指向該 commit id
    • git checkout <commit id> -- <filename>
      還原特定的檔案到某個 commit id 狀態
    • git checkout -- <filename>
      還原特定回到最新 commit id 的狀態

回溯版本 - reset

  • git reset
    • git reset HEAD^
      回到上一個 commit 狀態,加上 --hard 會放棄原本修改
    • git reset
      放棄 add, 會保留修改

推上遠端 / 從遠端拉下

  • git remote add <name> <url>
  • git push origin master -u
    • 推上更新
    • 之後就用 git push 就好
  • git pull
    • 拉下更新,以同步程式碼
  • 以 Github 帳號開 repository, 作為 remote 的點
    • https
    • ssh

Github - Fork

複製一份 repo 到你的帳號

然後你的新 repo 會顯示 forked from xxx

Github - Pull Request

要求上游合併你新增出來的 commit

Fork & Pull Request

LHUIOSC 社網來示範好了

clone 專案到 local

git clone <url>

Thanks

Copy of IOSC 第一週讀書會

By 李大祥

Copy of IOSC 第一週讀書會

LHUIOSC 第一週讀書會,主題主要是 JavaScript with Node.js, 以及 git 與 Github 的應用教學

  • 791