前端工程自動化構建總結

前端自動化構建是當下的熱門,我記得2014年的時候,前端的自動化構建,大可能是用在javascript的合併、壓縮、語法檢查、coffeescript,Sass,LESS轉換上,構建工具也有不少,好比ant,grunt,gulp等,二次封裝的工具也有不少,好比百度的FIS,國外的Yeoman。2016年之後,隨着es6,es7,Node的興起,前端又發生了翻天覆的變化,特別是移動端的H5最爲明顯,之前切個圖,在PC上預覽測試就能夠發佈的時代,在移動端就不靈驗了,在手機端預覽至少要搭建一個http服務器,好比http://192.168.0.2/index.html。在手機端輸入網址不方全,一般會將網址作成一個二維碼,而後用手機掃一下就能夠打開預覽。咱們每改一下樣式,就在手機上點一下刷新或電腦上按一下F5,這在最初的時候,也不以爲有什麼問題,由於拿到我手上的靜態頁,一般由切片的同事作好了兼容性測試,須要一邊刷新瀏覽器,一邊改樣式的機會很少。隨着咱們嘗試用Less,stylus,這樣的css工具,一方面,須要用到gulp這樣的工具在後臺自動監聽咱們的樣式改動,另外一方面,手動刷新的時候,gulp的腳本未必轉換完了。這時候迫切須要瀏覽器自動刷新。javascript

總的來講,需求就兩點,一是須要一個http服務器,來供手機訪問靜態資源,另外一個是監聽代碼的改動並自動刷新瀏覽器。要知足這兩個需求的第三方工具,應當不難找,事實上像fis,yeoman,vuecli這樣的工具應當均可以作到。但是我以爲它們都太複雜了,雖然我只用到其中一點點功能,可是我不得不仔細的通讀他們的文檔,找到本身須要的功能。有時候,官方說三分鐘入門,但是我花三十分鐘了尚未入門。或許我幾天以後,我好不容易入門了,結果周圍同事又給我推薦另外一個工具,說比我手上這好一千倍,因而我又去學另外一個工具。如此,很容易陷入不一樣工具之間的學習。更要命的是,轉了一圈回來,其實我用的那一點功能,用哪個工具都差很少,既不像A同窗說的那麼差勁,也不像B同窗說的那麼好。php

2015年6月份的時候,咱們的項目開始用express+React.js作服務端渲染,Redux作狀態管理。咱們搭建了一套開發框架,之前那些自動化的工具,都不能徹底知足個人需求了。js和css的改動愈來愈頻繁,並且node不像php代碼那樣,改動以後,服務器會自動更新,它須要手動重啓node進程,另外一方面,自動刷新瀏覽器,會致使redux的action日誌看不到。這個時候,瀏覽器的自動刷新已經知足不了咱們的需求。咱們須要瀏覽器在不刷新的狀況下,局部更新我改過的代碼。這也就是「熱替換」(HMR)這個概念的來由。不少新同事搞不清什麼是自動刷新,什麼是熱替換。熱替換聽起來,有點像是ajax的效果,不過,ajax是點擊某個動做或觸發某個事件以後由js腳本觸發,而「熱替換"是在咱們改動了代碼的時候觸發(也就是CTRL+S保存的時候). 自動刷新就是指不用手動去按F5. css

要實現自動刷新和靜態服務器,最簡的就是用webpack-dev-server . 若是以前用過webpack,那麼webpack-dev-server則很容易接受,若是尚未用過webpack,那麼我以爲頗有必要去看看。網上有不少介紹webpack及webpack-dev-server的文章,我以爲要這實現這個需求,只要兩步就能夠:html

   1.安裝webpack-dev-server前端

   2. 運行webpack-dev-server --inline --hotvue

webpack.config.js的配置:java

var path = require("path");
var webpack = require('webpack');
//var ExtractTextPlugin = require("extract-text-webpack-plugin");
var node_modules_dir = path.resolve(__dirname, 'node_modules');
 
module.exports = {
	entry:[
	 	//'webpack-dev-server/client?http://localhost:8081',
    	     //'webpack/hot/dev-server',
		'./src/app.jsx','./src/app.css'
	],
	module: {
    	loaders: [{
		    test: /\.es6|jsx$/,
		    exclude: [node_modules_dir],
		    loaders: ['react-hot','babel-loader'],
	    },
	    {
	    	test:/\.css$/,
	    	loaders:['style', 'css']
	    }]
  	},
	output: {
		path: path.resolve(__dirname, "dist"),
		publicPath:"/assets/",
    	filename: 'bundle.js'
 	},
 	resolve: {
    	extensions: ['', '.js','.es6','.jsx']
    },
 	plugins: [
 		new webpack.DefinePlugin({
		    'process.env.NODE_ENV': '"development"'
		}),
		//new webpack.HotModuleReplacementPlugin(),
		new webpack.NoErrorsPlugin()
    ]
}

經過命令行的方式執行webpack-dev-server , 重點要說的是--hot這個參數,它就是啓動熱替換用的。它會自動給plugins插入new webpack.HotModuleReplacementPlugin() 所以不須要人爲的再配置這個插件了。因此我在webpack.config.js中註釋掉了這一行。 而後entry中也不須要加webpack/hot/dev-server和webpack-dev-server/client,記住:命令行方式運行webpack-dev-server會自動替你完成這些工做。不要人云亦云的去添加這些註釋的內容,我看到甚至還有用express配合webpack-hot-middleware,webpack-dev-middleware 之類的用法,那更加複雜了,對於只想要實現自動刷新和熱替換來講,命令行方式運行,配合 --hot --inline 這兩個參數是最簡單有效的作法。其它複雜的配置和用法,有它的特殊的適用場景,好比同時須要兩個服務器,一個充當數據接口,一個充當靜態文件服務器, 咱們但願webpack-dev-server經過node API的方式運行。這個有點複雜,用到這麼複雜的情形的,通常都是能本身搞定這個配置的。有這方面需求的,參考demo8的代碼。 node

填坑記

extract-text-webpack-plugin這個插件,它能夠將模塊中的樣式部分提出來,單獨打包成文件,可是它只適用於生產模式。開始我也沒有注意,在開發模式下也用了,還以爲很爽,直到有一次,我發現更改樣式的時候,瀏覽器竟然自動刷新了,而我指望是熱替換。這時我才理解,只適用於生產模式,不是說它在開發模式下,就不生效了,而是它配合 --hot參數的時候,不會有熱替換的效果。react

簡單的一行小字,沒有細看,結果走了不少彎路。俗話說,方向反了,中止就是進步。 對於普通的js模塊來講,熱替換須要本身寫loader插件,若是是react,vue則官方會提供熱替換的loader,好比react的 react-hot-loader 。若是沒有用這些能夠支持熱替換的插件,那麼默認的就是瀏覽器的自動刷新效果。css的話,只要加上css-loader,style-loader就能夠了。最後再補一刀,output:中要配publicPathwebpack

output: {
		path: path.resolve(__dirname, "dist"),
		publicPath:"/assets/",
    	        filename: 'bundle.js'
 	},

在html中也要寫publickPath的地址:

/assets/這個虛擬目錄中的文件其實是保存在內存中的,這樣就爲模塊的熱替換提供了可能。若是寫成實際的產出目錄,是怎麼也不會看到熱替換的效果的,甚至連自動刷新都不會出現.

源碼地址:https://github.com/bjtqti/how_to_use_webpack/tree/master/demo18

驗證是否成功開啓HMR

首先看控制檯的提示:

出現這個HMR說明配置方面是對的,可是光有這個還不行,若是模塊沒有熱替換的loader,那麼就會觸發失敗,失敗的結果就是致使瀏覽器刷新。這也是爲何有時候明明出現這個熱替換的標誌了,仍是會出現瀏覽器刷新。若是添加了支持熱替換的loader,那麼當咱們保存更改的時候,瀏覽器只會默默的更新變化區域,而不會產生刷新。同時,控制檯的log也會累積,不會被清空。

 

手機預覽

辛苦作出來的H5頁面,在電腦上模擬顯示的效果,都未必可靠,最後都須要放到手機上進行真機檢測。經過webpack-dev-server生成的http服務器,能夠實現經過手機訪問。好比電腦的ip是192.168.1.122, 默認狀況下,那麼經過http://191.168.1.122:8080就能夠在手機上打開咱們的H5頁面。若是打不開,請檢查兩個地方:

 1. webpack-dev-server 添加 --host 0.0.0.0 參數

 2. 保證電腦和手機處於同一個無線網絡,即電腦能夠ping通手機。

打包發佈

在手機上檢測無缺以後,就須要把代碼進行合併,壓縮,添加hash標記,小圖片,字體文件轉base64,提取共公代碼等等.  一方面能夠簡單的使用

webpack -p 也可自行配置webpack.config.js,演示:

 plugins: [
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': '"production"'
        }),
        new ExtractTextPlugin('css/[name].css'),
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            },
            output: {
              comments: false
            },
            sourceMap: false
        }),
        new webpack.optimize.CommonsChunkPlugin('vendor','js/vendor.js'),
        new webpack.optimize.OccurenceOrderPlugin(true),
        new webpack.NoErrorsPlugin()
    ]

  

到此,整個構建工做就完成了。

 

小結

關於webpack及webpack-der-server的教程不少,可是不少文章發佈的較早,不必定適用你如今用的版本。遇到問題的時候,我建議先看看錯誤提示,而後查看官方文檔。先從簡單的用法開始去動手嘗試,必定要嘗試,不要以爲很簡單,只在腦海裏想固然的運行一遍就覺得學會了,俗話說,實踐出真知,一樣的問題,不一樣的環境(windows/mac/node版本...),會有不一樣的狀況,只有本身一一去試過了,遇到問題心中有數,纔不會慌。最後,要把學到的內容結合實際的項目去運用看看,有哪些功能對目前的開發有幫助,哪些功能還不是很瞭解,須要更深刻的學習。遇到實在有本身找不到解決辦法的問題,再去網上查,我的以爲stockoverflow還算比較靠譜。最後,要記得把本身遇到的坑整理成章,分享是一種美德。

相關文章
相關標籤/搜索