JavaScript開發者的工具箱 非常實用

InfoQ - 邵思華發表於2015-05-16

自從HTML5變得流行以來,整個Web平臺取得了長足的進步,人們也開始將JavaScript視為一門能夠建立複雜應用的語言。許多新的API紛紛浮現,而關於瀏覽器如何應用這些技術的文章也大量湧現。

作為一門指令碼語言,JavaScript最初建立的目的是用於增強web頁面的表現能力,而現如今JavaScript幾乎已經用在所有你能想到的地方了。隨著整個業界的技術能力不斷提高,JavaScript如今已經可以在服務端執行,同時也能夠被編譯為原生手機應用的程式碼。當今的JavaScript開發者都是整個豐富生態圈中的一份子,他們可以在幾百種IDE、工具和框架中進行隨意選擇。由於各種選擇和資源的數量實在太多,某些開發者也會感到不知從哪裡開始學習。我很樂於討論並概述一下現代JavaScript開發者所面臨的處境,首先我將簡要的介紹一下JavaScript的歷史,隨後會涵蓋目前最流行的一些框架、工具和IDE。

快速回顧歷史

讓我們開始一次快速的旅行。時間回到1995年,當時Netscape Navigator和Internet Explorer 1.0是瀏覽器方面僅有的選擇。網站上充斥著各種煩人的閃爍文字以及太多的GIF圖片。要通過撥號網路載入一個包含了大量豐富內容的頁面,最多需要等待整整兩分鐘時間。隨後出現了一種web語言,它允許這些古老的網站執行客戶端的程式碼。這一年正是JavaScript所誕生的年份。

建立於20年之前的這些網站對於JavaScript的使用並不多,當然也沒有充分發掘這門語言的潛力。偶爾會通過彈出對話方塊告訴你某些資訊,或是在某個方框中通過滾動文字的方式顯示新聞,或是用cookie儲存你的使用者名稱,以便當你經過幾個月後再來訪問這個網站時能夠直接顯示出你的名字。職場中當然也不存在任何以JavaScript作為主要開發語言的工作職位,當時能夠在工作中真正編寫一些JavaScript以及是非常幸運了。總之,當時的網站對於JavaScript的應用就是在DOM中玩一些小花招。

如今,你基本上已經可以在所有地方看到JavaScript的身影了。從Bootstrap到ReactJS、Angular、通用的jQuery,甚至是執行在服務端的Node.js,JavaScript已經成為了最重要、最流行的web語言之一。

框架

自從問世以來,JavaScript的改動的最大方面之一就是對於它的應用方式。呼叫那些尷尬的document.GetElementById方法和建立繁重的XmlHttpRequest物件的日子已經一去不復返了。取而代之的方式,是通過各種幫助性的類庫對這些基本功能進行抽象,讓JavaScript更易於為開發者使用。這也正是如今JavaScript隨處可見的主要原因之一。

jQuery

jQuery是由John Resig在2006年推出的,它提供了一套豐富的工具集,對各種隱晦的、神祕的JavaScript命令與方法進行了抽象與簡化。展示這一工具最簡單的方式莫過於程式碼示例了。

使用純粹的JavaScript建立一個AJAX請求:

function loadXMLDoc() {
    var xmlhttp;

    if (window.XMLHttpRequest) {
        // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else {
        // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 ) {
           if(xmlhttp.status == 200){
               alert("success");
           }
           else if(xmlhttp.status == 400) {
              alert("error 400")
           }
           else {
               alert("something broke")
           }
        }
    }

    xmlhttp.open("GET", "test.html", true);
    xmlhttp.send();
}

來源: Stack Overflow

而使用jQuery建立AJAX請求:

$.ajax({
    url: "test.html",
    statusCode: {
    	200: function() {
    		alert("success");
    	},
    	400: function() {
    		alert("error 400");
    	}
    },
    error: function() {
    	alert("something broke");
    }
});

jQuery使得複雜的JavaScript函式變得方便使用,DOM操作更是小菜一碟。從結果上說,jQuery成為了最早的一批被廣泛使用的JavaScript框架,其中對JavaScript進行抽象的思想則成為了其它各種框架構建的基礎。

AngularJS

AngularJS通常也被稱為“Augular”,於2009年登臺亮相。它是由Google建立的一種框架,目標是為了簡化單一頁面應用(SPA)的建立。類似於jQuery,它的目標同樣是將複雜的操作抽象成為具有高度重用性的方法。它為JavaScript提供了一種模型-檢視-控制器(MVC)的架構。

ReactJS

ReactJS通常也被稱為“React”,是一個剛剛在這場遊戲中登場的新手。它由Facebook建立,並在2013年首次釋出。Facebook認為React在處理SPA問題上可以成為Angular的替代品,因此如果你認為Angular和React這兩種框架是競爭對手,那你的理解就對了。不過,與Angular相比,React最大的不同之處在於,它是一個更高效、具有更高效能、速度更快的類庫。下圖展示了使用React、Angular、Knockout(另一種類庫,在本文中不做討論),以及純粹的JavaScript在DOM中渲染包含1000個內容的列表,各自所需的時間:

來源: The Dapper Developer

如果你的應用非常看重效能,那麼React就是正確的選擇。

JavaScript開發環境

對於高效的開發來說,IDE的使用是非常重要的。IDE的全名是整合開發環境,是一種為開發者提供了一系列工具的應用程式。這種工具中最重要的一部分通常來說是一個富文字編輯器,通常會為使用者提供語法高亮、自動完成和鍵盤快捷鍵,以加速各種煩人的手動操作。

Sublime Text

Sublime Text實際上並不是一種IDE,而是一個輕量級的、速度飛快的用於程式設計的文字編輯器,提供了語法高亮功能和直觀的鍵盤快捷鍵。它本身是跨平臺的,因此對於那些想在PC環境中使用Mac(或者反之)的開發者來說是理想的選擇。Sublime Text的每個部分幾乎都是可以進行自定義的,它還提供了多種外掛,為它加入了類似於IDE的功能,例如和Git的整合,以及程式碼整理。對於JavaScript的愛好者和新手開發者來說,它是一個很好的選擇。當本文釋出時,每個Sublime Text授權的價格為70美金。

來源: Sublime Text

WebStorm

WebStorm是由JetBrains團隊開發的一種智慧IDE,主要專注於HTML、CSS和JavaScript的開發。它只收取象徵性的授權費用(在本文釋出時為49美金),在有經驗的JavaScript專家之間,它得到了廣泛的認可,並已經被視為事實上的標準,這一點不無道理,因為它內建的程式碼完成功能和審查工具可以說是獨一無二的。WebStorm中也提供了一個豐富的JavaScript除錯器,並且與各種流行的單元測試框架進行了整合,例如Karma測試執行器和JSDriver,甚至還包括支援Node.js的Mocha。

WebStorm最優秀的特性之一莫過於它的實時編輯(Live Edit)功能了。只要在Chrome和WebStorm中同時安裝某個外掛,開發者就可以在變更程式碼的同時,直接在瀏覽器中看到結果。開發者還可以對實時編輯進行配置,讓瀏覽器視窗中的變更高亮顯示,這極大地提升了除錯與編碼的生產力。

總的來說,如果JavaScript是你的全職工作,那麼WebStorm這個IDE可以成為一個很好的選擇。

來源: JetBrains

Brackets

Brackets是一種開源的免費IDE,專注於視覺化工具。Brackets提供了一種類似於WebStorm的實時編輯特性,讓你可以在瀏覽器視窗中直接看到程式碼改變的結果。它還支援並行式的編輯,讓你一邊進行編碼工作,同時直接看到程式碼的結果,而無需在不同的應用程式間進行切換,或是使用彈出視窗。Brackets中最有趣的一個特性叫做抽取(Extract),它能夠對Photoshop的PSD檔案進行分析,以獲取其中的字型、顏色和大小等資訊。由於這一特性的存在,Brackets非常適合於那些同時進行設計工作的JavaScript開發者。

(單擊圖片以放大)

來源: Brackets

Atom

Atom是由GitHub推出的一款開源的免費富文字編輯器,非常易於上手使用,在安裝後可以直接執行,而無需進行任何配置檔案的改動,就能夠“良好地執行了”。Atom最有趣的一點是可以對它的每一方面都進行自定義(GitHub將其稱為“可以隨便折騰”),它是在一個web核心的基礎上所建立的,因此使用者就可以通過編寫標準的HTML、CSS和JavaScript,對它的外觀進行自定義。想要為Atom換個不同的背景和文字字型?改一下CSS就行。或者你也可以選擇下載並應用各種為Atom所建立的主題。這種靈活性讓Atom能夠按照你所希望的方式進行展現。對於JavaScript新手開發者和熱衷於自定義的使用者來說,Atom是一個優秀的工具。

(單擊圖片以放大)

來源: Atom

構建與自動化工具

現代的JavaScript專案正傾向於變得越來越複雜,變化的部分也在不斷增多。這並不是說這門語言或是對應的工具不夠高效,而是由於當前所建立的web應用程式的豐富性、酷炫的體驗和複雜性所導致的直接後果。在大型的專案中工作時,你必須經常做許多重複性的工作,無論是在你打算簽入程式碼、或是將程式碼構建到生產環境中。這些工作可能會包括合併、壓縮、對LESS或SASS CSS檔案的編譯,甚至是執行測試。手動完成這些工作不僅令人沮喪,效率也很低下。更好的辦法是通過某種支援這些任務的構建工具,對這些工作進行自動化。

合併(Bundling)與壓縮(Minification)

你所編寫的大多數JavaScript和CSS都會在多個web頁面中共享。因此,你很可能會將這些內容放到單獨的.js和.css檔案中,然後在web頁面中引用這些檔案。這種方式的結果是,使用者的瀏覽器為了完全顯示你的web引用,需要分別傳送一個HTTP請求,以獲取這些檔案(或者至少需要驗證一下這些檔案是否已經改變了)。

HTTP請求的代價是很高的。除了請求本身的大小之外,你還將因為網路延遲、HTTP頭和Cookie等內容買單。合併與壓縮工具的設計目的就是減少、乃至完全消除這些請求所帶來的影響。

合併

要改善web程式碼的效能,開發者所能做的最簡單的一件事就是將程式碼進行合併。在合併流程中,多個JavaScript或CSS檔案將被併入一個單一的JavaScript或CSS檔案中。感覺上就像是將多張個別的全景影像的照片連線在一起,以完成一張繼續的單一照片。通過將JavaScript檔案與CSS檔案進行合併,我們就能夠消除很大一部分HTTP請求的開銷。

壓縮

JavaScript開發者還有一種可以改善效能的方式,就是將剛剛合併的程式碼進行壓縮。壓縮過程能夠將JavaScript和CSS程式碼以儘可能最小的形式進行壓縮,同時保證功能不變。對於JavaScript來說,這就意味著將變數重新命名為無意義的單字元形式,並且去除所有空白和格式符。而對於CSS來說,由於頁面風格依賴於變數的名稱,因此通常來說只會去除格式符與空白。壓縮能夠極大的改進網路效能,因為它減少了每個HTTP響應的位元組數。

未經壓縮的AJAX JavaScript程式碼,與上面所展示的程式碼相同:

$.ajax({
    url: "test.html",
    statusCode: {
    	200: function() {
    		alert("success");
    	},
    	400: function() {
    		alert("error 400");
    	}
    },
    error: function() {
    	alert("something broke");
    }
});

同樣的程式碼經過壓縮之後的形式:

$.ajax({url:"test.html",statusCode:{200:function() {alert("success");},
400:function(){alert("error 400");}},error:function(){alert("something broke");}});

請注意,我將壓縮後的輸出結果分為兩行的目的,只是為了在文章中閱讀起來更方便,而實際上經過壓縮後的輸出通常來說只有一行。

合併與壓縮的時機

通常來說,合併與壓縮步驟只會在生產環境上執行,這樣做的原因是為了讓你在本地或是開發環境中可以對包含了格式符和行號的原始程式碼進行除錯。而除錯上面所顯示的那種壓縮程式碼會非常困難,因為所有的程式碼都擠在一行中。而且壓縮後的程式碼會變得完全不可讀,在你嘗試除錯時會發現這種程式碼完全無用,並讓你感到非常受挫。

原始碼對映檔案

有些時候,程式碼中的某些bug只有在生產環境才能重現。這樣一來,當你要除錯某些問題時,經過壓縮的程式碼就成為了一個問題。幸運的是,JavaScript支援原始碼對映檔案,它能夠在壓縮後的程式碼和原始程式碼之間進行“對映”。這些程式碼對映檔案是在壓縮階段由下文所說的某些構造工具所生成的。隨後你的JavaScript偵錯程式就能夠使用這些對映檔案,為你提供清晰可讀的程式碼進行除錯了。你應當儘可能將對映檔案與實際程式碼一起釋出,這樣就能夠在某些功能出錯時進行程式碼的除錯了。

程式碼整理

程式碼整理工具會根據預定義的格式化規則檢查你程式碼中的常見錯誤和問題,這些工具所報告的錯誤通常都類似於以下這些:使用了tab縮排而不是空格、在行末遺漏了分號、或是在沒有使用if、for或while語句的情況下使用了大括號。大多數IDE中都提供了程式碼整理工具,而其它一些IDE也允許使用者自行安裝程式碼整理外掛。

最流行的兩種JavaScript整理工具是JSHint和JSLint,JSLint是由Doug Crockford開發的整理框架,而JSHint則是由社群人員從JSLint中分支出來的。他們僅在各自的程式碼格式化標準上有著一些區別。我的建議是兩者都嘗試一下,然後選擇一個最適合你的程式碼風格的工具。

自動化任務:Grunt

與它的名稱不同,Grunt(本意為打呼嚕)絕不是一個粗糙的工具,而是一個健壯的命令列構造工具,能夠執行使用者所定義的各種任務。通過設定一個簡單的配置檔案,你就可以讓Grunt進行各種工作,例如編譯LESS或SASS檔案、構建並壓縮某個特定資料夾中的所有JavaScript和CSS檔案、甚至是執行某種程式碼整理工具或是測試框架。你也可以通過配置,將Grunt作為一種Git鉤子執行,當你往原始碼控制庫裡進行簽入時,自動地壓縮與合併你的程式碼。

Grunt支援各種命名的目標,因為你可以在不同的環境中指定不同的命令,比方說你可以將“dev”和“prod”指定為目標。這一點對於某些場景來說非常有用,例如在生產環境中將程式碼進行合併與壓縮,而在開發環境中忽略這一步驟,以便於除錯的需要。

Grunt中一個很有用的特性叫做“grunt watch”,它能夠對一個目錄中的檔案,或一個檔案集合中的變更進行監控。這一特性可以整合入WebStorm和Sublime Text這樣的IDE中使用。通過使用監控特性,你可以根據檔案變更的情況觸發事件。對於LESS或SASS的編譯就是這一特性的實用作法,你可以設定grunt以監控你的LESS或SASS檔案,當檔案產生變更時立即進行編譯,編譯後生成的檔案就可以直接在開發環境中進行使用了。你也可以讓grunt監控在你修改了每個檔案之後都自動地執行某種程式碼整理工具。通過grunt監控進行實時任務執行,是一種加速你的生產力的極好的方式。

自動化任務:Gulp

Grunt和Gulp都是用於解決構建自動化問題的工具,可以說兩者是直接的競爭者。他們之間主要的差別在於,Grunt更專注於配置,而Gulp更專注於程式碼。你在Grunt檔案中通過宣告式的JSON對構建任務進行配置,而在Gulp檔案中通過編寫JavaScript函式以實現相同的功能。

下面的這個Grunt配置檔案會在SASS檔案產生變更時,編譯生成CSS檔案:

grunt.initConfig({
  sass: {
    dist: {
      files: [{
        cwd: "app/styles",
        src: "**/*.scss",
        dest: "../.tmp/styles",
        expand: true,
        ext: ".css"
      }]
    }
  },
  autoprefixer: {
    options: ["last 1 version"],
    dist: {
      files: [{
        expand: true,
        cwd: ".tmp/styles",
        src: "{,*/}*.css",
        dest: "dist/styles"
      }]
    }
  },
  watch: {
    styles: {
      files: ["app/styles/{,*/}*.scss"],
      tasks: ["sass:dist", "autoprefixer:dist"]
    }
  }
});
grunt.registerTask("default", ["styles", "watch"]);

來源: Grunt vs Gulp – Beyond the Numbers

下面的這個Gulp配置檔案同樣會在SASS檔案產生變更時,編譯生成CSS檔案:

gulp.task("sass", function () {
  gulp.src("app/styles/**/*.scss")
    .pipe(sass())
    .pipe(autoprefixer("last 1 version"))
    .pipe(gulp.dest("dist/styles"));
});
gulp.task("default", function() {
  gulp.run("sass");
  gulp.watch("app/styles/**/*.scss", function() {
    gulp.run("sass");
  });
});

來源: Grunt vs Gulp – Beyond the Numbers

我建議你可以隨意選擇自己所喜歡的那一種。這兩種工具一般來說都是通過Node.js的包管理器npm下載的。

總結

JavaScript自從網際網路的早期誕生以來,已經經歷了巨大的改進。如今,它已成為了互動式web應用程式中一個突出的重要組成部分。

開發者們從1995年起到如今也經歷了巨大的變化,如今的開發者們更樂於使用豐富而健壯的框架、工具和IDE,以提高工作的效率和生產力。

建立你的第一個現代JavaScript應用程式或者比你自己想象中還要簡單!只要選擇好一個IDE(我向初學者推薦Atom),然後安裝npmgrunt。如果你之後在哪裡卡住了,Stack Overflow是非常好的資源。只要稍稍花一點時間學習基礎知識,你就很快能夠上手開發並最終釋出你的第一個現代JavaScript應用了。

資源

框架:

IDE:

程式碼整理工具:

構建與自動化工具

實用資源

相關文章