前端架構(git、模塊化)

協做流程

1.職責

頁面工程師

圖片描述

前端工程師

圖片描述

接口設計

三種接口

1.頁面入口規範

頁面入口規範

基本信息javascript

輸入參數

模板列表
接口列表前端

2.同步數據規範

圖片描述

基本信息java

預填數據webpack

注入接口git

3.異步接口規範

圖片描述

基本信息github

輸入數據web

輸出結果promise

同步請求,異步請求?

版本管理

版本控制系統VCS (Version control system)瀏覽器

1.分支模型

產品級的分支模型:緩存

圖片描述

2.git

git是一個基於內容尋址的存儲系統。基於文件內容,而不是基於文件。

安裝

Windows: msysgit http://msysgit.github.io

Mac: brew install git

Ubuntu: apt-get install git

git基礎操做

1.git config

用戶配置:

git config --global user.name "Darcy"
git config --global user.name text.example.com

配置級別:

圖片描述

2.git init

初始化以後會出現一個.git/目錄,下面存儲着包括config文件在內的幾乎全部git相關文件。

3.git status

圖片描述

圖片描述

跟蹤:track

4.git add

添加文件內容到暫存區,同時文件被跟蹤

批量添加: git add . 添加當前目錄全部文件

5..gitignore

若是有不但願跟蹤的文件,那麼須要配置忽略文件。

僅做用於未跟蹤的文件。

圖片描述

gitignore常見配置:github中的示例

6.git rm

暫存區刪除文件。

  • git rm --cached 僅僅從暫存區刪除

  • git rm 同時從暫存區和工做目錄刪除

  • git rm $(git ls-files --deleted) 刪除全部被跟蹤,可是在工做目錄被刪除的文件

7.git commit

提交。

  • git commit -m "initial commit"

  • git commit -a -m "initial commit" 直接提交

8.git log

提交歷史記錄。

  • git log

  • git log --oneline 只有7位hash和提交時輸入的commit message

  • git log --color --graph --pretty=format:(此處省略2行) 更美觀,且有分支鏈

上面的命令太長了,不可能每次都這樣輸入,所以須要配置別名alias

  • 語法:git config --global alias.shortname <full command>

  • 例子:git config --global alias.lg "log --color --graph --pretty=format:(此處省略2行)"
    這樣就能夠用 git lg 來表示上面那行命令了。

別名其實也存儲在gitcofig文件中

9.git diff

顯示版本差別。

  • git diff 工做目錄與暫存區的差別

  • git diff -cached[<reference>] 暫存區與某次提交的差別,默認是<HEAD>,<HEAD>指向當前的提交

  • git diff [<reference>] 工做目錄與某次提交的差別

10.git checkout --<file>

撤銷本地修改。

即:將工做內容從暫存區複製到工做目錄。

11.git reset HEAD <file>

取消暫存。

即:將文件內容從上次提交複製到暫存區。

12.git checkout HEAD --<file>

撤銷所有改動:取消暫存 + 撤銷本地修改。

圖片描述

git分支操做

13.git branch

  • git branch <branch-name> 新建分支

  • git branch -d <branch-name> 刪除指定分支

  • git branch -v 顯示全部分支信息

14.git checkout

經過移動HEAD檢出版本,可用於分支切換。

  • git checkout <branch-name> 切換分支

  • git checkout -b <branch-name> 新建一個分支並切換到新分支

  • git checkout -b <reference> 切換到其餘引用對象,好比 commit id 或 標籤

  • git checkout - 回到上一個分支(把HEAD移動到上一個分支)

15.git reset

將當前分支恢復到某個歷史版本。如下三種模式的主要區別是內容是否會恢復到工做目錄和暫存區。

  • git reset --mixed e33e42 --mixed是默認參數,不寫也行,當前內容(即原來的提交)會被複制到暫存區

  • git reset --hard e33e42 --hard 時,當前內容(即原來的提交)會被複制到暫存區和工做目錄

  • git reset --soft e33e42 --soft時,暫存區和工做目錄都不會有任何改變,原來的提交變成了一個無索引的提交,有可能會被回收,能夠用 git reflog 找回來

  • 捷徑:git reset HEAD^/HEAD~1/HEAD~n HEAD的上一次提交,前第n次提交

區分resetcheckout 在操做分支與操做文件時的不一樣

clipboard.png

16.git stash

咱們在git checkout切換分支的時候,常常會被提示「當前有未提交的內容,請commitstash」,而咱們一般是寫到一半不但願commit的,因此這時就須要git stash

做用是:保存目前的工做目錄和暫存區狀態,返回一個乾淨的工做空間。

  • git stash save 'push to stash area' 第一步:保存

  • git stash list 第二步:查看已有列表 會顯示:stash@{0}: On master: push to stash area

  • git stash apply stash@{0} 第三步:把保存的內容恢復到工做目錄

  • git stash drop stash@{0} 第四步:把對應的stash命令刪除掉

  • git stash pop stash@{0} 捷徑:第三步+第四步

17.git merge

假定當前在master分支。

  • git merge next 合併 next 分支的內容到master分支

若有衝突,會是下面這樣:

<<<<<<< HEAD

next 

=======

origin/master

>>>>>>> origin/master

====上面指當前分支的提交,下面是要merge過來的分支的提交內容。

18.git rebase

修剪提交歷史的基線,俗稱「變基」。

  • git rebase master

不要在共有分支使用rebase。

19.git tag

標籤,一個不變的別名。用於標記某次發佈。指向一個commit對象。

  • git tag v0.1 e39d0b2

打完標籤以後,能夠直接使用標籤名切換分支: git checkout v0.1

git遠程操做

20.git push

提交本地歷史到遠程。

21.git remote

  • git remote add origin ~/git-server 添加一個遠程倉庫別名origin

  • git remote -v 查看遠程倉庫信息

22.git fetch

獲取遠程倉庫的提交歷史。

  • git fetch origin/master

  • git merge origin/master

23.git pull

  • git pull <remote> <branch>

  • =git fetch + git merge

23.git clone

獲取一個遠程倉庫做爲本地倉庫。

  • git clone ~/git-server test2 會克隆遠程倉庫到 test2目錄下

技術選型

模塊化(JS)

1、模塊

1.模塊的職責:

  • 封裝實現

  • 暴露接口

  • 聲明依賴

2.第一步:沒有應用任何模塊系統(反模式 Anti-Pattern)

math模塊:

//math.js
function add(a, b) {
  return a + b;
}
function sub(a, b) {
  return a - b;
}

caculator模塊:

//caculator.js
var action = "add";

function compute(a, b){
  switch(action){
    case "add": return add(a, b);
    case "sub": return sub(a, b);
  }
}

能夠看出 caculator模塊是依賴math模塊的。

math模塊特色:

  1. 無封裝性:變量所有散落在全局裏。

  2. 接口結構不明顯:若是咱們沒有簡化代碼,那麼並不能清楚的知道math到底輸出了哪些接口

caculator模塊特色:

  1. 沒有依賴聲明:依賴了math模塊可是卻沒有聲明。

  2. 使用全局狀態:使用了action這個全局狀態,應該儘可能避免。

3.第二步:使用字面量(Object Literal)優化

math模塊:

//math.js
var math = {
  add: function add(a, b) {
    return a + b;
  }
  sub: function sub(a, b) {
    return a - b;
  }
}

caculator模塊:

//caculator.js
var caculator = {
  action: "add",
  compute: function compute(a, b){
    switch(action){
      case "add": return add(a, b);
      case "sub": return sub(a, b);
    }
  }
}

math模塊特色:

  1. 結構性好:用字面量把接口進行告終構化。

  2. 訪問控制差:依然沒有進行控制。

caculator模塊特色:

  1. 依然沒有依賴聲明:依賴了math模塊可是卻沒有聲明。

  2. 沒法設置私有屬性action雖然是成員屬性,但在外部依然能夠訪問到。

4.第三步:使用當即執行的函數表達式IIFE(Immediately-invoked Function Expression)解決沒法設置私有屬性的問題。

caculator模塊:

//caculator.js
var caculator = (function(){
  var action = "add";
  return {
    compute: function compute(a, b){
      switch(action){
        case "add": 
          return math.add(a, b);
        case "sub": 
          return math.sub(a, b);
      }
    }
  }
})();

caculator模塊特色:

  1. 依然依然沒有依賴聲明:依賴了math模塊可是卻沒有聲明。

  2. 有了私有屬性action是咱們要的私有屬性,compute函數能夠訪問到,並且在caculator外面沒法訪問到。

5.第四步:增長依賴聲明

caculator模塊:

//caculator.js
var caculator = (function(m){
  var action = "add";
  function compute(a, b){
    switch(action){
      case "add": 
        return m.add(a, b);
      case "sub": 
        return m.sub(a, b);
    }
  }
  return {
    compute: conpute
  }
})(math);

caculator模塊特色:

  1. 顯示了依賴聲明:把math模塊做爲參數傳了進去,而且能夠對形參進行命名,這裏命名爲m

  2. math模塊仍然污染了全局變量

  3. 必須手動進行依賴管理:math模塊是手動傳進去的,必須手動保證math是在這以前就被加載了。

  4. 注意return的部分與原來不同了:學名叫 揭露模塊模式review module pattern,優勢是在暴露的模塊進行增刪查改的時候會很是方便

6.第五步:使用命名空間(name space)解決污染全局空間的問題

幫助咱們只暴露一個相似於namespace的全局變量。而不是將math這樣的模塊都註冊在全局做用域中。

math模塊:

//math.js
namespace("math", [], function(){
  function add(a, b) {
    return a + b;
  }
  function sub(a, b) {
    return a - b;
  }
  return {
    add: add,
    sub: sub
  }
})
//第一個參數爲模塊聲明,第二個參數爲依賴的模塊,第三個參數爲模塊的構成

caculator模塊:

//caculator.js
namespace("caculator", ["math"], function(m){
  var action = "add";
  function compute(a, b){
    return m[action](a, b);
  }
  return {
    compute: compute
  }
}

依賴是統一註冊在某個地方,而不是全局中的一個變量。

namespace的實現:

圖片描述

cache中緩存了全部的模塊。
實際返回的是createModule這個函數,參數包括:模塊名,依賴的模塊,當前模塊的實現。
若是隻傳入了一個參數,就返回這個模塊cache[name]
取得全部依賴的模塊deps,即保證前面的模塊都已經被定義好了,這樣當前模塊(這裏爲caculator模塊)才能運行。
最後初始化模並返回定義的模塊cache[name]

該方法特色:

  1. 再也不污染全局環境:把模塊都定義在一個namespace變量中。

  2. 沒有依賴管理:依然是咱們手動進行依賴管理。

依賴管理(dependency manage)

若是這些模塊分散在不一樣的文件中,咱們在用的時候就要對引入的腳本順序進行手動排序。
好比 module2.js中依賴了module1.js,那麼寫的時候就要先寫module.js,像這樣:

<body>
  <script src="module1.js"></script>
  <script src="module2.js"></script>
</body>

可是咱們在實際開發過程當中的依賴老是很複雜。那是一條又長又複雜的依賴鏈。非要人肉分析是會抓狂的。而這實際上是模塊系統的工做。

2、模塊系統

1.模塊系統的職責

  • 依賴管理(加載 / 注入 / 分析 / 初始化)

  • 決定模塊寫法

2.CommonJS

//main.js
function add(a, b){
  return a + b;
}
function sub(a, b){
  return a - b;
}
exports.add = add
exports.sub = sub

比原來的寫法多了接口暴露:exports.add = add exports.sub = sub

//caculator.js
var math = require("./math");

function Caculator(container){
  //...
}

exports.Caculator = Caculator

比原來的寫法多了依賴聲明: var math = require("./math"); 和 接口暴露:exports.Caculator = Caculator

優勢:

  • 運行時支持,模塊定義很是簡單:只是利用了幾個全局變量exports, module, require

  • 文件級別的模塊做用域隔離:這幾個全局變量的做用域都是文件級別的,雖然JS沒有文件級別的做用域,但咱們對它進行了封裝,使得使用時一個文件有一個做用域,它們使用起來很是安全。

  • 能夠處理循環依賴。

缺點:

  • 不是標準組織的規範。

  • 同步的require,沒有考慮瀏覽器環境。而咱們的瀏覽器文件加載是一個異步的過程,這是最大的問題,這是否就意味着咱們的瀏覽器沒辦法使用了呢?固然不是。如今有不少工具好比browserify,好比webpack,能夠幫助咱們把多個文件級別的模塊打包成一個文件,這樣咱們引入單個文件就能夠在瀏覽器裏使用了。

由於CommonJS自然的不適合異步環境,因此出現了自然異步的AMD(Asynchronous Module Definition)

3.AMD

與咱們前面的namespace很是像。

//main.js
define([], function(){
  function add(a, b){
    return a + b;
  }
  function sub(a, b){
    return a - b;
  }
  return {
    add: add,
    sub: sub
  }
})

比原來的寫法多了包裹函數:define,第一個參數爲依賴的模塊列表,第二個參數爲當前模塊的實現。

//caculator.js
define(["./math"], function(math){
  function Caculator(container){
    //...
  }
  return {
    Caculator: Caculator
  }
}

同時AMD還支持一個簡單的CommonJS寫法,只不過要用一層函數包裹起來define(function(require, exports){ ... })

優勢:

  • 專爲異步I/O環境打造,適合瀏覽器環境。

  • 支持相似CommonJS的書寫方式。

  • 經過插件支持能夠加載非JS資源。

  • 成熟的打包構建工具,並可結合插件實現一些預處理的工做。

缺點:

  • 模塊定義繁瑣,須要額外的函數嵌套。

  • 只是庫級別的支持,須要引入額外的庫,好比requireJS。

  • 沒法處理循環依賴。

  • 沒法實現條件加載,由於只是庫級別的。

4.原生JS語言級別支持的模塊化標準ES6 Module(Javascript module definition for future)

//main.js
function add(a, b){
  return a + b;
}
function sub(a, b){
  return a - b;
}
export { add, sub }

比原來的寫法多了接口暴露:export {add, sub}

//caculator.js
import { math } from './math';

function Caculator(container){
  //...
}

export { Caculator }

比原來的寫法多了依賴聲明: import { math } from './math'; 和 接口暴露:export { Caculator }

優勢:

  • 真正官方的規範,將來的趨勢。

  • 語言級別的支持。

  • 適應全部的JavaScript運行時環境,包括瀏覽器。

  • 能夠處理循環依賴。

框架(JS框架)

什麼是庫和框架

  • 針對特定問題的解答,就有專業性

  • 不控制應用程序的流程

  • 被動的被調用

好比,一個DatePicker時間選擇器是一個庫,一個Backbone.view是一個框架。

框架

  • 控制反轉 Inverse of control <···主要區別

  • 決定應用程序生命週期

  • 通常會集成大量的庫

下面這個圖很好的解釋了控制反轉

圖片描述
框架決定了何時調用庫,何時要求你的代碼去實現某些功能。

框架和庫,他們都是解決方案。關於解決方案,分爲7各方面:

  • DOM

  • communication 通訊

  • Utility 工具庫

  • Template 模板技術

  • Component 組件

  • Route 路由

  • Architecture MV*架構

1.DOM解決方案

重點:Selector / Manipulation(操做) / Event(dom) / Animation

  1. jQuery

  2. zepto.JS

  3. Mootools

  4. 手勢支持:Hammer.js

  5. 局部滾動:iScroll.js

  6. 高級動畫:Velocity.js

  7. 視頻播放:video.js

2.Communication(通訊)解決方案

重點:XMLHttpRequest / Form / JSONP / Socket

做用:

  • 處理與服務器的請求與響應

  • 預處理請求數據/響應數據 & Error/Success的判斷封裝

  • 多種類型請求,統一接口

  • 處理瀏覽器兼容性

  1. jQuery

  2. zepto.JS

  3. Reqwest

  4. qwest

以上都是異步的請求,但對於實時性要求很是高的產品好比im聊天工具,就須要當即響應。這時須要用websocket。推薦下面的庫:

  1. socket.io

3.Utility(工具包)解決方案

重點:函數加強 & shim / Flow Control

職責:

  • 提供JS原生不提供的功能

  • 方法門面包裝,使其易於使用。即shim(語言墊片),保證明現與規範一致。

  • 異步隊列 / 流程控制 好比promise

3.Template

三種類型:String-based / Dom-based / Living Template

圖片描述

4.Component組件

經常使用組件: Modal / Slider / DatePicker / Tabs / Editor

  1. Bootstrap

  2. Foundation

5.Routing路由

分類:Client Side / Server Side

職責:

  • 監聽url變化,並通知註冊的模塊,進行頁面切換

  • 經過Javascript進行主動跳轉

  • 歷史管理

  • 對目標瀏覽器的兼容性的支持

route庫

圖片描述

6.Architecture架構(目的:解耦)

分類:MVC / MVVM / MV*

職責:

  • 提供一種範式幫助(強制)開發者進行模塊解耦

  • 試圖與模型分離

  • 更容易進行單元測試

  • 更容易實現應用程序的擴展

圖片描述

各類框架比較的參考網站:
http://todomvc.com/
https://www.javascripting.com/
https://www.javascriptoo.com/
http://microjs.com/#

7.Component組件

開發實踐

系統設計

1.系統說明

2.系統分解

3.接口設計

  • 數據類型(每一個頁面的每一個模塊都要單獨定義包含的數據類型列表)

  • 模板資源

  • 異步接口(請求方式,請求地址,輸入參數,輸出結果)

  • 頁面摘要

4.工程構建

  • 項目結構

  • 初始代碼

  • 模擬數據

系統實現

1.組件封裝

  • 通用原件(logo,輸入框,圖標,按鈕,翻頁,複選框列表,loading)

  • 通用列表(歌單。歌手,收藏的節目)

  • 複合組件(好比評論)

  • 浮層彈窗

一個組件(BannerSlifer)的栗子:

圖片描述

2.邏輯實現

測試發佈

1.測試聯調

  1. 本地測試

  2. 異步測試

  3. 對接聯調

2.發佈上線

  1. 打包發佈

  2. 優化配置

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息