前端項目從0到1的感悟

去年6月份左右,加入了一個創業公司,很幸運作了一個從零開始的項目,前端工程由我一手搭建起來,並不斷迭代功能到如今,有許多的感悟心得,在這裏寫點總結javascript

肯定框架、技術點

一個項目的開始,特別是豐富多樣的前端工程,首先必定要肯定好採用的框架和技術點。2016年vue.js如火如荼,webpack強勢崛起,可是是否就可直接拿到項目中搞起呢?答案是否認的,一個新的技術若是本身或團隊中成員都還在學習摸索的過程,是確定不能在生產環境中使用的,更況且這是個創業的團隊,沒有成熟完整的前端團隊。因此我當時仍是走老套路,jquery爲核心,fastclick輔助,requireJs按需加載,arttemplate作模板渲染,核心UI類庫使用jqueryWeUI,加上sass預編譯樣式文件,gulp打包構建,(後臺是微服務架構,maven構建,springMVC+mybatis,此工程爲h5前置工程)這樣一來就基本上知足條件,能夠開工了。css

開發工具

不一樣的開發工具可能在展現格式上有必定的差異,因此一個團隊最好仍是能統一的開發工具。後臺通常使用eclipse,前端我推薦使用sublime,以及相關的插件:
html

開發規範,命名規則

既然是多我的同時開發,確定會有一些代碼風格上的異同,然而爲了方便後期維護,必需制定一些相關的規範。如:前端

  • 開發規範
    1. 全部頁面編碼必須是
    2. 儘可能使用語義話標籤,如頭部使用header,內容使用articl,頁腳使用footer,模塊使用section標籤
    3. 全部頁面採用下面的通用模板
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
    
        <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
        <meta http-equiv="Pragma" content="no-cache" />
        <meta http-equiv="Expires" content="0" />
        <meta name="format-detection" content="telephone=no" >
    
        <title>通用模板頁面</title>
        <link rel="stylesheet" type="text/css" href="/static/li/li-1.2.0.css">
    </head>
    <body>
        <header></header>
        <article></article>
        <footer></footer>
    </body>
    <script type="text/html" id="registerMainTpl">
    
    </script>
    <script src="../static/component/requirejs/require.min.js"></script>
    <script type="text/javascript">
    var script = document.createElement("script"),
        head = document.head || document.getElementsByTagName('head')[0];
    
    script.type = "text/javascript";
    script.src = '/config.js?ver=' + (new Date()).getTime();
    
    head.appendChild(script); 
    
    script.onload = script.onreadystatechange = function(){
    require(
        [
            'jquery',
            'fastclick',
            'artTemplate',
            'li',//本身封裝的js類庫,包括head裏面引用的li-1.2.0.css
            'common',//公共js,存放一些公用的方法
        ], 
        function($,FastClick,template){
            FastClick.attach(document.body);
    
            var $body = $('body'),
                $header = $('header'),
                $article = $('article');
            var registMain = {
                h5: function(){
                    this.renderHtml();
                    this.renderComponent();
                    this.watch(); 
                },
                //全局屬性
                options: {
    
                },
    
                //渲染模板的數據
                data: {
    
                },
    
                //渲染html
                renderHtml: function(){
    
                },
                //渲染組件
                renderComponent: function(){
    
                },
    
                //事件監聽
                watch: function(){
                    var self = this;
    
                }
            }
    
            dn.init(function(){
                registMain.h5();
            })
        })
    }
    </script>
    </html>
  • 命名
    1. id採用駝峯命名法則,如 formName
    2. class中間用-隔開,如 li-col-50
    3. 圖片命名也用-隔開,如 zhongan-bananer
    4. 模板以Tpl結尾,如 registerMainTpl
    5. 函數也用駝峯命名,使用 get/set/put/delete等前綴
    6. 文件名也用駝峯,使用跟文件內容相同的英文單詞或詞組
    7. jquery選擇器能用id就不用class

目錄結構

一個項目的目錄結構就像人的骨架同樣重要,對於日漸迭代版本愈來愈多的前端項目,若是沒有一個好的目錄結構會顯得很是臃腫,難以維護,如下這個截圖是我如今正使用的目錄,也還有須要改進的地方,作一個參考:vue

定義readme.md

將規範規則,文檔目錄、wiki連接等說明放在readme必讀文檔裏java

定義config.js

若是你是使用requirejs的項目,確定有個config.js文件,這個文件每一個頁面都會引用,而且是在頁面加載js的開始同步引用。官方說法是這個頁面放js文件的key-value形式配置呢,而我習慣再js配置以前再定一個window對象的項目惟一子對象,再將項目一些經常使用的常量也定義好,以及請求狀態碼、url彙總,這樣極有利於後續維護,如:jquery

//項目的全局惟一對象
window.li = {
    version: 20170301,//當前版本號,打包時用gulp自動變動
    errorTips: '哎喲,網絡好像有點問題了..',//無網絡提示
    timeout: 1000*60*60*24*20,//登陸失效暫時爲20天
    _MOBILE: 'http://h5.liliangel.cn/base/mobile',//跳轉手機頁面
    _ROOT: 'http://www.liliangel.cn',//測試域名地址
    _XHR: '/rest/',//ajax請求前綴
    _CORS: '/cors/',//跨域請求前綴
    _STATIC: 'http://static.liliangel.cn',//靜態資源域名
    _WX: 'http://h5.liliangel.cn/'//微信h5服務器地址
}

//全部請求狀態碼
li.code = {
    SUCCESS: 600, //成功
    PHONE_EXIST: 603 //手機號碼已經存在
}

//全部請求url
li.api = {
    sendMessage: 'wechat/sendMessage' //發送消息url
}

//靜態資源配置
require.config({
    urlArgs: "v=" +  li.version,
    baseUrl : "/",
    paths: {
        jquery:'plugin/jquery/jquery-1.9.0.min',
        artTemplate: 'plugin/template/artTemplate-3.0',
        
    },
    shim: {
        bootstrap: {
            deps: ['jquery'],
            exports: '$'
        }
    },
    waitSeconds: 15
});

定義common.js

用來放置全部公共方法,一樣也是每一個頁面都引用,正如上面定義好的一些常量同樣,一個項目的開始,還須要一些方法上的準備工做,如:webpack

  1. 全部js方法li.init()主入口,至關於jquery的ready()方法,這樣一來就能夠控制全部js加載前作的事情了,如前置判斷在微信瀏覽器執行fun1,在原生app中執行fun2,這也是混合式開發中常見的需求。程序員

  2. ajax的li.GET()、li.POST()方法,若是你以爲ajax的封裝可能不能知足的特定需求,好比通用的加載中、好比通用的異常、通用的請求超時時間和回調、通用的請求完成回調、是否須要驗證token等等,總之你能夠根據本身風格重寫一下ajax未必不可...web

  3. 通用的獲取token方法li.getToken(),不少時候請求須要驗證token,前端須要把這個證書獲取到傳給後臺,那麼這個獲取證書的邏輯後續可能會存在一些變更,如加密算法修改、原生端經過交互方法調用app內的而後微信端從緩存或session中獲取等等,因此獲取token方法也必須封裝好

  4. 通用的登陸過時提示、回調。當調用後臺接口返回登陸過時或者非法請求後,須要作些通用的處理,如去登陸頁、三秒提示後去登陸頁、去錯誤頁等,總之存在需求變故的可能的地方,能封裝的方法儘可能封裝,省得到時候需求一變化所有都得去改

  5. 通用的去登陸、註冊頁方法。一般一個項目中,去登陸頁面的會有不少地方調用,同時可能在方法裏判斷一下手機號是否已經註冊、沒有註冊就去註冊頁面這樣的簡單邏輯,提升用戶體驗..

  6. 跳轉頁面方法,可能你會以爲用window.location.href足夠了,可是實際的開發中,緩存的現象真的很頭疼,儘管你各類設置各類加版本號了,可是你一般會忽略在加載頁面的時候在url後面也添加一個版本號

  7. 後退
    一般狀況下,你可能會以爲window.history.go(-1)就能夠了,可是若是你的頁面同時也要用在混合app裏時,就須要考慮一些和原生端交互的問題,跳轉頁面也是同樣,一般狀況下須要保留當前webview從新打開一個webview,因此儘可能將後退和跳轉頁面封裝一個通用的方法,方便後期添加修改。

  8. 判斷當前瀏覽器廠家
    h5最多的可能就是判斷是不是微信瀏覽器了

    var ua = navigator.userAgent.toLowerCase(),
        isWechat = ua.indexOf('micromessenger') != -1;
    if(isWechat){
        ...
    }
  9. 獲取url參數
    獲取當前頁面url地址中的參數是很經常使用的方法,一般我也會將其封裝在common裏面,如:

    getUrlPar: function(name){
        var _reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"),
            _regNext = window.location.search.substr(1).match(_reg);
        if (_regNext != null) return decodeURI(_regNext[2]) || '';
        else return '';
    },
  10. ajax 全局錯誤監聽

一般狀況下,後臺會在web.xml會配置一個error-page指向一個錯誤頁面,可是那樣都是跳轉頁面404錯誤還好,其餘錯誤也跳頁面其實並不友好,而其餘的錯誤一般是請求中錯誤,咱們只要設置一個ajax全局監聽便可,下面是代碼片斷,固然還能夠作不少你暫時沒有想到的事情

$(document).on('ajaxError', function(e, xhr, options){
    if (404 == xhr.status) {
        common.404()
    }else if(500 == xhr.status){
        common.500()
    }
})

定義common.css

全部公共樣式,一樣的每一個頁面都要引用,其中在整個項目樣式通用控制起決定性做用,如:

  1. 全局字體樣式

    * {
      font-family: 'Microsoft YaHei'; 
    }
  2. 標籤樣式

    body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button, input, textarea, th, td {
      margin: 0;
      padding: 0; }
    
    /** 標籤樣式 start */
    html {
      font-size: 20px; }
    
    body {
      font-size: 16px;
      background-color: #e5e6e7; }
    
    h1 {
      font-size: 2.25rem; }
    
    h2 {
      font-size: 1.975rem; }
    
    h3 {
      font-size: 1.50rem; }
    
    h4 {
      font-size: 1.125rem; }
    
    h5 {
      font-size: 0.875rem; }
    
    h6 {
      font-size: 0.750rem; }
    
    a {
      text-decoration: none;
      -webkit-tap-highlight-color: transparent; }
    
    em {
      font-style: normal; }
    
    label > * {
      pointer-events: none; }
    
    ul {
      list-style: none; }
    
    button {
      -webkit-appearance: none;
      border: 0;
      background: 0 0; }
  3. 媒體查詢控制字體大小
    ```
    /** 媒體查詢 start */
    @media only screen and (min-width: 400px) {
    html {
    font-size: 21.33333333px !important; } }

    @media only screen and (min-width: 414px) {
    html {
    font-size: 22.08px !important; } }

    @media only screen and (min-width: 480px) {
    html {
    font-size: 25.6px !important; } }

    ```
    這是全部頁面的基礎樣式控制,主要是在字體方面,用rem來解決移動開發中多屏適配,若是有UI框架引入的時候就要根據實際狀況考慮是覆蓋基礎樣式仍是被覆蓋來決定引入的前後順序了

打包(gulp)

  1. 壓縮css、圖片,壓縮、加密js
  2. 去掉console.log()等調試信息
  3. 給css自動添加兼容性前綴
  4. 給js、css、img、font、json等靜態資源引用處添加版本號(當前時間戳)

    E:
    cd \h5\weixin\target
    gulp build
    cd \h5\weixin\target\weixin\
    del \h5\weixin\target\weixin\weixin.war
    cd \h5\weixin\target\weixin\
    jar cvf weixin.war ./
    del \last\code\2017\dnzd\weixin.war
    move weixin.war \last\code\2017\dnzd\

    實際開發中可能有實時刷新和實時編譯sass這些任務。上面是生產構建的腳本,build這個任務裏面包含了上面4點,固然還能夠添加requireJs優化等等這些...

意識和協做

團隊協做開發中,成員寫代碼的意識很重要,一個再完善的開發規範不若有個良好的代碼意識的程序員,一個技術再好團隊不如一個團隊意識強的的團隊,固然,改變一我的的開發習慣是比較痛苦的,可是若是你發現這是一個好的規範,那麼你須要刮骨療傷去成長,若是你不能忍受一些條條框框,那麼團隊也須要更好的程序員。在項目開發協做中,特別是團隊組建初期,特別是先後臺交互、UI跟前端對接、產品經理跟開發溝通中,可能會存在很大的意見分歧,可可能有人會說你代碼哪里哪里很差、沒有註釋、不可維護.. 求同存異,儘量的少去指責他人,由於你看上去亂遭遭的代碼,永遠相信也是寫的人當時深思熟慮後的做品。同時面對別人的說法,你須要更成熟的選擇一笑而過,你也應該去採納別人的建議,沉默中把本身的弱項提升,那就是成長。

多說幾句

作前端的這幾年,我從一個css、js都不懂的小白也算是歷練成了一個老司機,其中的辛酸苦辣只有本身明白。學習的過程的確是痛苦的,但卻也是有樂趣在其中的,深有體會,一件事情堅持一直作下去,總會有許多的收穫,時間長了,慢慢的你會發現,在不少人心中你已經很厲害了。就像寫博客的這一年多,除了我本身收穫許多積累許多以外,我還意外收穫了35個粉絲!最後想說的是,前端是豐富多彩的,你能夠融入其中,但不能只停留在這一塊領域,你想要更好的發展,你必須多元化發展,好比作一個會JAVA後臺的前端,作一個偏UI的前端,作一個很懂技術的產品經理,這些都將是你的優點,不少企業其實並不須要你會很高深的技術,不少項目其實也用不上多少高深的技術,不少時候,你能實現需求,能作出用戶體驗好的產品,能再特殊的階段兼任某個崗位,能作一些別人作不了的事情,你的存在就更有價值!總之在技術上要抓住一個重點,也要發散本身的技術點,走更寬的路,同時技術人也要注重情商的提升..

共勉

程序員最重要的是完美實現需求,技術有時候只是工具。

相關文章
相關標籤/搜索