基於gulp的前端自動化方案

遊魂Andy發表於2018-10-24

前言

​ 最近幾年前端技術發展日新月異,特別是單頁應用的普及。元件化、工程化、自動化成了前端發展的趨勢。webpack已經成為了前端打包構建的主流,但是一些老古董的專案還是存在的,也有優化的必要,正好公司的老專案需要優化,不多說拿gulp實踐一下。

本文需要安裝node(自行安裝),並瞭解過gulp入門。gulp指令碼下載:github.com/youhunwl/gu… 歡迎star。

實踐

建立專案目錄

首先初始化npm依賴項與基本資訊,使用命令npm init一直回車,生成package.json檔案,也可以直接去上邊github倉庫目錄下載。

你的專案目錄關係到你的gulp指令碼里的任務路徑,我指令碼里寫的是匹配所有的目錄和檔案。我簡單舉個例子:這裡js/common裡的js檔案也會被處理。如果只想處理特定目錄的檔案,請修改任務裡的路徑。

demo/
├── css/
│   ├── index.css
├── js/
│   ├── common/
│   │       └─ common.js
│   ├── index.js
├── img/
│   ├── logo.png
└── index.html
複製程式碼

安裝所需依賴

安裝gulp所需要的模組,這裡直接列舉我的package.json檔案內容

{
  "name": "demo",
  "version": "0.0.0",
  "private": true,
  "dependencies": {},
  "devDependencies": {
    "gulp": "^3.9.1",
    "gulp-autoprefixer": "^3.1.1",
    "gulp-cache": "^1.0.2",
    "gulp-clean-css": "^3.10.0",
    "gulp-htmlclean": "^2.7.15",
    "gulp-htmlmin": "^3.0.0",
    "gulp-if": "^2.0.2",
    "gulp-imagemin": "^4.1.0",
    "gulp-minify-css": "^1.2.4",
    "gulp-notify": "^3.0.0",
    "gulp-path": "^3.0.3",
    "gulp-rev-append": "^0.1.8",
    "gulp-sequence": "^0.4.6",
    "gulp-sourcemaps": "^2.6.4",
    "gulp-uglify": "^2.0.0",
    "uglify-js": "^3.3.9"
  }
}

複製程式碼

編寫gulp指令碼

新建 gulpfile.js檔案,並引入所需模組,這裡我把路徑統一寫在PATHS中。具體關於路徑的寫法,可以去看gulp官網的api:www.gulpjs.com.cn/docs/api/

gulp-minify-css這個官網提示已經棄用,改用gulp-clean-css,這裡保留只是為了告訴大家,效果一樣,使用者一致,為了保證專案不出問題,還是用最新的吧。

'use strict';
var gulp = require('gulp'),
    minifycss = require('gulp-minify-css'),//壓縮css 已棄用
    cleancss = require('gulp-clean-css'),//壓縮css
    imagemin = require('gulp-imagemin'),//壓縮圖片
    autoprefixer = require('gulp-autoprefixer'),//處理瀏覽器字首
    uglify = require('gulp-uglify'),//壓縮js
    sourcemaps = require('gulp-sourcemaps'),//生成 sourcemap
    gulpif = require('gulp-if'),//條件判斷
    notify = require('gulp-notify'),//處理報錯
    cache = require('gulp-cache'),//只壓縮修改的圖片
    htmlclean = require('gulp-htmlclean'),// 精簡html
	htmlmin = require('gulp-htmlmin'),//壓縮html
    rev = require('gulp-rev-append'),//增加版本號
    sequence = require('gulp-sequence'),//同步執行任務
    PATHS = {
    ROOT: './',
    DEST: './dist/',
    HTML: '**/*.{html,htm}',
    CSS: '**/*.css',
    IMG: '**/*.{png,jpg,gif,ico}',
    JS: '**/*.js'
}
複製程式碼

壓縮處理css

這裡需要排除node_modules資料夾和生成構建的後的目錄/dist/及它們的子目錄,直接 !後面跟要排除的目錄就行了。

gulp.task('minify-css', function () {
    return gulp.src([PATHS.CSS,'!./dist/**', '!./node_modules/**'])
     .pipe(sourcemaps.init())
     .pipe(autoprefixer({
        browsers: ['last 10 versions', 'Firefox >= 20', 'Opera >= 36', 'ie >= 9', 'Android >= 4.0', ],
        cascade: true, //是否美化格式
        remove: false //是否刪除不必要的字首
    }))
     .pipe(cleancss({
        keepSpecialComments: '*' //保留所有特殊字首
    }))
     .pipe(sourcemaps.write('.'))
     .pipe(gulp.dest(PATHS.DEST))
     .pipe(notify({ message: 'css minify complete' }));
});
複製程式碼

有些引用的css或者js不需要壓縮,比如jQuery',Bootstrap,也或者是公司內部的公共庫 .min.{css,js}等等。

這裡我們們就用到gulp-if了,去排除min.css

var conditionCss = function (f) {
    if (f.path.endsWith('.min.css')) {
        return false;
    }
    return true;
};
複製程式碼

再修改下處理css的操作

.pipe(gulpif(conditionCss, cleancss({
    keepSpecialComments: '*' //保留所有特殊字首
})))
複製程式碼

壓縮處理js

同理排除下 min.js ,這裡還要注意記得把 gulp指令碼也排除不處理。

gulp.task('minify-js', function () {
    return gulp.src([PATHS.JS, '!./dist/**', '!./node_modules/**', '!gulpfile.js'])
     .pipe(sourcemaps.init())
     .pipe(gulpif(conditionJs, uglify()))
     .pipe(sourcemaps.write('.'))
     .pipe(gulp.dest(PATHS.DEST))
     .pipe(notify({ message: 'js minify complete' }));
});
複製程式碼

壓縮處理 img

gulp.task('minify-img', function () {
    return gulp.src([PATHS.IMG,'!./dist/**', '!./node_modules/**'])
        .pipe(cache(imagemin()))
        .pipe(gulp.dest(PATHS.DEST));
});
複製程式碼

壓縮處理HTML

gulp.task('minify-html', function () {
    return gulp.src(PATHS.DEST+PATHS.HTML)
        .pipe(htmlclean())
        .pipe(htmlmin({
        removeComments: true, //清除HTML註釋
        collapseWhitespace: true, //壓縮HTML
        minifyJS: true, //壓縮頁面JS
        minifyCSS: true, //壓縮頁面CSS
        minifyURLs: true
    }))
        .pipe(gulp.dest(PATHS.DEST));
});
複製程式碼

增加版本號

gulp.task('rev', function () {
    return gulp.src([PATHS.HTML,'!./dist/**', '!./node_modules/**'])
        .pipe(rev())
        .pipe(gulp.dest(PATHS.DEST));
});
複製程式碼

同步執行task

因為gulp所有的任務都是非同步完成的,在有時候我們需要同步執行任務,比如:先編譯less,在對編譯好的css進行壓縮,這個時候非同步就有問題了。

gulp.task('deploy', sequence(['minify-css', 'minify-js'], 'minify-img', 'rev', 'minify-html'));
複製程式碼

執行gulp所有任務

這裡建立一個名為default 的任務,執行上面的deploy任務

gulp.task('default', ['deploy'], function (e) {
    console.log("[complete] Please continue to operate");
})
複製程式碼

部署

在終端中輸入 gulp或者gulp default執行構建,即可在我們設定的產出目錄裡看到我們壓縮處理後的程式碼。

基於gulp的前端自動化方案

至此,一個簡單的gulp指令碼就寫的差不多了,麻雀雖小五臟俱全。如果大家有什麼好的建議歡迎交流。

相關文章