Gulp 自動化你的前端
來自: http://www.sheyilin.cn/2016/02/gulp_introduce/
“1. 我為什么使用grunt; 2. 我為何放棄grunt轉投 gulp ; 3. 我為何放棄 gulp 與grunt,轉投 npm scripts; 4. 我為何放棄前端” ——司徒正美
前端(段子)界的發展突飛猛進,總感覺隨時會跟不上技術潮流(其實我已經被甩開了一條街,so sad
選擇在這樣一個時機發布一篇 gulp 教程并不是我的初衷,第一次用 gulp 是在一年前,而這篇帖子在草稿箱里躺了一個多月,再不發出來說不定就過時了。
當我在用 gulp 時我用它做什么?
- 編譯 sass
- 合并優化壓縮 css
- 校驗壓縮 js
- 優化圖片
- 添加文件指紋(md5)
- 組件化頭部底部(include html)
- 實時自動刷新…
總之,gulp是前端開發過程中對代碼進行自動化構建的利器。它不僅能對資源進行優化,而且在開發過程中能夠通過配置自動完成很多重復的任務,讓我們可以專注于代碼,提高工作效率。
然而總所周知的原因,國內到 npm 服務器的連接很不穩定,如果你有V了個PN大可不必擔心,也可通過設置 npm 代理服務器的方式訪問:
// 設置代理 npm config set proxy="http://127.0.0.1:1080" // 刪除代理 npm config delete proxy
推薦一個簡單的方案: 使用淘寶 npm 鏡像
“這是一個完整 npmjs.org 鏡像,你可以用此代替官方版本(只讀),同步頻率目前為 10分鐘 一次以保證盡量與官方服務同步。”—— 淘寶團隊點贊
npm config set registry="https://registry.npm.taobao.org"
接下來開始 gulp 教程:
準備工作: 安裝 node.js (推薦 TLS 版),并重啟系統。
1. 全局安裝 gulp
npm install gulp -g
2. 目錄結構:
└── src/ 源碼目錄
├── build/ .html 組件
├── sass/ .scss .sass 文件
├── css/ .css 文件
├── js/ .js 文件
└── img/ 圖片
3. 關于 package.json
可以使用 npm init 配置,推薦直接寫入初始內容:
{ "name": "gulp-build", "version": "1.0.0", "description": "Gulp.js", "private": true }
對于完整的 package.json (比如別人的開源項目), 只需對整個項目執行 npm install 即可安裝 package.json 文件中聲明的所有插件模塊。
4. 給項目目錄安裝 gulp
npm install gulp --save-dev
—save-dev 這個參數會將插件信息自動更新到 package.json 里,其中的 devDependencies 屬性會隨插件依賴的安裝卸載而改變。
PS. Windows 7及以上,按住 Shift 再右鍵,選擇在此處打開命令窗口。免去 cd 命令定位目錄的煩惱。
5. 給項目目錄安裝常用的插件
PS.可與上一步同時進行
npm install gulp-sass gulp-cached gulp-uglify gulp-rename gulp-concat gulp-notify gulp-filter gulp-jshint gulp-rev-append gulp-cssnano gulp-imagemin browser-sync gulp-file-include gulp-autoprefixer del --save-dev
插件將在配置文件里介紹,更多用法請參見相應的 GitHub 主頁。
以上兩個安裝操作將會在項目目錄下生成 node_modules 文件夾,相應的插件都在這里。
Windows 用戶請注意,此文件夾可能 無法刪除 無法復制 無法移動 ,會出現諸如“ 包含名稱過長且無法放入回收站 ”,“ 源文件名長度大于文件系統支持的長度。請嘗試將其移動到具有較短路徑名稱的位置 ” 等等問題。使用一個簡單的方式即可刪除,使用 WinRAR “添加到壓縮文件”,勾選壓縮選項里的 “壓縮后刪除源文件” ,確定之后即可刪除。
6. API
別看我,看它: http://www.gulpjs.com.cn/docs/api/
7. 代碼示例
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>嘿嘿嘿</title> <link href="css/m.base.css?rev=@@hash" rel="stylesheet" type="text/css" /> <link href="css/jquery.fullPage.css?rev=@@hash" rel="stylesheet" type="text/css" /> <link href="css/mobile.css?rev=@@hash" rel="stylesheet" type="text/css" /> </head> <body>
<!-- common js --> <script type="text/javascript" src="js/jquery-2.1.4.min.js"></script> <script type="text/javascript" src="js/main.js?rev=@@hash"></script> <script> </script> </body> </html>
代碼中, ?rev=@@hash 是 gulp-rev-append 插件的指紋標識。
@@include('build/header.html')<div class="wrap">內容</div>
@@include('build/footer.html')</pre>
代碼中 @@include(‘build/header.html’) 可以插入 html 文件。
8. 我的 gulpfile.js ,配置及說明
/*!
- gulp
- $ npm install gulp gulp-sass gulp-cached gulp-uglify gulp-rename gulp-concat gulp-notify gulp-filter gulp-jshint gulp-rev-append gulp-cssnano gulp-imagemin browser-sync gulp-file-include gulp-autoprefixer del --save-dev */
// Load plugins var gulp = require('gulp'), // 必須先引入gulp插件 del = require('del'), // 文件刪除 sass = require('gulp-sass'), // sass 編譯 cached = require('gulp-cached'), // 緩存當前任務中的文件,只讓已修改的文件通過管道 uglify = require('gulp-uglify'), // js 壓縮 rename = require('gulp-rename'), // 重命名 concat = require('gulp-concat'), // 合并文件 notify = require('gulp-notify'), // 相當于 console.log() filter = require('gulp-filter'), // 過濾篩選指定文件 jshint = require('gulp-jshint'), // js 語法校驗 rev = require('gulp-rev-append'), // 插入文件指紋(MD5) cssnano = require('gulp-cssnano'), // CSS 壓縮 imagemin = require('gulp-imagemin'), // 圖片優化 browserSync = require('browser-sync'), // 保存自動刷新 fileinclude = require('gulp-file-include'), // 可以 include html 文件 autoprefixer = require('gulp-autoprefixer'); // 添加 CSS 瀏覽器前綴
// sass gulp.task('sass', function() { return gulp.src('src/sass/*/.scss') // 傳入 sass 目錄及子目錄下的所有 .scss 文件生成文件流通過管道 .pipe(cached('sass')) // 緩存傳入文件,只讓已修改的文件通過管道(第一次執行是全部通過,因為還沒有記錄緩存) .pipe(sass({outputStyle: 'expanded'})) // 編譯 sass 并設置輸出格式 .pipe(autoprefixer('last 5 version')) // 添加 CSS 瀏覽器前綴,兼容最新的5個版本 .pipe(gulp.dest('dist/css')) // 輸出到 dist/css 目錄下(不影響此時管道里的文件流) .pipe(rename({suffix: '.min'})) // 對管道里的文件流添加 .min 的重命名 .pipe(cssnano()) // 壓縮 CSS .pipe(gulp.dest('dist/css')) // 輸出到 dist/css 目錄下,此時每個文件都有壓縮(.min.css)和未壓縮(.css)兩個版本 });
// css (拷貝 .min.css,常規 CSS 則輸出壓縮與未壓縮兩個版本) gulp.task('css', function() { return gulp.src('src/css/**/.css') .pipe(cached('css')) .pipe(gulp.dest('dist/css')) // 把管道里的所有文件輸出到 dist/css 目錄 .pipe(filter(['', '!.min.css'])) // 篩選出管道中的非 *.min.css 文件 .pipe(autoprefixer('last 5 version')) .pipe(gulp.dest('dist/css')) // 把處理過的 css 輸出到 dist/css 目錄 .pipe(rename({suffix: '.min'})) .pipe(cssnano()) .pipe(gulp.dest('dist/css')) });
// styleReload (結合 watch 任務,無刷新CSS注入) gulp.task('styleReload', ['sass', 'css'], function() { return gulp.src(['dist/css/*/.css']) .pipe(cached('style')) .pipe(browserSync.reload({stream: true})); // 使用無刷新 browserSync 注入 CSS });
// script (拷貝 .min.js,常規 js 則輸出壓縮與未壓縮兩個版本) gulp.task('script', function() { return gulp.src(['src/js/**/.js']) .pipe(cached('script')) .pipe(gulp.dest('dist/js')) .pipe(filter(['', '!.min.js'])) // 篩選出管道中的非 *.min.js 文件 // .pipe(jshint('.jshintrc')) // .pipe(jshint.reporter('default')) // .pipe(concat('main.js')) // .pipe(gulp.dest('dist/js')) .pipe(rename({suffix: '.min'})) .pipe(uglify()) .pipe(gulp.dest('dist/js')) });
// image gulp.task('image', function() { return gulp.src('src/img/*/.{jpg,jpeg,png,gif}') .pipe(cached('image')) .pipe(imagemin({optimizationLevel: 3, progressive: true, interlaced: true, multipass: true})) // 取值范圍:0-7(優化等級),是否無損壓縮jpg圖片,是否隔行掃描gif進行渲染,是否多次優化svg直到完全優化 .pipe(gulp.dest('dist/img')) });
// html 編譯 HTML 文件 gulp.task('html', function () { gulp.src('src/*.html') .pipe(fileinclude()) // include html .pipe(rev()) // 生成并插入 MD5 .pipe(gulp.dest('dist/')); });
// clean 清空 dist 目錄 gulp.task('clean', function() { return del('dist/*/'); });
// build 需要插入資源指紋(MD5),html 最后執行 gulp.task('build', ['sass', 'css', 'script', 'image'], function () { gulp.start('html'); });
// default 默認任務,依賴清空任務 gulp.task('default', ['clean'], function() { gulp.start('build'); });
// watch 開啟本地服務器并監聽 gulp.task('watch', function() { browserSync.init({ server: { baseDir: 'dist' // 在 dist 目錄下啟動本地服務器環境,自動啟動默認瀏覽器 } });
// 監控 SASS 文件,有變動則執行CSS注入 gulp.watch('src/sass//*.scss', ['styleReload']); // 監控 CSS 文件,有變動則執行CSS注入 gulp.watch('src/css//.css', ['styleReload']); // 監控 js 文件,有變動則執行 script 任務 gulp.watch('src/js/**/.js', ['script']); // 監控圖片文件,有變動則執行 image 任務 gulp.watch('src/img//*', ['image']); // 監控 html 文件,有變動則執行 html 任務 gulp.watch('src//.html', ['html']); // 監控 dist 目錄下除 css 目錄以外的變動(如js,圖片等),則自動刷新頁面 gulp.watch(['dist/**/', '!dist/css/*/']).on('change', browserSync.reload);
});</pre>
9. 使用 gulp 的方法
gulp taskname // 如 gulp sass,不指定 taskname 則默認執行 default 任務
趕在四年一遇的2月29號,匆忙發表。