前端模塊化開發學習之gulp&browserify篇

   隨着web應用的發展,前端的比重佔得愈來愈多,編寫代碼從而也愈來愈複雜。而一般咱們須要將不一樣功能或者不一樣模塊的代碼分開寫,最後在html中一塊兒加載,這樣作是能夠的,可是當你須要進行維護或者是二次開發的時候,你會以爲十分費勁,由於你不知道文件之間複雜的關係,因此咱們須要利用一些插件來配合進行模塊化的開發。javascript

  所謂模塊化的開發,寫過nodejs的人都知道,文件之間的依賴能夠用require()實現,可是瀏覽器端是不支持這樣的依賴形式的,而browserify卻能夠解決這個問題,再加上gulp這個強大的構建工具,使得前端的模塊化開發變得簡單了。css

   接下來就利用gulp和browserify兩個工具,將ReactJs編寫的一個小Demo進行展現:html

    一.如何用React編寫Demo前端

    二.Gulp入門及操做java

    三.Browserify入門及操做node

    四.演示Demoreact

   先來看下咱們最終的目錄結構,以便讀者的後續操做:webpack

  

   一.如何用React編寫Demogit

   React是Facebook於2013年開源的一套框架,它從剛開始的UI框架逐漸演變成了新的Web解決方案。它的主要特色有三個:
github

    ---Just the UI

    ---Virtual DOM

    ---data flow

  一個語言的框架,重要的不是記住它的接口,而是要掌握它的思想,要理解並掌握React,須要從這三個特性入手。

   Just the UI

    沒錯,React在UI上有很是有優點的地方,這個優點主要來源於React能夠將一個網頁,甚至是一個項目工程的靜態頁面切割成不一樣的塊,也就是組件。

    組件化的開發能夠避免模板(如ejs)開發複雜的邏輯,同時它不影響其餘框架庫類合併使用,更有利於團隊開發。可見React使開發有了更便捷,使維護更簡單。 

  Virtual DOM

    熟悉前端的人都知道,傳統的DOM渲染及操做是很耗時的,特別是在DOM操做比較頻繁的狀況下,DOM是性能出現瓶頸的主要因素。

    而React採用虛擬DOM,利用diff算法來進行DOM管理,這裏的虛擬DOM實際上是保存在內存中,因此速度是很是快的。並且虛擬DOM能夠在服務器端渲染,在性能方面這是頗有創新的。可見React使網站性能更好。

  data flow

    React中的數據流與Angular是不一樣的,或許你認爲Angular的雙向數據流對於數據交互很是輕鬆,可是React基於屬性Props和狀態State的單向數據流會給你帶來條理很是清晰的邏輯,固然你還能夠引入其餘框架或者庫類來進行與後臺的數據交換,這一切的數據都是由組件(React中組件就是一個個狀態機)的屬性和狀態決定。可見React使任務邏輯更清晰。

 

  React是很創新的,對現代工業化前端的開發,維護以及使用的性能都是很是好的提高。還有關於React一些細節就不在這裏細說了。  

  

  接下來咱們開始編寫咱們的React Demo。這是一個相似問卷的一個小Demo,包含了3個判斷題的組件的一個頁面,咱們最後須要將用戶填寫的結果上傳到服務器,例子很簡單,你們主要要體驗下這個開發過程。

  首先在建立一個工程項目:

    1.建立一個項目文件夾,而且在sublime text中打開

    2.使用cmd進入這個文件夾,而後npm init建立package.json文件,這個文件展現工程的相關信息,包括插件的信息。(前提是要先安裝npm)

    

    3.編寫子組件Child.jsx(判斷題組件),從如今開始咱們直接採用模塊化的語法來編寫JSX文件,寫過Node的小夥伴會以爲很熟悉,它其實和服務器端的CommonJs規範是差很少的。有關React的語法能夠經過React的官方文檔進行了解。

    facebook.github.io/react/index.html      >>Learn React Now !

 1 var React = require("react/addons");
 2 
 3 // 判斷題能夠看做對和錯只能選一個的題目,所以是一個單選框
 4 var Child = React.createClass({
 5     // 狀態對象包含判斷題的當前選項的值
 6     // @param : value
 7     // @key : true,false
 8     getInitialState : function(){
 9         return{
10             value : "true"
11         };
12     },
13     handleChange : function(event){
14         //經過事件委託鏈接子組件和父組件,將子組件中的value狀態傳入到父組件中
15         if(this.props.onChange){
16             this.props.onChange(event);
17         }
18         //更改子組件的狀態,從新渲染UI上。
19         this.setState({
20             value : event.target.value
21         });
22     },
23     render : function(){
24         return(
25             <div>
26                 <label>{this.props.label}</label>
27                 <input type="radio" name={this.props.name} checked={this.state.value == "true"} value="true" onChange={this.handleChange} />
28                 "true"
29                 <input type="radio" name={this.props.name} checked={this.state.value == "false"} value="false" onChange={this.handleChange} />
30                 "false"
31             </div>
32         )
33     }
34 });
35 
36 module.exports = Child;
View Code   

    4.編寫父組件Parent.jsx(提交組件)。

 1 var React = require("react/addons");
 2 var Child = require("./Child.jsx");
 3 
 4 var Parent = React.createClass({
 5     getInitialState : function(){
 6         return{
 7             //題目編號
 8             name : ["judge-1","judge-2","judge-3"],
 9             //題目名稱
10             label : ["do you think yxy is handsome?",
11                 "do you like this boke?",
12                 "do you want to know React?"
13             ],
14             //用戶默認選項
15             value1 : "true",
16             value2 : "true",
17             value3 : "true"
18         }
19     },
20     handleChange : function(value,event){
21         var newState = {};
22         //經過子組件傳過來的value改變當前父組件的value
23         newState[value] = event.target.value;
24         //設置新狀態
25         this.setState(newState);
26     },
27     handleSubmit : function(event){
28         //取消提交默認事件
29         event.preventDefault();
30         //打印父組件存放的數據
31         console.log(this.state);
32     },
33     render : function(){
34         var renderChilds = [];
35         renderChilds = this.state.name.map(function(value,index){
36             return(
37                 <Child name={this.state.name[index]} label={this.state.label[index]} onChange={this.handleChange.bind(this,"value"+(index+1))}></Child>
38             );
39         }.bind(this));
40         return(
41             <form onSubmit={this.handleSubmit}>
42                 {renderChilds}
43                 <button type="submit">提交</button>
44             </form>
45         );
46     }
47 });
48 
49 module.exports = Parent;
View Code

    5.最後的出口文件app.jsx。

1 var React = require("react/addons");
2 var Parent = require("./Parent.jsx");
3 
4 React.render(<Parent></Parent>,document.body);
5 Perf = React.addons.Perf;
View Code

    6.目前爲止咱們工程的目錄以下:

    

    React編寫告一段落。

 

  二.Gulp入門及操做

  什麼是Gulp

  Gulp是一個基於流的自動化構建工具,須要注意兩點,一爲自動化,二爲流。

  在Gulp以前又一款名爲Grunt的工具拉開了前端自動化的帷幕。所謂自動化,就是自動幫你完成一些工程中須要咱們去手動完成的一些重複繁瑣的操做,簡單的好比預處理,壓縮,合併文件等等。而"流",表明着Gulp經過IO流的通道高效地進行自動化任務,前面提到的Grunt是與之相反,它沒進行一次任務都會打開一次IO通道,任務耗時天然沒有Gulp好。

  瞭解Grunt ->  官網 : http://gruntjs.com/          中文官網 : http://www.gruntjs.net/        

  瞭解Gulp ->  官網 :  http://gulpjs.com/          中文官網 : http://www.gulpjs.com.cn/

  

  安裝Gulp

  安裝及項目使用過程在官網都有介紹,這裏再簡單說一下。

  1.全局安裝Gulp

npm install -g gulp

  2.做爲項目的開發依賴安裝

npm install  gulp --save-dev

  

  如何使用Gulp管理文件

  1.建立gulpfile.js文件於項目根目錄,在其中編寫咱們的任務代碼。

var gulp = require('gulp');

gulp.task('default', function() {
  // 將你的默認的任務代碼放在這
});

  2.在gitBash或者其餘窗口命令中執行任務

gulp

 

  關於Gulp

  Gulp的學習很是簡單,反覆練習幾回你就會發現Gulp的方便之處~

 

  三.Browserify入門及操做

  上一點中,咱們知道了gulp是一款很是強大的自動化構建工具,然而咱們最開始也提到了瀏覽器中是不能直接解析相似require()這樣的語法的。因此咱們須要Browserify這個強大的工具。

 

  什麼是Browserify

  Browserify 可讓你使用相似於 node 的 require() 的方式來組織瀏覽器端的 Javascript 代碼,經過預編譯讓前端 Javascript 能夠直接使用 Node NPM 安裝的一些庫。

  瞭解Browserify ->  官網 : http://browserify.org/

  

  安裝Browserify

  安裝Browserify和安裝Gulp是同樣的簡單。

  1.全局安裝Browserify

npm install -g browserify

  2.做爲項目的開發依賴安裝

npm install browserify --save-dev

  

  如何使用Browserify

   1.利用Browserify解決require()依賴問題,將app.js中全部依賴項加載並整合到goal.js中。html只要加載goal.js便可。

browserify app.js > goal.js

  

  關於Browserify

  Browserify解決了js在瀏覽器端的依賴問題,可是還有一個更爲強大的工具名曰webpack!它能夠將js,css,png等不少文件的依賴問題解決,而Browserify只能解決js。但已經足夠強大,有關webpack的內容我和你們都還須要慢慢去了解。

 

  四.演示Demo

  終於到了激動人心的時候,如今我會結合前面兩個工具來進行前端模塊化開發的模擬。

 

  1.包含全部依賴到node_modules文件中,package.json中會出現對應依賴項。

    1.1 React框架.

    npm install react --save-dev

    安裝React是爲了使咱們編寫的React組件可以順利使用。

    

    1.2 Gulp工具.

    npm install gulp --save-dev

    安裝Gulp方便自動化構建咱們的文件

 

    1.3 Browserify工具

    npm install browserify --save-dev

    安裝Browserify解決js依賴問題。

 

    *1.4 reactify工具

    npm install reactify --save-dev

    將jsx編譯爲js,相似與JSXTransform.js。

 

    *1.5 react-tools工具

    npm install react-tools --save-dev

      

    *1.6 vinyl-source-stream工具

    npm install vinyl-source-stream --save-dev

    這個要着重說一下,使用gulp時,你可能會陷入「流不兼容」的問題。這主要是由於常規流和Vinyl文件對象有差別,或是使用了僅支持buffer(不支持流)庫的gulp插件與常規流不兼容。

    若是咱們須要將gulp和(或)gulp插件與常規的可讀流一塊兒使用,咱們就須要先把可讀流轉換爲vinyl。

    若是實在不能理解,能夠取百度Google更多資料,推薦看看這篇文章 : http://segmentfault.com/a/1190000000711469

 

     

  2.編寫gulpfile.js文件

    在編寫以前要明確咱們的目的 ->將全部的jsx及jsx所依賴的js文件合併到一個新的js文件中

    所以gulpfile.js文件以下 : 

 1 var gulp = require("gulp");
 2 var browserify = require("browserify");
 3 var source = require("vinyl-source-stream");
 4 var reactify = require("reactify");
 5 
 6 
 7 //gulp主動設置的命令
 8 gulp.task("combine",function(){
 9     //經過browserify管理依賴
10     browserify({
11         //入口點,app.jsx
12         entries : ["./app.jsx"],
13         //利用reactify工具將jsx轉換爲js
14         transform : [reactify]
15     })
16         //轉換爲gulp能識別的流
17         .bundle()
18         //合併輸出爲app.js
19         .pipe(source("app.js"))
20         //輸出到當前文件夾中
21         .pipe(gulp.dest("./"));
22 });
23 
24 
25 //gulp默認命令
26 gulp.task("default",["combine"]);
View Code

 

  

  3.執行gulp命令

 

  

  

  4.查看咱們的目錄結構

  

 

  5.打開index.html

  

 

  6.執行4次提交操做,觀察數據是否正確顯示

  

  

  7.能夠看到value1,value2,value3的值隨咱們的不一樣提交而改變。

 

  

  總結:

  前端現在已經步入工業化的時代,結合多樣的工具可讓咱們更高效地進行開發,固然如今的前端工具仍處於不穩定的階段,但咱們也須要不斷的摸索,從grunt到gulp,再到當下最火的webpack,前端多樣化的工具的更新迭代從未停下腳步,所以咱們更不該該中止學習的腳步。

  一樣的,gulp+browserify的開發模式可能會隨着前端的浪潮逐漸被埋沒,但它的思想是永恆的,咱們要作的即是拋下浮躁,去探索更好的開發模式。

相關文章
相關標籤/搜索