Gulp和Webpack的差異

? ? ? ?在現(xiàn)在的前端開發(fā)中,前后端分離、模塊化開發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等等一些原本后端的思想開始逐漸滲透到“大前端”的開發(fā)中。前端開發(fā)過程越來越繁瑣,當今越來越多的網(wǎng)站已經(jīng)從網(wǎng)頁模式進化到了 Webapp 模式。它們運行在現(xiàn)代的高級瀏覽器里,使用 HTML5、 CSS3、 ES6 等更新的技術(shù)來開發(fā)豐富的功能,網(wǎng)頁已經(jīng)不僅僅是完成瀏覽的基本需求,并且Webapp通常是一個單頁面應用(SPA),每一個視圖通過異步的方式加載,這導致頁面初始化和使用過程中會加載越來越多的 JavaScript 代碼,這給前端開發(fā)的流程和資源組織帶來了巨大的挑戰(zhàn)。

前端開發(fā)和其他開發(fā)工作的主要區(qū)別,首先是前端是基于多語言、多層次的編碼和組織工作,其次前端產(chǎn)品的交付是基于瀏覽器,這些資源是通過增量加載的方式運行到瀏覽器端,如何在開發(fā)環(huán)境組織好這些碎片化的代碼和資源,并且保證他們在瀏覽器端快速、優(yōu)雅的加載和更新,就需要一個模塊化系統(tǒng),這個理想中的模塊化系統(tǒng)是前端工程師多年來一直探索的難題。

本文需要有一定的GulpWebpack的基本概念,對Gulp和Webpack的使用有一定的了解。

同時還需要對npm或者cnpm有一定的的了解,對ComonJS、AMD規(guī)范有一定的的了解。

Gulp

Gulp就是為了規(guī)范前端開發(fā)流程,實現(xiàn)前后端分離、模塊化開發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等功能的一個前端自動化構(gòu)建工具。說的形象點,“Gulp就像是一個產(chǎn)品的流水線,整個產(chǎn)品從無到有,都要受流水線的控制,在流水線上我們可以對產(chǎn)品進行管理?!?/p>

另外,Gulp是通過task對整個開發(fā)過程進行構(gòu)建。

Webpack

Webpack是當下最熱門的前端資源模塊化管理和打包工具。它可以將許多松散的模塊按照依賴和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源。還可以將按需加載的模塊進行代碼分隔,等到實際需要的時候再異步加載。通過 loader的轉(zhuǎn)換,任何形式的資源都可以視作模塊,比如 CommonJs 模塊、AMD 模塊、ES6 模塊、CSS、圖片、JSON、Coffeescript、LESS 等。

Gulp和Webpack功能實現(xiàn)對比

簡單介紹了一下Gulp和Webpack的概念性的問題和大環(huán)境,接下來進入本文的主題,對比一下Gulp和Webpack的優(yōu)缺點。將從基本概念、啟動本地Server、sass/less預編譯、模塊化開發(fā)、文件合并與壓縮、mock數(shù)據(jù)、版本控制、組件控制八個方面對Gulp和Webpack進行對比。

基本概念

首先從概念上,我們可以清楚的看出,Gulp和Webpack的側(cè)重點是不同的。

Gulp側(cè)重于前端開發(fā)的整個過程的控制管理(像是流水線),我們可以通過給gulp配置不通的task(通過Gulp中的gulp.task()方法配置,比如啟動server、sass/less預編譯、文件的合并壓縮等等)來讓gulp實現(xiàn)不同的功能,從而構(gòu)建整個前端開發(fā)流程。

Webpack有人也稱之為模塊打包機,由此也可以看出Webpack更側(cè)重于模塊打包,當然我們可以把開發(fā)中的所有資源(圖片、js文件、css文件等)都可以看成模塊,最初Webpack本身就是為前端JS代碼打包而設計的,后來被擴展到其他資源的打包處理。Webpack是通過loader(加載器)和plugins(插件)對資源進行處理的。

另外我們知道Gulp是對整個過程進行控制,所以在其配置文件(gulpfile.js)中配置的每一個task對項目中該task配置路徑下所有的資源都可以管理。

比如,對sass文件進行預編譯的task可以對其配置路徑下的所有sass文件進行預編譯處理:

gulp.task('sass',function(){gulp.src('src/styles/*.scss').pipe(sass().on('error',sass.logError)).pipe(gulp.dest('./build/prd/styles/'));//編譯后的輸出路徑});

上面這個task可以對'src/styles/*.scss'目錄下的所有以.scss結(jié)尾的文件進行預處理。

Webpack則不是這樣管理資源的,它是根據(jù)模塊的依賴關系進行靜態(tài)分析,然后將這些模塊按照指定的規(guī)則生成對應的靜態(tài)資源(如下圖)。

通俗的說,Webpack就是需要通過其配置文件(webpack.config.js)中entry配置的一個入口文件(JS文件),如下圖

entry: {app:__dirname +"/src/scripts/app.js",}

然后Webpack進入該app.js文件進行解析,app.js文件如下圖:

//引入scss文件import'../style/app.scss';//引入依賴模塊vargreeter =require('./Greeter.js');document.getElementById('root').appendChild(greeter());

解析過程中,發(fā)現(xiàn)一個app.scss文件,然后根據(jù)webpack.config.js配置文件中的module.loaders屬性去查找處理.scss文件的loader進行處理,處理app.scss文件過程中,如果發(fā)現(xiàn)該文件還有其他依賴文件,則繼續(xù)處理app.scss文件的依賴文件,直至處理完成該“鏈路”上的依賴文件,然后又遇到一個Greeter.js模塊,于是像之前一樣繼續(xù)去查找對應的loader去處理…

所以,Webpack中對資源文件的處理是通過入口文件產(chǎn)生的依賴形成的,不會像Gulp那樣,配置好路徑后,該路徑下所有規(guī)定的文件都會受影響。

模塊化開發(fā)

所謂的前端模塊化開發(fā),我的理解就是,在開發(fā)的時候,把不通的資源文件按照他的具體用途進行分類管理,在使用的時候利用CommonJS、AMD、CMD等規(guī)范將這些資源文件引入到當前文件中。然后在測試或者最后上線的時候,將這些資源文件按照一定的要求進行壓縮合并再加上版本控制處理。

可能這樣的理解或者說法值得商榷,但是個人還是覺得模塊化就是對內(nèi)容的管理,是為了解耦合。

首先從Gulp入手,看看在項目中,怎樣利用模塊化的思想進行開發(fā)。下面是一個gulp項目的目錄結(jié)構(gòu):

Gulp |——build:項目輸出路徑 | |——prd:css、js文件輸出路徑 | |——scripts:js文件的輸出路徑 | |——styles:css文件的輸出路徑 | |——ver:版本號相關文件 | |——index.html:編譯后的index.html |——images:圖片文件夾 |——mock:mock數(shù)據(jù)文件夾 |——node_modules:npm包管理文件夾 |——src:工作目錄 | |——scripts | |——libs:第三方依賴庫(jQuery等) | |——tpls:模板文件 | |——utils:工具類文件夾 | |——views:頁面自定義js文件 | |——app.js:index.html文件的入口js | |——styles:文件和scripts文件夾下基本一致(本例中我引用了第三方框架,目錄更深,不在展示) |——gulpfile.js:gulp的配置文件 |——index.html:主頁html文件 |——package.json:npm包管理配置文件

在實際開發(fā)過程中,在src目錄下工作,html、js和css等文件通過gulp的task配置,執(zhí)行合并和壓縮后輸出到build目錄下(下面會詳細介紹合并壓縮的實現(xiàn))。在詳細一點就是:

創(chuàng)建主頁html文件

創(chuàng)建與之對應的app.js入口文件和app.scss入口文件。這兩個文件只通過CommonJS規(guī)范引入各自views文件中自定義的js(或scss)文件,具體邏輯不寫此文件中。

在views目錄下編寫js(或css)文件的邏輯代碼,其中如果多個文件需要公共邏輯或者工具方法,就可以抽離出來在util文件夾下創(chuàng)建對應的公共方法,然后在views中需要的js(或css)文件中通過CommonJS規(guī)范引入使用。libs目錄下的第三方庫或框架也是這個思想去引用。

scripts目錄下的tpls文件是用來放置html模板的,引用方式和引用libs相同。

大體介紹了一下我理解的模塊化的思想,但是需要指出的是Gulp對js文件的模塊化工作是通過Webpack實現(xiàn)的,具體來說是通過安裝gulp-webpack模塊和相關的loader模塊進行js模塊化管理的。具體步驟如下:

在項目中通過npm安裝一個gulp-webpack、vinyl-namedimports-loaderstring-loader模塊(壓縮合并模塊后面再介紹)

$ npminstallgulp-webpack vinyl-named -D

然后在Gulp的配置文件gulpfile.js中通過CommonJs規(guī)范引入gulp-webpack 模塊,并進行簡單配置

//1.引入 gulp-webpack和vinyl-named模塊varwebpack=require('gulp-webpack');varwebpack=require('vinyl-named');//2.js 模塊化配置varjsFiles = ['./src/scripts/*.js', ]; gulp.task('packjs',function(){ gulp.src(jsFiles) .pipe(uglify().on('error',function(err){console.log('\x07',err.lineNumber,err.message);returnthis.end(); }))//Webpack 對js模塊化部分 start.pipe(webpack({output:{filename:'[name].js'},module:{loaders:[{test:/\.js$/,loader:'imports?define=>false'}, {test:/\.string$/,loader:'string'} ] } }));//Webpack 對js模塊化部分 end.pipe(concat('all.js')) .pipe(gulp.dest('./build/prd/scripts/'));});

對css文件我們也采用同js文件一樣的模塊化思想,利用sass進行模塊化開發(fā),至于對scss文件的合并壓縮配置,下面還會詳細介紹。

接下來應該介紹一下Webpack的模塊化實現(xiàn)了,其實也就沒什么可以說的了,文件目錄和Gulp的基本相同,只不過實現(xiàn)過程中使用到的插件或者說模塊不同,配置不同而已。另外需要注意的是,Webpack對于資源文件的模塊化打包處理都是按js文件的處理方式處理的,例如還是上一小節(jié)中,你可能發(fā)現(xiàn)了,我在app.js入口文件中有這樣一行代碼

import'../style/app.scss';

你當時可能產(chǎn)生疑問,為什么在js文件中引入scss文件呢?

這是因為Webpack是通過依賴關系進行文件管理的,所以,想要對樣式文件進行模塊化管理則必須與app.js入口文件建立依賴關系,因此我們將樣式文件的入口app.scss文件引入到了app.js中(其他資源想要被管理,也需要這樣與app.js入口文件建立依賴關系)。

但是這樣做很明顯的就是樣式文件通過app.js入口文件全部都合并壓縮到js文件中了,這很顯然不是我們想要的結(jié)果,所以我們需要將樣式文件從js文件中剝離出來。

在項目中通過npm安裝一個extract-text-webpack-plugin的模塊

$ npminstallextract-text-webpack-plugin-D

然后在Webpack的配置文件webpack.config.js中進行簡單配置

//1.引入extract-text-webpack-plugin模塊varEt =require('extract-text-webpack-plugin');module.exports = {//source-map調(diào)試devtool:'eval-source-map',//webpack入口文件配置entry: { app:__dirname +"/src/scripts/app.js", },//webpack出口文件配置output: { path: __dirname +"/prd/scripts/",//輸出文件路徑配置filename:"bundle.js"http://輸出文件名配置},module:{ loaders:[ { test:/\.scss$/, loader: Et.extract('style','css!sass')//從js中抽離scss文件} ] }, plugins: [newEt('./styles/bundle.css'),//從js中抽離scss文件輸出目錄設置],//本地server配置devServer: { contentBase: __dirname +'/prd/',//本地服務器所加載的頁面所在的目錄port:8089,//本地服務端口配置colors:true,//終端中輸出結(jié)果為彩色historyApiFallback:true,//不跳轉(zhuǎn)inline:true//實時刷新}}

上面有些配置信息并不完全,下面的小節(jié)中會逐漸介紹到。這樣我們就實現(xiàn)了將css文件從js文件中剝離出來的目的。Webpack不但可以對css文件可以進行模塊化管理,還可以對圖片進行模塊管理,有興趣的可以自己去嘗試一下。

文件合并與壓縮

上面的模塊化中,我們提到了模塊化其實很大一部分是在做文件的合并與壓縮操作,所以我們馬上來看看Gulp和Webpack是怎樣是想文件的合并和壓縮的。

先來看看大背景,由于現(xiàn)在前端越來越龐大,頁面文件依賴也越來越多,所以對這些文件進行合理的合并和壓縮就志在必得。根據(jù)前面的了解,Webpack應該比Gulp更擅長文件合并和壓縮,畢竟人家被稱為模塊打包機嗎。

結(jié)論是正確的,Gulp可以對css文件以及js文件進行合并壓縮處理,而Webpack可以實現(xiàn)對css文件,js文件,html文件等進行合并壓縮和圖片的壓縮,還可以對js文件進行編譯(如es6–>es5,react jsx)等等,這些都是通過Webpack的loader實現(xiàn)的,當然這些也可以加入到Gulp中,畢竟Gulp把Webpack當做一個模塊,通過gulp-webpack都引入了。

Gulp合并壓縮文件

css的壓縮

要想實現(xiàn)Gulp對css文件的壓縮只需要安裝一個gulp-minify-css模塊即可。

在項目中通過npm安裝一個gulp-minify-css的模塊

$ npminstallgulp-minify-css -D

然后在Gulp的配置文件gulpfile.js中通過CommonJs規(guī)范引入gulp-minify-css模塊,并進行簡單配置

//1.引入 gulp-minify-css模塊varminifyCSS =require('gulp-minify-css');//2.css 預處理varcssFiles = ['./src/styles/usage/page/index.scss']gulp.task('sass',function(){ gulp.src(cssFiles) .pipe(sass().on('error',sass.logError)) .pipe(minifyCSS())//執(zhí)行壓縮處理在一行.pipe(gulp.dest('./build/prd/styles/'));});

這樣一個簡單的css壓縮就實現(xiàn)了。

js合并壓縮

要想實現(xiàn)Gulp對js文件的合并壓縮需要安裝一個gulp-uglifygulp-concat兩個模塊,前者是用于壓縮的模塊,后者是一個合并的模塊。

在項目中通過npm安裝gulp-uglifygulp-concat模塊

$ npminstallgulp-uglify gulp-concat-D

然后在Gulp的配置文件gulpfile.js中通過CommonJs規(guī)范引入gulp-uglifygulp-concat模塊,并進行簡單配置

//1.引入**gulp-uglify**和**gulp-concat**模塊varuglify =require('gulp-uglify');varconcat =require('gulp-concat');//js 合并壓縮varjsFiles = ['./src/scripts/*.js', ]; gulp.task('packjs',function(){ gulp.src(jsFiles)//js文件的壓縮.pipe(uglify().on('error',function(err){console.log('\x07',err.lineNumber,err.message);returnthis.end(); })) .pipe(webpack({output:{filename:'[name].js'},module:{loaders:[{test:/\.js$/,loader:'imports?define=>false'}, {test:/\.string$/,loader:'string'} ] } }));//js文件的合并.pipe(concat('all.js')) .pipe(gulp.dest('./build/prd/scripts/'));});

js的文件合并壓縮也完成了。我們再來看一下Webpack的合并壓縮。

Webpack的合并壓縮

壓縮js和css

針對js和css文件的壓縮,Webpack已經(jīng)內(nèi)嵌了uglifyJS來完成對js與css的壓縮混淆,無需引用額外的插件。我們只需要在Webpack配置文件中的plugins屬性中做如下配置:

plugins: [newwebpack.optimize.UglifyJsPlugin({//壓縮代碼compress: {warnings: false },except: ['$super','$','exports','require']//排除關鍵字})]

需要注意的是:壓縮的時候需要排除一些關鍵字,不能混淆,比如$或者require,如果混淆的話就會影響到代碼的正常運行。

html的壓縮

想要對html進行壓縮,同樣也是需要配置Webpack的配置文件,并且需要下載兩個插件HtmlWebpackPluginhtml-minifier插件:

1.在項目中通過npm安裝HtmlWebpackPluginhtml-minifier模塊

$ npminstallHtmlWebpackPlugin -D$ npminstallhtml-minifier -D

2.然后在Webpack的配置文件webpack.config.js進行如下配置:

plugins: [newHtmlWebpackPlugin({//根據(jù)模板插入css/js等生成最終HTMLfavicon:'./src/img/favicon.ico',//favicon路徑filename:'/view/index.html',//生成的html存放路徑template:'./src/view/index.html',//html模板路徑inject:true,//允許插件修改哪些內(nèi)容,包括head與bodyhash:true,//為靜態(tài)資源生成hash值minify:{//壓縮HTML文件removeComments:true,//移除HTML中的注釋collapseWhitespace:true//刪除空白符與換行符} }) ]

HtmlWebpackPlugin插件在生成HTML時調(diào)用了 html-minifier 插件來完成對HTML的壓縮,這里我們使用兩個配置完成來移除HTML中的注釋以及空白符達到壓縮的效果。

sass/less預編譯

我們再來看看sass/less預編譯,其實就sass/less的預編譯來說,兩者區(qū)別不是很大。Gulp是通過gulp-sass、gulp-less模塊進行預處理;而Webpack是通過scss-loader、less-loader加載器(loader)進行預處理。我們還是分別來看一下兩者對此的實現(xiàn)。

Gulp預編譯sass/less

以sass為例子:

在項目中通過npm安裝一個gulp-sass的模塊

$ npminstallgulp-sass -D

然后在Gulp的配置文件gulpfile.js中通過CommonJs規(guī)范引入gulp-sass模塊,并進行簡單配置

//1.引入 gulp-sass模塊varsass=require('gulp-sass');//2.css 預處理varcssFiles = ['./src/styles/usage/page/**/*'//./src/styles/usage/page目錄下的所有文件];gulp.task('sass',function(){ gulp.src(cssFiles) .pipe(sass().on('error',sass.logError)) .pipe(minifyCSS()) .pipe(gulp.dest('./build/prd/styles/'));//編譯后的輸出路徑});//3.對sass文件的修改添加監(jiān)聽事件gulp.task('watch',function(){ gulp.watch('./src/styles/**/*',['sass']);});gulp.task('default',['watch','webserver'],function(){console.log('所有任務隊列執(zhí)行完畢');});

這樣,一個簡單的sass預處理的task就配置完成了,然后我們還將該task加到gulp.watch()上實現(xiàn)了自動編譯(即修改sass文件后保存,則立即執(zhí)行sass預處理),配合Gulp啟動的server則可以實現(xiàn)sass文件修改保存即可在瀏覽器中查看效果的目的,下一小節(jié)會介紹啟動本地server。

Webpack預編譯sass/less

同樣以sass為例子:

在項目中通過npm安裝一個sass-loadernode-sass模塊,前者是用來加載sass相關文件的,后者是用來編譯sass文件的。另外還需要安裝另外兩個模塊css-loaderstyle-loader,前者是用來加載css相關文件的,后者是用來將css樣式裝填到html中的內(nèi)聯(lián)樣式。

$ npminstallsass-loader node-sass css-loaderstyle-sass -D

然后在Webpack的配置文件webpack.config.js中進行簡單配置

module:{loaders:[ { test: /\.css$/,//匹配以.css結(jié)尾的文件,如果你項目不需要刻意不配置 loader:'style!css'//這里順序必須這樣 }, {test: /\.scss$/,//匹配以.scss結(jié)尾的文件 loader:'style!css!sass'} ]}

前面提到過,Webpack是通過文件的依賴關系進行加載分析的,所以當程序從主入口(js文件)進入后,在依賴的資源文件中發(fā)現(xiàn)有sass文件后,就會利用我們配置的sass-loader去加載,然后用node-sass去解析編譯成普通的css語法的樣式文件,在然后就是利用style-loader將樣式以內(nèi)聯(lián)樣式的形式配置到html中(這里有一個問題,就是css-loader有什么用?我也沒搞明白,但是不添加會報錯,有知道的可以留言交流一下)。這樣Webpack就完成了sass的預處理。

啟動server

我們都知道在前端開發(fā)中,ajax請求是需要啟動一個server的。特別是在前后端分離思想中,前端開發(fā)不再像以前一樣過分依賴于后端開發(fā),以前的那種前端測試ajax請求需要裝個tomcat或者其它服務器來啟動server的現(xiàn)象已經(jīng)成為過去式,現(xiàn)在我們可以使用像Gulp這類前端自動構(gòu)建工具啟動一個本地server進行測試,再也不收后端程序員鉗制了(開個玩笑,和后端好好溝通才能讓前端開發(fā)更方便)。那么,我們來分別看一下Gulp和Webpack是怎樣實現(xiàn)這個功能的。

Gulp啟動server

在Gulp中想要啟動一個本地serve,只需要以下幾步:

在項目中通過npm安裝一個gulp-webserver的模塊

$ npminstallgulp-webserver -D

然后在Gulp的配置文件gulpfile.js中通過CommonJs規(guī)范引入gulp-webserver模塊,并進行簡單配置

//1.引入 gulp-webserver 模塊varwebserver =require('gulp-webserver');//2.配置server taskgulp.task('webserver',function(){ gulp.src('./') .pipe(webserver({host:'localhost',port:80,//瀏覽器自動刷新livereload:true,//顯示文件目錄directoryListing:{enable:true,path:'./'}, }));});//3.配置默認taskgulp.task('default',['webserver'],function(){console.log('啟動任務隊列執(zhí)行完畢');})

在命令行中啟動server

$ gulp

啟動成功:

在瀏覽器地址欄中輸入localhost打開頁面驗證。

經(jīng)過以上這三步,我們就在Gulp中啟動了一個server了。在Gulp中啟動本地服務有一個很方便的配置,就是livereload:true屬性的設置,設置后瀏覽器會根據(jù)你項目中資源的變化自動刷新瀏覽器(如果你的chrome瀏覽器設置該屬性后在你修改文件并保存時仍沒有自動刷新,可能是你的chrome瀏覽器不支持,可以chrome擴展程序中搜索并安裝LiveReload插件),比如:

我的gulp測試目錄結(jié)構(gòu):

index.html

Document

我在app.js文件中輸入以下內(nèi)容,然后保存。

console.log('gulp-webserver livereload');

瀏覽器中控制臺上會立刻打印出一下信息:

說明瀏覽器自動刷新工程,這個小功能在我們開發(fā)中屢試不爽。但是,這個功能是需要結(jié)合上一小節(jié)中的gulp.watch()實時監(jiān)控文件變化,然后執(zhí)行合并壓縮和sass/less編譯等操作后,瀏覽器再刷新時才能保證是我們修改后的內(nèi)容。所以,livereload:true屬性只是監(jiān)控到我們修改文件后刷新瀏覽器重新請求文件,如果我們不重新編譯修改后的文件,瀏覽器獲取到的還是原文件,并不會展示變化。

Webpack啟動server

在Webpack中也可以通過插件的形式安裝一個webpack-dev-server來實現(xiàn)達到啟動本地server的目的,具體步驟如下:

在項目中通過npm安裝一個webpack-dev-server的模塊

$ npminstall-g webpack-dev-server-D

然后在Webpack的配置文件webpack.config.js中進行簡單配置

module.exports= { devtool:'eval-source-map',//webpack入口文件配置entry: { app:__dirname +"/src/scripts/app.js", },//webpack出口文件配置output: { path: __dirname +"/prd/scripts/",//輸出文件路徑配置filename:"bundle.js"http://輸出文件名配置},//本地server配置devServer: { contentBase: __dirname,//本地服務器所加載的頁面所在的目錄port:8089,//本地服務端口配置colors:true,//終端中輸出結(jié)果為彩色historyApiFallback:true,//不跳轉(zhuǎn)inline:true//實時刷新}}

在命令行中啟動server

$ webpack-dev-server

然后你就會看見命令行輸出內(nèi)容很多,只要看看保證沒有Error就說明成功了。

在瀏覽器地址欄中輸入localhost:8089測試一下。

Webpack的啟動本地服務也順利實現(xiàn)了,是不是也想實現(xiàn)像Gulp一樣瀏覽器自動刷新呀?那Webpack能不能實現(xiàn)呢?答案是肯定的,Webpack官方提供了一個輔助開發(fā)工具,它可以自動監(jiān)控項目下的文件,一旦有修改保存操作,開發(fā)服務器就會自動運行Webpack 打包命令,幫我們自動將開發(fā)的代碼重新打包。而且,如果需要的話,還能自動刷新瀏覽器,重新加載資源。理論上好像是這樣,但是實現(xiàn)好像有不少限制,比如,HTML文件的自動刷新問題(html-webpack-plugin插件使用老是報錯),當本地server啟動在非output.path路徑之外時則不能自動刷新等問題,等我再學習學習再說,或者有知道的可以留言討論。

而這個輔助工具就是webpack-dev-server,它主要提供兩個功能:一是為靜態(tài)文件提供server服務,二是自動刷新和熱替換(HMR)。所以想實現(xiàn)如Gulp一樣的功能也是可以的,只需要在$ webpack-dev-server后面添加--inline --hot即可。需要注意的是--inline是自動刷新,同時在第二部中的devServer屬性中有一個inline:true需要配置;而--hot是熱替換(詳細了解熱替換了解webpack-dev-server、webpack-dev-server)。

通過對比來看,好像Webpack的webpack-dev-server比Gulp的gulp-server功能要強一些。因為通過上面可以看出webpack-dev-server有兩個大功能:一是為靜態(tài)文件提供server服務,二是自動刷新(自動刷新其實需要兩步:1.修改文件后,文件自動編譯{包括合并壓縮或者語法編譯等},2.刷新瀏覽器請求最新編譯后的文件)和熱替換(HMR);而gulp-server雖然提供了啟動本地server的能力和僅自動刷新瀏覽器的能力,缺少一個文件自動編譯的能力,這需要借助其他模塊實現(xiàn)(上一小節(jié)已介紹,結(jié)合gulp.watch()實時監(jiān)控文件變化,并編譯)。

另外需要注意的是,實際開發(fā)中發(fā)現(xiàn)webpack-dev-server實現(xiàn)自動刷新的時候,并沒有執(zhí)行自動編譯,只是將修改的內(nèi)容合并壓縮等處理后發(fā)送給了瀏覽器,并造成了已經(jīng)編譯的現(xiàn)象,但是通過build/prd/scripts目錄下的bundle.js(合并壓縮后的輸出文件)文件,可以發(fā)現(xiàn)內(nèi)容并沒有編譯(對于Webpack還是不熟悉,好多問題等待解決)。

mock數(shù)據(jù)

在現(xiàn)在前后端分離的思想中,前端和后端耦合度越來越小,現(xiàn)在唯一需要前后端密切聯(lián)系的就是借口的定義和數(shù)據(jù)格式的確定。一般在項目開始前,前端和后端將項目中的接口和數(shù)據(jù)格式全部確定下來(當然項目需求變更就需要臨時確立這些共識了),然后前端就可以自己mock數(shù)據(jù)了。

Gulp實現(xiàn)mock數(shù)據(jù)

Gulp中對mock數(shù)據(jù)的實現(xiàn)使通過NodeJS內(nèi)置的fs模塊和url模塊實現(xiàn)的,因為Gulp本身就是基于NodeJS的。還記得第一小節(jié)“模塊化開發(fā)”中目錄結(jié)構(gòu)中的那個mock目錄嗎?那就是用來儲存.json文件的mock數(shù)據(jù)目錄。

配置Gulp的gulpfile.js文件

//1.引入 fs 和 url 模塊varfs =require('fs');varurl =require('url');//2.重新配置一下上一小節(jié)的servergulp.task('webserver',function(){ gulp.src('./') .pipe(webserver({ host:'localhost', port:80, livereload:true, directoryListing:{ enable:true, path:'./'},//mock數(shù)據(jù)配置middleware:function(req,res,next){varurlObj = url.parse(req.url,true);switch(urlObj.pathname) {case'/pro/getPro': res.setHeader('Content-Type','application/json;charaset=utf-8'); fs.readFile('./mock/list.json',function(err,data){//上面list.json路徑使用相對路徑,絕對路徑前臺無法獲取數(shù)據(jù)res.end(data); });return;case'/web/getUser'://....return; } next(); } }));});

具體來說,就是通過NodeJS攔截http請求,根據(jù)請求URL來模擬后端做出處理后返回不同的數(shù)據(jù)。

Webpack實現(xiàn)mock數(shù)據(jù)

完善中。。。

版本控制

對于版本控制,我們在開發(fā)過程中,也是一個使用比較頻繁的功能,特別是開發(fā)團隊比較大的時候,這個功能就顯得更加重要了。那么Gulp和Webpack是具體怎樣實現(xiàn)的呢?

Gulp實現(xiàn)版本控制

在項目中通過npm安裝gulp-revgulp-rev-collector模塊,前者用于生成文件的MD5碼文件和按MD5碼命名的資源文件,后者是利用MD5碼,對文件名進行替換。

$ npminstallgulp-rev gulp-rev-collector -D

然后在Gulp的配置文件gulpfile.js中進行簡單配置

//1.引入連個模塊varrev =require('gulp-rev');varrevCollector =require('gulp-rev-collector');// 2.版本號控制gulp.task('ver',function(){ gulp.src(cssFiles) .pipe(rev())//產(chǎn)生MD5碼.pipe(gulp.dest('./build/prd/styles/'))//重命名文件.pipe(rev.manifest())//產(chǎn)生版本信息的json文件.pipe(gulp.dest('./build/ver/styles/')); gulp.src(jsFiles) .pipe(rev()) .pipe(gulp.dest('./build/prd/scripts/')) .pipe(rev.manifest()) .pipe(gulp.dest('./build/ver/scripts/')); })//動態(tài)修改html中對css和js文件的修改gulp.task('html',function(){ gulp.src(['./build/ver/**/*','./build/*.html']) .pipe(revCollector()) .pipe(gulp.dest('./build/'));})

Gulp實現(xiàn)版本控制很方便,將這兩個task加入gulp.watch()中,即可實現(xiàn)修改保存文件實時自動修改版本的功能。

Webpack實現(xiàn)版本控制

Webpack中需要版本控制的有css、js文件,不過Webpack的版本控制只實現(xiàn)了將css、js文件添加hash值方式命名的文件方式,修改引用路徑中的文件名需手動實現(xiàn)。

不過實現(xiàn)確實很簡單,只需要將webpack.config.js配置文件中的output.filename和plugins中的輸出文件名稱修改一下即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 在現(xiàn)在的前端開發(fā)中,前后端分離、模塊化開發(fā)、版本控制、文件合并與壓縮、mock數(shù)據(jù)等等一些原本后端的思想開始逐漸滲...
    彬_仔閱讀 25,827評論 21 139
  • 安裝Gulp首先需要安裝Node.js,并在控制臺輸入$ npm install gulp -gMac端需要寫成$...
    LaBaby_閱讀 1,029評論 0 1
  • gulpjs是一個前端構(gòu)建工具,與gruntjs相比,gulpjs無需寫一大堆繁雜的配置參數(shù),API也非常簡單,學...
    依依玖玥閱讀 3,306評論 7 55
  • 最近在學習 Webpack,網(wǎng)上大多數(shù)入門教程都是基于 Webpack 1.x 版本的,我學習 Webpack 的...
    My_Oh_My閱讀 8,344評論 40 247
  • 前言 眾所周知目前比較火的工具就是gulp和webpack,但webpack和gulp卻有所不同,本人兩者的底層研...
    cduyzh閱讀 1,467評論 0 13

友情鏈接更多精彩內(nèi)容