Gulp是前端自動化的工具,但Gulp能用來作什麼javascript
1.搭建web服務器css
2.使用預處理器Sass,Lesshtml
3.壓縮優化,能夠壓縮JS CSS Html 圖片前端
4.自動將更新變化的代碼實時顯示在瀏覽器java
5.前端測試node
......jquery
這些都不是他的所有功能,社區豐富的插件,爲他提供了強大的後盾。git
首先下載gulp(前提默認你安裝好了node,先 npm install,建立一個package.json)es6
npm install gulp -g //全局安裝 npm install gulp --save-dev //本地安裝並加入package.json
接下來安裝各類須要的插件:github
npm install babel-core babel-preset-es2015 browser-sync gulp gulp-autoprefixer gulp-babel gulp-cache gulp-clean gulp-cssnano gulp-htmlmin gulp-if gulp-imagemin gulp-load-plugins gulp-plumber gulp-sass gulp-size gulp-sourcemaps gulp-uglify gulp-useref gulp-rev-append main-bower-files wiredep --save-dev
各類插件按需求本身選擇,各自功能以下:
1.babel-core babel-preset-es2015 gulp-babel 用於解析es6轉換爲es5
2.browser-sync 服務器同步瀏覽
3.gulp-autoprefixer 根據設置瀏覽器版本自動處理瀏覽器前綴
4.gulp-cache 圖片快取,只有更改過得圖片會進行壓縮
5.gulp-clean 清空文件夾
6.gulp-cssnano 壓縮CSS代碼
7.gulp-htmlmin 壓縮html
8.gulp-if 用於判斷
8.gulp-imagemin 圖片壓縮
9.gulp-load-plugins 自動加載(超級有用 省去一大堆代碼)
10.gulp-plumber 管道工 不會讓錯誤爆出來 繼續執行
11.gulp-sass 預編譯Sass
12.gulp-size 統計管道里面內容的大小的,上面是用它來顯示出壓縮先後的大小用來對比用
13.gulp-sourcemaps 當壓縮的JS出錯,能根據這個找到未壓縮代碼的位置 不會一片混亂代碼
14.gulp-uglify JS壓縮
15.gulp-useref 將html引用順序的CSS JS 變成一個文件
例如:<!-- build:js scripts/main.js --> <script src="1.js"></script><script src="2.js"></script><!--endbuild--> 最後變成<script src="main.js"></script>
16.gulp-rev-append html引用添加版本號
17.main-bower-files 找到bower.json裏配置的 overrides 下配置的main下的路徑
18.wiredep 在.html文件會把默認bower.json的配置自動注入到下面標籤中去 <!-- bower:js --> <!-- endbower --> <!-- bower:css--> <!-- endbower -->
接下來是用 bower安裝 Jquery bootstrap-sass
bower init //新建bower.json bower install jquery bootstrap-sass --save-dev //安裝jquery bootstrap
說明:定義一個gulp任務
name: 類型(必填):String 指定任務的名稱(不該該有空格)
deps:類型(可選):StringArray,該任務依賴的任務(執行name任務要先去執行的任務)
gulp.task('A' , function(){ console.log('A') }); gulp.task('B' , ['A'] , function(){ //運行B以前先去運行A console.log('B') });
fn:類型(必填):Function 該任務調用的插件操做
說明:src方法指定須要處理的源文件路徑,返回當前文件流至可用插件
globs: 類型(必填):String/StringArray 須要處理的源文件匹配符路徑
通配符路徑匹配示例:
「src/a.js」:指定具體文件;
「*」:匹配全部文件 例:src/*.js(包含src下的全部js文件);
「**」:匹配0個或多個子文件夾 例:src/**/*.js(包含src的0個或多個子文件夾下的js文件);
「{}」:匹配多個屬性 例:src/{a,b}.js(包含a.js和b.js文件) src/*.{jpg,png,gif}(src下的全部jpg/png/gif文件);
「!」:排除文件 例:!src/a.js(不包含src下的a.js文件);
options:類型(可選):Object 三個屬性 buffer read base
options.buffer:類型:Boolean 默認:true 設置爲false,將返回file.content的流而且不緩衝文件,處理大文件時很是有用;
options.read: 類型:Boolean 默認:true 設置false,將不執行讀取文件操做,返回null;
options.base: 類型:String 設置輸出路徑以某個路徑的某個組成部分爲基礎向後拼接
gulp.src('client/js/**/*.js') .pipe(minify()) .pipe(gulp.dest('build')); // Writes 'build/somedir/somefile.js' gulp.src('client/js/**/*.js', { base: 'client' }) .pipe(minify()) .pipe(gulp.dest('build')); // Writes 'build/js/somedir/somefile.js'
說明:處理完後文件輸出的路徑
path:類型(必填):String or Function 指定文件輸出路徑,或者定義函數返回文件輸出路徑亦可
options: 類型(可選):Object,有2個屬性cwd、mode;
options.cwd: 類型:String 默認:process.cwd():前腳本的工做目錄的路徑 當文件輸出路徑爲相對路徑將會用到;
options.mode: 類型:String 默認:0777 指定被建立文件夾的權限;
說明:watch方法用於監聽文件變化,一被變化就執行指定任務
glob: 須要處理的源文件匹配符路徑。類型(必填):String or StringArray;
opts: 類型(可選):Object 具體參看https://github.com/shama/gaze;
tasks: 類型(必填):StringArray 須要執行的任務的名稱數組;
cb(event): 類型(可選):Function 每一個文件變化執行的回調函數;
|--gulp_test |--app //生產文件路徑 |--fonts |--images
|--1.png |--scripts
|--main.js
|--index.js |--styles
|--main.scss
|--index.css |--index.html |--dist //發佈文件路徑 |--fonts |--images |--scripts |--styles |--index.html |--bower_components |--bootstrap-sass |--jquery |--node_modules |--各類插件 |--package.json |--bower.json
app是咱們新建的目錄和文件夾,其他是按照上面操做自動生成的。
首先在gulp_test下新建.babelrc (用於配置es6 語法) .bowerrc (用於定義bower的路徑)兩個文件
.babelrc
{ "presets": [ "es2015" ] }
.bowerrc
{ "directory": "bower_components" }
設置一下bower.json
{ "name": "gulp_test", "authors": [ "QRL" ], "keywords": [ "bower_components" ], "private": true, "devDependencies": { "jquery": "^3.0.0" }, "overrides": { "bootstrap-sass": { "main": [ "assets/stylesheets/_bootstrap.scss", "assets/fonts/bootstrap/*", "assets/javascripts/bootstrap.js" ] } }, "dependencies": {"bootstrap-sass": "^3.3.6"} }
app下的index.html內容
<!doctype html> <html lang=""> <head> <meta charset="utf-8"> <meta name="description" content=""> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>test gulp webapp</title> <link rel="apple-touch-icon" href="apple-touch-icon.png"> <!-- Place favicon.ico in the root directory --> <!-- build:css styles/index_main.css --> //這個註釋的意思是 將兩個css合併成一個index_main.css 注意順序 <link rel="stylesheet" href="styles/index.css"> <link rel="stylesheet" href="styles/main.css"> <!-- endbuild --> </head> <body> <div class="container"> <div class="header"> <ul class="nav nav-pills pull-right"> <li class="active"><a href="#">Home</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> <h3 class="text-muted">Hello</h3> </div> <div class="jumbotron"> <h1>Hello Gulp!</h1> <p class="lead">Always a pleasure scaffolding your apps.</p> <p><a class="btn btn-lg btn-success" href="#">Splendid!</a></p> </div> <div class="row marketing"> <div class="col-lg-6"> <h4>HTML5 Boilerplate</h4> <p>HTML5 Boilerplate is a professional front-end template for building fast, robust, and adaptable web apps or sites.</p> <h4>Sass</h4> <p>Sass is the most mature, stable, and powerful professional grade CSS extension language in the world.</p> <h4>Bootstrap</h4> <p>Sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development.</p> <h4>Modernizr</h4> <p>Modernizr is an open-source JavaScript library that helps you build the next generation of HTML5 and CSS3-powered websites.</p> </div> </div> <div class="footer"> <p>♥ from the Yeoman team</p> </div> </div> <!-- Google Analytics: change UA-XXXXX-X to be your site's ID. --> <script> (function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]= function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date; e=o.createElement(i);r=o.getElementsByTagName(i)[0]; e.src='https://www.google-analytics.com/analytics.js'; r.parentNode.insertBefore(e,r)}(window,document,'script','ga')); ga('create','UA-XXXXX-X');ga('send','pageview'); </script> <!-- build:js scripts/vendor.js --> //將如下js合併成一個,並改名爲vendor.js <script src="/bower_components/jquery/dist/jquery.js"></script> <!-- endbuild --> <!-- build:js scripts/plugins.js --> //注意一下這裏 待會會按照順序變成一個plugins.js文件 //是否遇到過這麼多的插件引用,Ctrl+c Ctrl+v 還要細緻的修改 請留意 wiredep 任務 留意下面的<!-- bower:js --><!-- endbower -->註釋,這可不是隨隨便便的註釋 <!-- bower:js --> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/affix.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/alert.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/modal.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/transition.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/button.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/popover.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/carousel.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/scrollspy.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/collapse.js"></script> <script src="/bower_components/bootstrap-sass/assets/javascripts/bootstrap/tab.js"></script> <!-- endbower --> <!-- endbuild --> <!-- build:js scripts/index_main.js --> <script src="scripts/index.js"></script> <script src="scripts/main.js"></script> <!-- endbuild --> </body> </html>
接下來最重要了,一樣在gulp_test下新建gulpfile.babel.js(由於這裏使用es6,因此須要將本來的gulpfile.js 改名爲 gulpfile.babel.js )
打開gulpfile.babel.js,開始操做
首先寫進如下代碼:
import gulp from 'gulp'; //引入gulp import gulpLoadPlugins from 'gulp-load-plugins'; //自動加載插件 省去一個一個require進來 import browserSync from 'browser-sync'; //瀏覽器同步 import {stream as wiredep} from 'wiredep'; //把bower 下載的文件引入到html文件中 const $ = gulpLoadPlugins(); const reload = browserSync.reload;
接下來
先嚐試刪除dist文件夾 終端運行 "gulp clean"
gulp.task('clean' , function(){ return gulp.src([ 'dist', //刪除dist整個文件夾 'dist/test/**/*', //刪除dist下的test寫任意子文件夾裏的文件 '!package.json' //不刪除package.json文件 ] ).pipe($.clean()); });
預編譯Sass
gulp.task('styles' , ()=>{ return gulp.src('app/styles/*.scss') //指明源文件路徑 讀取其數據流 .pipe($.plumber()) //替換錯誤的pipe方法 使數據流正常運行 .pipe($.sourcemaps.init()) //壓縮環境出現錯誤能找到未壓縮的錯誤來源 .pipe($.sass.sync({ //預編譯sass outputStyle: 'expanded', //CSS編譯後的方式 precision: 10,//保留小數點後幾位 includePaths: ['.'] }).on('error', $.sass.logError)) .pipe($.autoprefixer({browsers:['> 1%', 'last 2 versions', 'Firefox ESR']})) //自動匹配瀏覽器支持的後綴 .pipe($.sourcemaps.write('.')) //map文件命名 .pipe(gulp.dest('dist/styles')) //指定輸出路徑 });
../dist/styles目錄下會生成 對應的 *.css 和 *.css.map
轉化es6的JS
gulp.task('scripts' , ()=>{ return gulp.src('app/scripts/**/*.js') .pipe($.plumber()) .pipe($.sourcemaps.init()) .pipe($.babel()) //靠這個插件編譯 .pipe($.sourcemaps.write('.')) .pipe(gulp.dest('dist/scripts')); });
../dist/scripts目錄下會生成 對應的 *.js 和 *.js.map
壓縮圖片
gulp.task('images',()=>{ return gulp.src('app/images/**/*') .pipe ($.cache ($.imagemin ({ //使用cache只壓縮改變的圖片 optimizationLevel: 3, //壓縮級別 progressive: true, interlaced: true}) )).pipe (gulp.dest ('dist/images')); });
經過對比圖片大小,能夠看出壓縮了多少
引用字體文件
gulp.task('fonts', () => { return gulp.src(require('main-bower-files')('**/*. {eot,svg,ttf,woff,woff2}', function (err) {}) //main-bower-files會從bower.json文件裏尋找定義好的主要文件路徑 .concat('app/fonts/**/*')) //將bootstrap-sass的fonts和app下咱們本身選用的fonts合併起來
.pipe(gulp.dest('dist/fonts')); });
../dist/fonts目錄下會生成 對應的文件
接下來是最最有用的操做,將CSS合併壓縮,JS合併壓縮,html壓縮,加上時間戳避免緩存
gulp.task('html', ['styles' , 'scripts'], ()=>{ //先執行styles scripts任務 var version = (new Date).valueOf() + ''; var options = { removeComments: false,//清除HTML註釋 collapseWhitespace: true,//壓縮HTML collapseBooleanAttributes: false,//省略布爾屬性的值 <input checked="true"/> ==> <input /> removeEmptyAttributes: false,//刪除全部空格做屬性值 <input id="" /> ==> <input /> removeScriptTypeAttributes: false,//刪除<script>的type="text/javascript" removeStyleLinkTypeAttributes: false,//刪除<style>和<link>的type="text/css" minifyJS: false,//壓縮頁面裏的JS minifyCSS: false//壓縮頁面裏的CSS }; return gulp.src('app/*.html') .pipe($.plumber()) .pipe($.useref({searchPath: ['app', '.']})) //將頁面上 <!--endbuild--> 根據上下順序合併 .pipe($.if('*.js', $.uglify())) .pipe($.if('*.css', $.cssnano())) .pipe($.if('*.html', $.htmlmin(options))) .pipe($.replace('.js"></script>' , '.js?v=' + version + '"></script>')) //這種方法比較不成熟 每一次的任務都會改變,無論文件是否被修改 .pipe($.replace('.css">' , '.css?v=' + version + '">')) .pipe(gulp.dest('dist')); });
查看dist/index.html , 是否還記得
是否是瞬間被嚇到了,不再用一個個壓縮JS文件,不再要擔憂緩存這種問題,不再用由於頁面的臃腫而煩惱,幾行配置,一鍵搞定。
優化上面的引用加版本號: 使用插件 gulp-rev-append
import rev from 'gulp-rev-append' gulp.task('html', ['styles' , 'scripts'], ()=>{ //先執行styles scripts任務 return gulp.src('app/*.html') .pipe($.plumber()) .pipe($.useref({searchPath: ['app', '.']})) //將頁面上 <!--endbuild--> 根據上下順序合併 .pipe($.if('*.js', $.uglify())) .pipe($.if('*.css', $.cssnano())) .pipe(rev()) //爲引用添加版本號 .pipe($.if('*.html', $.htmlmin(options))) .pipe(gulp.dest('dist')); });
同時須要在index.html的引用後面加上 ?rev=@@hash
<script src="scripts/index.js?rev=@@hash"></script>
添加後的效果
<script src="scripts/index.js?rev=200c90563a2be0adfd8c03f8e4162df7"></script>
最重要是隻要app/index.js裏不發生改變,這個版本號就不會變化。
接下來再學一個黑魔法——本地建站和自動刷新
gulp.task('serve', ['styles','scripts','fonts'] , ()=>{ browserSync({ notify : false, port:9000, //端口號 server:{ baseDir:['dist'], //肯定根目錄 routes:{ '/bower_components': 'bower_components' } } }); gulp.watch([ //監測文件變化 實行從新加載 'app/*.html', 'app/images/**/*' ]).on('change',reload); gulp.watch('app/styles/**/*.scss' , ['styles']); //監測變化 執行styles任務 gulp.watch('app/scripts/**/*.js' , ['scripts']); gulp.watch('app/fonts/**/*' , ['fonts']); gulp.watch('bower.json' , ['wiredep','fonts']); });
終端一運行gulp serve 瀏覽器直接打開dist下的index.html,只要一修改監測的文件,瀏覽器當即刷新。
首先在app下新建一個 index_test.html
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <!--bower:css--> <!--endbower--> </head> <body> <p>Hellp wirdep</p> <a href="index.html">dianwo</a> <!-- bower:js --> <!-- endbower --> </body> </html>
而後在gulpfile.babel.js中寫上任務
gulp.task('wiredep_test' , function(){ gulp.src('./app/index_test.html') .pipe(wiredep({ optional:'configuration', goes : 'here', ignorePath:/^(\.\.\/)+/ //生成的路徑忽略../ })) .pipe(gulp.dest('./app')) //輸出到原路徑 });
而後運行一下,index_test.html 本來的<!-- bower:js --> <!-- endbower --> 變成
<!-- bower:js --> <script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/bootstrap-sass/assets/javascripts/bootstrap.js"></script> <!-- endbower -->
你或許很疑惑這是根據什麼自動查找生成的啊?由於沒有中文文檔,本身摸索後是在bower.json裏面配置的,review一下剛纔的bower.json
"devDependencies": { "jquery": "^3.0.0" }, "overrides": { "bootstrap-sass": { "main": [ "assets/stylesheets/_bootstrap.scss", "assets/fonts/bootstrap/*", "assets/javascripts/bootstrap.js" ] } }, "dependencies": {"bootstrap-sass": "^3.3.6"}
根據以上三個根據,起最大做用的是overrides,最終會根據這些進行生成。
能夠稍微測試一下,將bower.json作點小修改 ,增長jquery的選擇
"overrides": { "bootstrap-sass": { "main": [ "assets/stylesheets/_bootstrap.scss", "assets/fonts/bootstrap/*", "assets/javascripts/bootstrap.js" ] }, "jquery" :{ "main":[ "src/*.js" ] } }
回頭看看index_test.html 剛纔的jquery.js 被src下的js代替
<!-- bower:js --> <script src="bower_components/modernizr/modernizr.js"></script> <script src="bower_components/jquery/src/ajax.js"></script> <script src="bower_components/jquery/src/attributes.js"></script> <script src="bower_components/jquery/src/callbacks.js"></script> <script src="bower_components/jquery/src/core.js"></script> <script src="bower_components/jquery/src/css.js"></script> <script src="bower_components/jquery/src/data.js"></script> <script src="bower_components/jquery/src/deferred.js"></script> <script src="bower_components/jquery/src/deprecated.js"></script> <script src="bower_components/jquery/src/dimensions.js"></script> <script src="bower_components/jquery/src/effects.js"></script> <script src="bower_components/jquery/src/event.js"></script> <script src="bower_components/jquery/src/jquery.js"></script> <script src="bower_components/jquery/src/manipulation.js"></script> <script src="bower_components/jquery/src/offset.js"></script> <script src="bower_components/jquery/src/queue.js"></script> <script src="bower_components/jquery/src/selector-native.js"></script> <script src="bower_components/jquery/src/selector-sizzle.js"></script> <script src="bower_components/jquery/src/selector.js"></script> <script src="bower_components/jquery/src/serialize.js"></script> <script src="bower_components/jquery/src/traversing.js"></script> <script src="bower_components/jquery/src/wrap.js"></script> <script src="bower_components/bootstrap-sass/assets/javascripts/bootstrap.js"></script> <!-- endbower -->
最後一步,就結束了
gulp.task('build' , ['html' , 'images' , 'fonts'],()=>{ return gulp.src('dist/**/*') .pipe($.size({title:'build' , gzip:true})); }); gulp.task('default' ,['clean'],()=>{ gulp.start('build'); });
這就是單獨運行 gulp 就會執行default 而後執行咱們想要的操做,同時能夠根據size看到壓縮後節省的空間。
感謝您堅持看完,一步步跟着作,你會發現gulp原來辣麼容易,前端自動化工具辣麼方便。
對於老項目也能夠這樣一步一步改造哦!
聲明:上述的 2、get Gulp的簡單語法 摘抄於 Gulp中文網的API文檔 。其他內容均屬樓主一點一滴碼出來的。