适用于一般项目,(可以使用 jquery swiper 等插件,如需使用 react angular 等 需要添加配置)
源码地址
|-- app // 源码
|-- _data // json 数据
|-- imgs // 图片
|-- libs // 插件
|-- scripts // js文件
|-- styles // css文件
|-- tpl // 二级页面等
|-- index.html // 网站主页面
|-- config
|-- pluginConfig.js // gulp 插件配置项
|-- dev // 编译后目录
|-- build // 生产版本
|-- .eslintrc // eslint规则
|-- .eslintignore // eslint忽略文件
|-- .gitignore // git提交忽略文件
|-- gulpfile.babel.js // gulp配置
|-- package.json // npm包
|-- README.md // 项目说明
"devDependencies": {
"babel-core": "^6.23.1",
"babel-preset-es2015": "^6.22.0",
"babel-preset-stage-1": "^6.22.0",
"browser-sync": "^2.18.8",
"cross-env": "^3.2.4",
"del": "^2.2.2",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
"gulp-babel": "^6.1.2",
"gulp-cache": "^0.4.6",
"gulp-changed": "^2.0.0",
"gulp-clean-css": "^3.0.3",
"gulp-concat": "^2.6.1",
"gulp-eslint": "^3.0.1",
"gulp-htmlmin": "^3.0.0",
"gulp-imagemin": "^3.1.1",
"gulp-md5-assets": "^0.2.0",
"gulp-sass": "^3.1.0",
"gulp-uglify": "^2.1.0",
"run-sequence": "^1.2.2"
}
/config/pluginConfig.js
// gulp-htmlmin 压缩 html
exports.htmlmin = {
removeComments: true,
collapseWhitespace: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
minifyJS: true,
minifyCSS: true
};
// gulp-autoprefixer 添加浏览器前缀
exports.autofx = {
browsers: [
'ie >= 9',
'ie_mob >= 10',
'ff >= 30',
'chrome >= 34',
'safari >= 7',
'opera >= 23',
'ios >= 7',
'android >= 4.4',
'bb >= 10'
],
cascade: true,
remove: true
};
// gulp-clean-css 压缩 css
exports.cleanCSS = {
compatibility: 'ie8',
keepSpecialComments: '*'
};
// gulp-uglify 压缩 js
exports.uglify = {
mangle: {
except: ['require', 'exports', 'module', '$']
}
};
/gulpfile.babel.js
/dev
中文件用于,实时编译后执行;/build
中文件用于 压缩后输出生产版本
const gulp = require('gulp');
const changed = require('gulp-changed'); // 只编译改动过的文件
const htmlmin = require('gulp-htmlmin'); // html 压缩
const sass = require('gulp-sass'); // 编译 sass
const autofx = require('gulp-autoprefixer'); // css 浏览器前缀补全
const cleanCSS = require('gulp-clean-css'); // 压缩 css
const eslint = require('gulp-eslint'); // js 代码检查
const babel = require('gulp-babel'); // 编译 es6 代码
const uglify = require('gulp-uglify'); // js 压缩
const imagemin = require('gulp-imagemin'); // 图片压缩
const cache = require('gulp-cache'); // 图片缓存,图片替换了才压缩
const runSequence = require('run-sequence'); // 设定同步异步执行任务
const md5 = require('gulp-md5-assets'); // 添加 md5
const concat = require('gulp-concat'); // 合并文件
const del = require('del'); // 删除文件
const browserSync = require('browser-sync').create(); // 静态服务器
const reload = browserSync.reload;
const config = require('./config/pluginConfig'); // 引入插件的配置
// 转移 html --> (/dev)
gulp.task('move-html', () => {
return gulp
.src('./app/**/*.html')
.pipe(changed('./dev'))
.pipe(gulp.dest('./dev'));
})
// 压缩 html --> (/build)
gulp.task('minify-html', ['move-html'], () => {
return gulp
.src('./dev/**/*.html')
.pipe(htmlmin(config.htmlmin))
.pipe(gulp.dest('./build'))
.pipe(md5(10));
})
// 编译 sass --> (/dev)
gulp.task('sass', () => {
return gulp
.src('./app/styles/**/*.scss')
.pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError))
.pipe(autofx(config.autofx))
.pipe(gulp.dest('./dev/styles'))
.pipe(reload({stream: true}));
})
// 压缩 css --> (/build)
gulp.task('minify-css', ['sass'], () => {
return gulp
.src('./dev/styles/**/*.css')
.pipe(cleanCSS(config.cleanCSS))
.pipe(gulp.dest('./build/styles'))
.pipe(md5(10, './build/**/*.html')); // 查找对应文件,替换为添加md5的文件名
})
// 编译 js --> (/dev)
gulp.task('babel-js', () => {
return gulp
.src('./app/scripts/**/*.js')
.pipe(eslint())
.pipe(eslint.format()) // 错误格式化输出
.pipe(changed('./dev/scripts'))
.pipe(babel({
presets: ['es2015', 'stage-1']
}))
.pipe(gulp.dest('./dev/scripts'))
.pipe(reload({stream: true}));
})
// 压缩js --> (/build)
gulp.task('minify-js', ['babel-js'], () => {
return gulp
.src('./dev/scripts/**/*.js')
.pipe(uglify(config.uglify))
.pipe(gulp.dest('./build/scripts'))
.pipe(md5(10, './build/**/*.html'));
})
// 转移图片 --> (/dev)
gulp.task('move-img', () => {
return gulp
.src('./app/imgs/**/*.{png,jpg,gif,ico}')
.pipe(changed('./dev/imgs'))
.pipe(gulp.dest('./dev/imgs'))
.pipe(reload({stream: true}));
})
// 压缩图片 --> (/build)
gulp.task('minify-img', ['move-img'], () => {
return gulp
.src('./dev/imgs/**/*.{png,jpg,gif,ico}')
.pipe(cache(imagemin({
progressive: true,
optimizationLevel: 5
})))
.pipe(gulp.dest('./build/imgs'))
.pipe(md5(10, './build/**/*.{css,js,html,json}'));
})
// json 转移 --> (/dev)
gulp.task('move-json', () => {
return gulp
.src('./app/_data/*.json')
.pipe(gulp.dest('./dev/_data'))
.pipe(reload({stream: true}));
})
// json 转移至 build --> (/build)
gulp.task('build-json', () => {
return gulp
.src('./app/_data/*.json')
.pipe(gulp.dest('./build/_data'))
.pipe(md5(10, './build/**/*.js'));
})
// 转移 libs 插件 (libs 中引入的都是压缩后的文件)
gulp.task('move-libs-dev', () => {
return gulp.src('./app/libs/**/*')
.pipe(gulp.dest('./dev/libs'));
})
gulp.task('move-libs-build', () => {
return gulp.src('./app/libs/**/*')
.pipe(gulp.dest('./build/libs'))
.pipe(md5(10, './build/**/*.html'))
})
// 清空文件夹
gulp.task('clean-dev', (cb) => {
return del(['./dev/**/*'], cb);
})
gulp.task('clean-build', (cb) => {
return del(['./build/**/*'], cb);
})
// 命令行命令
/*
编译
清空 /dev 文件夹,将 html、编译后的css、编译后的js、libs中文件、图片、json文件引入
*/
gulp.task('dev', (cb) => {
// [] 中任务是并行的,其他按照先后顺序执行
runSequence('clean-dev', 'move-html', [
'sass', 'babel-js', 'move-libs-dev'
], 'move-img', 'move-json', cb)
})
// 测试执行
gulp.task('run', () => {
browserSync.init({ // 启动Browsersync服务
server: {
baseDir: './dev', // 启动服务的目录 默认 index.html
index: 'index.html' // 自定义启动文件名
},
open: 'external', // 决定Browsersync启动时自动打开的网址 external 表示 可外部打开 url, 可以在同一 wifi 下不同终端测试
injectChanges: true // 注入CSS改变
});
// 监听文件变化,执行相应任务
gulp.watch('./app/styles/**/*.scss', ['sass']);
gulp.watch('./app/scripts/**/*.js', ['babel-js']);
gulp.watch('./app/imgs/**/*.{png,jpg,gif,ico}', ['move-img']);
gulp.watch('./app/_data/*.json', ['move-json']);
gulp.watch('./app/**/*.html', ['move-html']).on('change', reload);
})
/*
压缩输出
清空 /build 文件夹,压缩html、压缩css、压缩js、引入libs中文件、引入压缩后图片、引入json,同时添加MD5
*/
gulp.task('build', (cb) => {
runSequence('clean-build', 'minify-html', [
'minify-css', 'minify-js', 'move-libs-build'
], 'minify-img', 'build-json', cb)
})
// 生产版本测试
gulp.task('build-test', ['build'], () => {
// 生产版本不允许更改文件后实时编译输出
browserSync.init({
server: {
baseDir: './build'
},
open: 'external'
});
})
.eslintrc
{
"env": {
"es6": true,
"browser": true
},
"extends": "eslint:recommended",
"rules": {
"no-console": 0
},
"globals": { // 需要设置全局变量的放在这里
"Swiper": true,
"$": true,
"jquery": true
}
}
在
package.json
中scripts
字段下定义:
"scripts": {
"dev": "gulp dev",
"run": "gulp run",
"build": "cross-env NODE_ENV='production' gulp build",
"build-test": "cross-env NODE_ENV='production' gulp build-test"
}
对应着
/gulpfile.babel.js
中定义的任务