Gulp快速入門

Gulp使用node.js流,由于它不需要將臨時文件/文件夾寫入磁盤,構(gòu)建起來速度更快。Gulp允許你輸入你的源文件,通過一堆插件管理它們,并在最后得到一個輸出,而Grunt則為每一個插件配置一個輸入和輸出。下面我們先看看Grunt和Gulp的一個基本使用Sass構(gòu)建的樣子:

Grunt:

sass: {
  dist: {
    options: {
      style: 'expanded'
    },
    files: {
      'dist/assets/css/main.css': 'src/styles/main.scss',
    }
  }
},

autoprefixer: {
  dist: {
    options: {
      browsers: [
        'last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'
      ]
    },
    src: 'dist/assets/css/main.css',
    dest: 'dist/assets/css/main.css'
  }
},

grunt.registerTask('styles', ['sass', 'autoprefixer']);

Grunt要求每個插件單獨配置,指定每個插件的源和目標路徑。 例如,我們輸入一個文件到Sass插件,然后保存輸出。 然后我們需要配置Autoprefixer來輸入Sass的輸出,然后輸出另一個文件。 讓我們來看看與gulp相同的配置:

Gulp:

gulp.task('sass', function() {
  return sass('src/styles/main.scss', { style: 'expanded' })
    .pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
    .pipe(gulp.dest('dist/assets/css'))
});

我們只用輸入一個文件,它被Sass插件修改后,傳遞給Autoprefixer插件并修改,然后我們得到一個文件。這個構(gòu)建過程更快,因為我們沒有讀取和寫入不必要的文件。

下面我們創(chuàng)建一個基本的gulp文件,其中包含一些核心任務(wù)。

$ npm install gulp -g

或者

// 進到你的項目文件比如gulp-demo
// cd gulp-demo
$ npm install gulp --save-dev

這會將gulp本地安裝到項目中,并將其保存到package.json文件中的devDependencies。

安裝gulp插件

$ npm install gulp-ruby-sass gulp-autoprefixer gulp-cssnano gulp-jshint gulp-concat gulp-uglify gulp-imagemin gulp-notify gulp-rename gulp-connect gulp-cache del --save-dev

加載插件

首先,創(chuàng)建一個gulpfile.js文件

touch gulpfile.js

然后添加以下內(nèi)容

var gulp = require('gulp'),
  sass = require('gulp-ruby-sass'),
  autoprefixer = require('gulp-autoprefixer'),
  cssnano = require('gulp-cssnano'),
  jshint = require('gulp-jshint'),
  uglify = require('gulp-uglify'),
  imagemin = require('gulp-imagemin'),
  rename = require('gulp-rename'),
  concat = require('gulp-concat'),
  notify = require('gulp-notify'),
  cache = require('gulp-cache'),
  del = require('del'),
  connect = require('gulp-connect');//livereload

Gulp插件與Grunt插件略有不同 - 它們被設(shè)計用來完成一件事,一件事。比如Grunt的imagemin使用緩存來避免重新壓縮已經(jīng)被壓縮的圖像。而Gulp可以用一個緩存插件完成,也可以用來緩存其他的東西。 這為構(gòu)建過程增加了額外的靈活性。

我們可以像Grunt一樣自動加載所有安裝的插件,但為了本文的目的,我們將堅持手動方法。

創(chuàng)建任務(wù)

實時更新

gulp.task('connect', function () {
  connect.server({
    livereload: true
  });
});

編譯Sass,自動處理前綴,壓縮CSS

gulp.task('styles', function() {
  return sass('src/styles/main.scss', { style: 'expanded' })
    .pipe(autoprefixer('last 2 version'))
    .pipe(gulp.dest('dist/assets/css'))
    .pipe(rename({suffix: '.min'}))
    .pipe(cssnano())
    .pipe(gulp.dest('dist/assets/css'))
    .pipe(notify({ message: 'Styles task complete' }))
    .pipe(connect.reload())
});

這里先稍作解釋

gulp.task('styles', function() { ... )};

gulp.task這是用來創(chuàng)建任務(wù)的API。 你可以在終端單獨執(zhí)行命令$ gulp styles

return sass('src/styles/main.scss', { style: 'expanded' })

這是我們定義源文件并傳遞任何選項的新gulp-ruby-sass API。對于許多其他的插件,你可以使用我們稍后在這篇文章中使用的gulp.src API(return gulp.src(...))。它也可以是glob模式,比如/*/.scss來匹配多個文件。 通過返回流使它異步,確保任務(wù)完全完成,然后我們收到通知說完成。

.pipe(autoprefixer('last 2 version'))

我們使用.pipe()將源文件傳送到插件中。

.pipe(gulp.dest('dist/assets/css'));

gulp.dest API是我們設(shè)置目標路徑的地方。一個任務(wù)可以有多個目標,一個輸出擴展版本,另一個輸出minifed版本。 這在上面的樣式任務(wù)中得到了證明。

校驗語法, 合并文件, 壓縮JS

gulp.task('scripts', function() {
  return gulp.src('src/scripts/**/*.js')
    .pipe(jshint('.jshintrc'))
    .pipe(jshint.reporter('default'))
    .pipe(concat('main.js'))
    .pipe(gulp.dest('dist/assets/js'))
    .pipe(rename({suffix: '.min'}))
    .pipe(uglify())
    .pipe(gulp.dest('dist/assets/js'))
    .pipe(notify({ message: 'Scripts task complete' }))
    .pipe(connect.reload())
});

這里我們使用gulp.src API來指定我們的輸入文件。

定義Html任務(wù)

gulp.task('html', function () {
  return gulp.src('src/*.html')
    .pipe(gulp.dest('dist'))
    .pipe(connect.reload());
});

壓縮圖片

gulp.task('images', function() {
  return gulp.src('src/images/**/*')
    .pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
    .pipe(gulp.dest('dist/assets/img'))
    .pipe(notify({ message: 'Images task complete' }))
    .pipe(connect.reload())
});

清理

在部署之前,清理目標文件夾并重建文件是一個好習慣 - 可以防止源文件中已經(jīng)刪除的留在目標文件夾中:

gulp.task('clean', function() {
  return del(['dist/styles', 'dist/scripts', 'dist/images', 'dist/html']);
});

我們不需要在這里使用gulp插件,因為我們可以直接在gulp中利用Node模塊。我們使用return來確保任務(wù)在退出之前完成。

監(jiān)控

要監(jiān)控我們的文件并在更改時執(zhí)行必要的任務(wù),我們首先需要創(chuàng)建一個新任務(wù),然后使用gulp.watch API開始監(jiān)控文件:

gulp.task('watch', function() {
  // 監(jiān)控 .scss 文件
  gulp.watch('src/styles/**/*.scss', ['styles']);
  // 監(jiān)控 .js 文件
  gulp.watch('src/scripts/**/*.js', ['scripts']);
  // 監(jiān)控圖片文件
  gulp.watch('src/images/**/*', ['images']);
  // 監(jiān)控 .html文件
  gulp.watch('src/*.html', ['html']);
});

我們通過gulp.watch API指定要觀看的文件,并通過依賴數(shù)組定義要運行的任務(wù)。我們現(xiàn)在可以運行$ gulp watch,任何對.scss,.js或圖像文件的更改都將運行它們各自的任務(wù)。

默認任務(wù)

我們可以創(chuàng)建一個默認任務(wù),使用$ gulp運行,運行我們創(chuàng)建的所有三個任務(wù):

gulp.task('default', ['clean'], function() {
   gulp.start('styles', 'scripts', 'html', 'images', 'watch', 'connect');
});

注意gulp.task中的附加數(shù)組。這是我們可以定義任務(wù)依賴關(guān)系的地方。在這個例子中,clean任務(wù)將在gulp.start中的任務(wù)之前運行。

注意:建議不要使用gulp.start來執(zhí)行依賴項arrary中的任務(wù),但是在這種情況下為了確保clean完全完成,這似乎是最好的選擇。

最終gulpfile.js文件

var gulp = require('gulp'),
  sass = require('gulp-ruby-sass'),
  autoprefixer = require('gulp-autoprefixer'),
  cssnano = require('gulp-cssnano'),
  jshint = require('gulp-jshint'),
  uglify = require('gulp-uglify'),
  imagemin = require('gulp-imagemin'),
  rename = require('gulp-rename'),
  concat = require('gulp-concat'),
  notify = require('gulp-notify'),
  cache = require('gulp-cache'),
  del = require('del'),
  connect = require('gulp-connect');//livereload

// Styles
gulp.task('styles', function () {
  return sass('src/styles/main.scss', { style: 'expanded' })
    .pipe(autoprefixer('last 2 version'))
    .pipe(gulp.dest('dist/styles'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(cssnano())
    .pipe(gulp.dest('dist/styles'))
    .pipe(notify({ message: 'Styles task complete' }));
});

// Scripts
gulp.task('scripts', function () {
  return gulp.src('src/scripts/**/*.js')
    .pipe(jshint('.jshintrc'))
    .pipe(jshint.reporter('default'))
    .pipe(concat('main.js'))
    .pipe(gulp.dest('dist/scripts'))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest('dist/scripts'))
    .pipe(notify({ message: 'Scripts task complete' }))
    .pipe(connect.reload())
});

// Html
gulp.task('html', function () {
  return gulp.src('src/*.html')
    .pipe(gulp.dest('dist'))
    .pipe(connect.reload());
});

// Images
gulp.task('images', function () {
  return gulp.src('src/images/**/*')
    .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
    .pipe(gulp.dest('dist/images'))
    .pipe(notify({ message: 'Images task complete' }))
    .pipe(connect.reload())
});

// Clean
gulp.task('clean', function () {
  return del(['dist/styles', 'dist/scripts', 'dist/images', 'dist/html']);
});

// Default task
gulp.task('default', ['clean'], function () {
  gulp.start('styles', 'scripts', 'html', 'images', 'watch', 'connect');
});

// Livereload
gulp.task('connect', function () {
  connect.server({
    livereload: true
  });
});

// Watch
gulp.task('watch', function () {
  gulp.watch('src/styles/**/*.scss', ['styles']);
  gulp.watch('src/scripts/**/*.js', ['scripts']);
  gulp.watch('src/images/**/*', ['images']);
  gulp.watch('src/*.html', ['html']);
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。