Gulp 基於 Node.js 的前端構建工具,可以實現前端代碼的編譯(sass、less)、壓縮合並(JS、CSS)、測試;圖片的壓縮;已經添加 JS 和 CSS 版本號,防止瀏覽器緩存。
1. 安裝
全局安裝
$ npm install gulp -g
進入項目跟目錄,初始化 npm init , 然后安裝:
$ npm install gulp
安裝插件
- sass的編譯(gulp-ruby-sass)
- 自動添加css前綴(gulp-autoprefixer)
- 壓縮css(gulp-clean-css)
- 壓縮js代碼(gulp-uglify)
- 壓縮圖片(gulp-imagemin)
- 合並文件(gulp-concat)
- 圖片緩存插件(gulp-cache)
- 編譯提醒(gulp-notify)
- 清除文件(del)
- 自動添加版本號(gulp-rev-collector 、 gulp-rev)
- ES6 轉 ES5 (gulp-babel、babel-preset-es2015、babel-core)
注意,避免 gulp-babel 編譯時出現Cannot find module '@babel/core', gulp-babel 的版本建議安裝7.0.1 ($ npm install gulp-babel@7 --save-dev)
2. 配置項目
"dependencies": {
"babel-core": "^6.26.3",
"del": "^4.1.1",
"gulp": "^4.0.1",
"gulp-autoprefixer": "^6.1.0",
"gulp-cache": "^1.1.1",
"gulp-clean-css": "^4.2.0",
"gulp-concat": "^2.6.1",
"gulp-imagemin": "^5.0.3",
"gulp-jshint": "^2.1.0",
"gulp-notify": "^3.2.0",
"gulp-rename": "^1.4.0",
"gulp-rev": "^9.0.0",
"gulp-rev-append": "^0.1.8",
"gulp-rev-collector": "^1.3.1",
"gulp-ruby-sass": "^4.0.0",
"gulp-uglify": "^3.0.2",
"jshint": "^2.10.2"
},
"devDependencies": {
"babel-preset-es2015": "^6.24.1",
"gulp-babel": "^7.0.1"
}
注意各個插件的版本號,升級后可能報錯
3. 引入插件
創建文件 gulpfile.js:
var gulp = require('gulp'),
babel = require('gulp-babel'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector'),
cleanCSS = require('gulp-clean-css'),
autoprefixer = require('gulp-autoprefixer'),
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');
4. 合並、壓縮css, 並添加不同瀏覽器的前綴
gulp.task('css', function () {
// 找到 src/css/ 下的所有 css 文件
return gulp.src('src/css/**/*.css')
// 添加前綴(如:-webkit-)
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
// 合並為一個css
.pipe(concat('main.css'))
// 合並后的css 保存到 dist/css 下
.pipe(gulp.dest('dist/css'))
// 重命名
.pipe(rename({ suffix: '.min' }))
// 壓縮css
.pipe(cleanCSS())
.pipe(rev())
.pipe(gulp.dest('dist/css'))
//CSS 生成文件 hash 編碼並生成 rev-manifest.json 文件,里面定義了文件名對照映射
.pipe(rev.manifest())
.pipe(gulp.dest('rev/css'))
.pipe(notify({ message: 'css 文件壓縮完成' }));
});
執行 $ gulp css
后,會在 dist 目錄下 生成兩個文件:main.css 和 main-e25b0dac62.min.css(其中e25b0dac62是一個隨機的版本號)。
另外,還會生成了一個文件 rev/css/rev-manifest.json, 里面定義了css對應的版本號映射:
{
"main.min.css": "main-e25b0dac62.min.css"
}
5. js 代碼合並和壓縮
gulp.task('js', function () {
return gulp.src('src/js/**/*.js')
// 編譯es6
.pipe(babel())
.pipe(concat('main.js'))
.pipe(gulp.dest('dist/js'))
.pipe(rename({ suffix: '.min' }))
.pipe(rev())
.pipe(uglify())
.pipe(gulp.dest('dist/js'))
.pipe(rev.manifest())
.pipe(gulp.dest('rev/js'))
.pipe(notify({ message: 'js 文件編譯完成' }));
});
5.1 注意:如果需要制定js的壓縮先后順序,可以在src中通過數組的形式按先后順序寫入:
gulp.src(['src/js/b.js','src/js/dashboard.js','src/js/common.js','src/js/a.js',])
5.2 編譯es6
需要在根目錄創建一個 .babelrc 文件:
{
"presets": ["es2015"]
}
6. 壓縮圖片
gulp.task('images', function () {
return gulp.src('src/images/**/*')
.pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
.pipe(gulp.dest('dist/images'))
.pipe(notify({ message: '圖片壓縮完成' }));
});
7. Html中替換成包含版本號的css、js文件
其中: gulp.src()的第一個參數:生成的json文件的路徑,這里將所有的js和css對應的json文件都選中;第二個參數:要替換css,js文件(路徑)的HTML文件
gulp.task('html', function () {
return gulp.src(['rev/**/*.json', 'src/**/*.html'])
.pipe(revCollector({
replaceReved: true, // 設置replaceReved標識, 用來說明模板中已經被替換的文件是否還能再被替換,默認是false
}))
.pipe(gulp.dest('dist'));
});
8. 清空目標文件
建議在每次任務執行前,先清除之前生成的文件:
gulp.task('clean', done => {
del(['dist/css', 'dist/js', 'dist/html', 'dist/images'])
console.log('----------------清空文件-------------------')
done()
});
9. 設置默認任務(default)
默認任務指定執行上面寫好的三個任務:
gulp.task('default', gulp.series('clean', gulp.parallel('css', 'js', 'images'), 'html', done => {
console.log('-----------全部執行完畢------------------')
done();
}));
運行:
$ gulp
默認的名為 default 的任務(task)將會被運行。
執行完成后,會在 dist 目錄下出現所有執行后的 js、css、html、images。
注意gulp 執行順序:
- gulp.series 用於串行(順序)執行
- gulp.parallel 用於並行執行
項目初始目錄:

編譯后目錄:

gulpfile.js 代碼:
var gulp = require('gulp'),
babel = require('gulp-babel'),
rev = require('gulp-rev'),
revCollector = require('gulp-rev-collector'),
cleanCSS = require('gulp-clean-css'),
autoprefixer = require('gulp-autoprefixer'),
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');
// 文件路徑
var paths = {
css: {
src: 'src/css/**/*.css',
dest: 'dist/css/',
rev: 'rev/css/'
},
js: {
src: ['src/js/a.js','src/js/common.js','src/js/dashboard.js','src/js/b.js',],
dest: 'dist/js/',
rev: 'rev/js/'
},
images: {
src: 'src/images/**/*',
dest: 'dist/images/'
}
};
// 合並 壓縮 css, 自動添加不同瀏覽器的前綴
gulp.task('css', function () {
// 找到 src/css/ 下的所有 css 文件
return gulp.src(paths.css.src)
// 添加前綴(如:-webkit-)
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
// 合並為一個css
.pipe(concat('main.css'))
// 合並后的css 保存到 dist/css 下
.pipe(gulp.dest(paths.css.dest))
// 重命名
.pipe(rename({ suffix: '.min' }))
// 壓縮css
.pipe(cleanCSS())
.pipe(rev())
.pipe(gulp.dest(paths.css.dest))
//CSS 生成文件 hash 編碼並生成 rev-manifest.json 文件,里面定義了文件名對照映射
.pipe(rev.manifest())
.pipe(gulp.dest(paths.css.rev))
.pipe(notify({ message: 'css 文件壓縮完成' }));
});
// js 代碼合並和壓縮
gulp.task('js', function () {
return gulp.src(paths.js.src)
.pipe(babel())
.pipe(concat('main.js'))
.pipe(gulp.dest(paths.js.dest))
.pipe(rename({ suffix: '.min' }))
.pipe(rev())
.pipe(uglify())
.pipe(gulp.dest(paths.js.dest))
.pipe(rev.manifest())
.pipe(gulp.dest(paths.js.rev))
.pipe(notify({ message: 'js 文件編譯完成' }));
});
// 壓縮圖片
gulp.task('images', function () {
return gulp.src(paths.images.src)
.pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))
.pipe(gulp.dest(paths.images.dest))
.pipe(notify({ message: '圖片壓縮完成' }));
});
//Html替換css、js文件版本
gulp.task('html', function () {
return gulp.src(['rev/**/*.json', 'src/**/*.html'])
.pipe(revCollector({
replaceReved: true,
}))
.pipe(gulp.dest('dist'));
});
// 清空目標文件
// 在任務執行前,先清除之前生成的文件:
gulp.task('clean', done => {
del(['dist/css', 'dist/js', 'dist/html', 'dist/images'])
console.log('----------------清空文件-------------------')
done()
});
// 設置默認任務(default)
gulp.task('default', gulp.series('clean', gulp.parallel('css', 'js', 'images'), 'html', done => {
console.log('-----------全部執行完畢------------------')
done();
}));
index.html 編譯前
src/html/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>標題</title>
<link rel="stylesheet" href="../css/main.min.css">
</head>
<body>
<div id="main">
<div class="box">
<div class="item">
<h3>😄😝</h3>
</div>
</div>
</div>
<script src="../js/main.min.js"></script>
</body>
</html>
index.html 編譯后
dist/html/index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>標題</title>
<link rel="stylesheet" href="../css/main-e25b0dac62.min.css">
</head>
<body>
<div id="main">
<div class="box">
<div class="item">
<h3>😄😝</h3>
</div>
</div>
</div>
<script src="../js/main-a4f342d289.min.js"></script>
</body>
</html>