使用gulp实现前端自动化
来源:互联网 发布:网络招聘兼职 编辑:程序博客网 时间:2024/04/30 15:44
目标
- js模块打包
- sass编译
- 雪碧图
- css js 自动添加MD5后缀
- css js 文件自动替换到html
- css js html压缩
- 文件变更后自动运行
- 使用@@include() 加载公共html模块如: 头部 底部
代码
使用框架 插件
- gulp-css-spriter 雪碧图
- gulp-minify-css css 压缩
- gulp-md5-plus避免浏览器读取了旧的缓存文件,需要为其添加md5戳
- gulp-file-include 文件插入
- gulp-uglify js压缩
- webpack-stream js打包
- gulp-rev 对文件名加MD5后缀
- gulp-rev-collector 路径替换
- gulp-concat 多个文件合并为一个
- gulp-cssmin css压缩
- gulp-watch
gulp.watch不监听文件的新建和删除。所以一个更好一点的方案是用一个插件 gulp-watch - gulp-plumber 防止出错推出文件监控
- gulp-util
- gulp-minify-html html压缩
- gulp-less
- gulp-sass
- gulp-htmlmin html压缩
gulp任务流程
- js 打包合并 -> 压缩 -> 加MD5戳 -> 插入替换html的文件 -> 发送到目标目录
- css less编译 雪碧图 -> 加MD5戳 ->压缩 -> 插入替换html的文件 -> 发送到目标目录
- html 头部顶部加载 -> 压缩 -> 目标路径
- 将图片拷贝到目标目录
代码gulpfile
const gulp = require('gulp');const clean = require('gulp-clean');const fileinclude = require('gulp-file-include');const rev = require('gulp-rev');const revReplace = require('gulp-rev-replace');const uglify = require('gulp-uglify');const cssmin = require('gulp-cssmin');const spriter = require('gulp-css-spriter');const plumber = require('gulp-plumber');const htmlmin = require('gulp-htmlmin');const sass = require('gulp-sass');const runSequence = require('run-sequence');const webpackStream = require('webpack-stream');const named = require('vinyl-named');const path = require('path');const config = { 'ENV': 'dev',//dev or product 'public': path.resolve(__dirname, '../public'), //发布静态资源 css js img 路径 'view': path.resolve(__dirname, '../views') //发布'html路径'};const webpackConfig = { module: { loaders: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, loader: 'babel-loader', query: { presets: ['es2015'] } } ], externals:['$','zepoto'] }};const tempdir = path.resolve(__dirname, 'temp');//临时目录//清理目标文件夹/文件gulp.task('clean', function () { return gulp.src([config.public, config.view, tempdir]) .pipe(clean({force: true}));});//用于在html文件中直接include文件 并保存到目标路径gulp.task('fileinclude', function () { return gulp.src(['html/*.html']) .pipe(plumber()) .pipe(fileinclude({ prefix: '@@', basepath: '@file' })) .pipe(gulp.dest(config.view));});//将图片拷贝到目标目录gulp.task('copy:img', function () { return gulp.src('img/**/*') .pipe(gulp.dest(path.join(config.public, 'img')));});//css 压缩 文件名添加MD5gulp.task('build:css', function () { const timestamp = +new Date(); return gulp.src(['css/*.css', 'css/*.scss']) .pipe(plumber()) .pipe(rev()) //添加MD5 .pipe(sass().on('error', sass.logError)) .pipe(spriter({ includeMode: 'implicit',//explicit:默认不加入雪碧图,,implicit:默认加入雪碧图/* @meta {"spritesheet": {"include": true}} */ spriteSheet: config.public + '/img/spritesheet' + timestamp + '.png',//img保存路径 pathToSpriteSheetFromCSS: '../img/spritesheet' + timestamp + '.png'//在css文件中img的路径 })) .pipe(cssmin()) //压缩 .pipe(gulp.dest(path.join(config.public, 'css'))) .pipe(rev.manifest()) .pipe(gulp.dest(path.join(tempdir, 'rev/css')));});//js 打包 压缩 混淆 文件名添加MD5gulp.task('build:js', function () { return gulp.src('js/*.js') .pipe(plumber()) .pipe(named()) .pipe(webpackStream(webpackConfig)) .pipe(rev()) //添加MD5 .pipe(uglify()) //压缩 混淆 .pipe(gulp.dest(path.join(config.public, 'js'))) .pipe(rev.manifest()) .pipe(gulp.dest(path.join(tempdir, 'rev/js')));});// 将html的css js 引用路径 替换为 修改(增加MD5)后的路径 并压缩gulp.task("revreplace", function () { const manifest = gulp.src(path.join(tempdir, 'rev/**/rev-manifest.json')); //noinspection JSUnusedGlobalSymbols const revReplaceOptions = { manifest: manifest, replaceInExtensions: ['.js', '.css', '.html', '.scss'], modifyUnreved: (filename) => { if (filename.indexOf('.js') > -1) { return '../js/' + filename; } if (filename.indexOf('.scss') > -1) { return '../css/' + filename; } }, modifyReved: (filename) => { if (filename.indexOf('.js') > -1) { return '/js/' + filename; } if (filename.indexOf('.css') > -1) { return '/css/' + filename; } } }; return gulp.src(config.view + '/*.html') .pipe(revReplace(revReplaceOptions)) .pipe(htmlmin({collapseWhitespace: true})) .pipe(gulp.dest(config.view));});const watchFiles = ['js/**/*.js', 'css/*.css', 'css/*.sass', 'css/**/*.scss', 'html/**/*.html'];gulp.task('watch', function () { gulp.watch(watchFiles, function (event) { gulp.start('default', function () { console.log('File ' + event.path + ' was ' + event.type + ', build finished'); }); });});gulp.task('dev', ['default', 'watch']);gulp.task('default', function (done) { runSequence('clean', ['fileinclude', 'copy:img', 'build:css', 'build:js'], 'revreplace', done);});
注
- 构建工具 只是辅助我们开发生产用的 不要应为这些繁琐的框架 配置 ,增加了项目的复杂度 使用和维护的难度
- 第三方库不打包,单独使用link javascript 因为可以使用第三方的cdn 所有页面都回加载一个网站主题css模块化CSS
- 我们应该时刻明确,我们是为 了方便管理,方便修改,方便多人合作,而不是简单的分割。如果说有什么建议,我想,CSS的模块化,应该尽量与HTML的模块化相一致。这里的一致说的是,无论是在文件的分割上,还是在CSS内容的分割上,与HTML的模块化一致
gulp任务
串行方式运行任务,亦即,任务依赖
默认情况下,任务会以最大的并发数同时运行 – 也就是说,它会不做任何等待地将所有的任务同时开起来。如果你希望创建一个有特定顺序的串行的任务链,你需要做两件事:
- 给它一个提示,用以告知任务在什么时候完成,
- 而后,再给一个提示,用以告知某任务需要依赖另一个任务的完成。
gulp 的任务运行不能很好的控制顺序 使用run-sequence
gulp文件监控
gulp运行任务出错时 就会退出程序不再监控 使用gulp-plumber 防止css js 出错时退出
监控js css html img
任务default是一个完整的流程 文件的拷贝 压缩 打包 等
监控时应根据不同的文件变更 执行相应任务 这样效率更佳
但是每个一个文件变更导致其它任务也应执行,还是执行完整任务来的简单且不易出错 效率不行的话 就换电脑
自动创建页面
每一个页面具有共性:都会有一个头部和底部 都有一个和页面名相同的css,js文件 都会加载一个网站的base.css,base.js等 使用一个nodejs 脚本来完成这些。
命令形式 node new
const readline = require('readline');const fs = require("fs") ;let pagename = null;//创建readline接口实例const rl = readline.createInterface({ input:process.stdin, output:process.stdout});rl.question("页面名是什么?",function(answer){ rl.close(); pagename = answer; if(fs.existsSync(__dirname + `/html/${pagename}.html`)){ console.log(`页面${pagename}已经存在`); process.exit(0); } let basehtml=`<!DOCTYPE html><html> <head> <title>base page</title> <meta charset="utf-8"/> <meta name='description' content=''> <meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="keywords" content=""/> <meta name="author" content="" /> <link rel="icon" href="/favicon.ico" type="image/x-icon"/> <link href="//cdn.bootcss.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet"> <link rel="stylesheet" type="text/css" href="../css/base.scss"> <link rel="stylesheet" type="text/css" href="../css/${pagename}.scss"> </head> <body> @@include('./common/head.html') <div class='container'> </div> @@include('./common/foot.html') <script type="text/javascript" src='../js/base.js'></script> <script type="text/javascript" src='../js/${pagename}.js'></script> </body></html>`; fs.writeFile(__dirname + `/html/${pagename}.html`, basehtml, {flag: 'a'}, function (err) { if(err) { console.error(err); } else { console.log(`创建${pagename}.html`); } }); fs.writeFile(__dirname + `/css/${pagename}.scss`, '', {flag: 'a'}, function (err) { if(err) { console.error(err); } else { console.log(`创建${pagename}.scss`); } }); fs.writeFile(__dirname + `/js/${pagename}.js`, '', {flag: 'a'}, function (err) { if(err) { console.error(err); } else { console.log(`创建${pagename}.js`); } });});
发现的问题
- 使用gulp-minify-html 后,ejs语法的 “<%=aa %> ” 出错:<%= aa=”” %=”“>
解决
- 换成 gulp-htmlmin
- 换成 gulp-rev-replace 并且在build任务中将rev(添加MD5) 执行步骤放在less(编译前面);保证了名字还是.less时加入到rev-mainfest.json.
添加配置项
modifyUnreved: (filename) => {
if (filename.indexOf('.js') > -1) {
return '../js/' + filename;
}
if (filename.indexOf('.less') > -1) {
return '../css/' + filename;
}
},
modifyReved: (filename) => {
return '/' + filename
}
0 0
- 使用gulp实现前端自动化
- 使用gulp 完成前端自动化
- 使用Gulp构建前端自动化
- Gulp前端自动化之 ejs插件使用
- 使用gulp来自动化部署前端项目
- 使用Gulp构建前端自动化解决方案
- 前端工程自动化--gulp的使用
- Linux前端自动化gulp安装与使用
- 关于前端自动化gulp的入门使用
- 前端自动化之--gulp
- 前端自动化gulp
- 前端自动化神器-gulp
- Gulp 前端自动化工具
- gulp-前端简单自动化
- Gulp前端自动化工具
- thinkphp整合系列之gulp实现前端自动化
- gulp前端自动化构建工具:常用插件介绍及使用
- 安装gulp前端自动化工具
- 理解和使用zlib库
- Java基础Day05笔记
- 解决eclipse中项目红色感叹号--dns_sd.jar包问题
- android轻量级缓存框架ACache
- 防微信摇一摇+钟摆动画
- 使用gulp实现前端自动化
- Android点击EditText外面隐藏输入法
- Json DFS parse(PG)
- STM32F407 - 低功耗模式之待机唤醒
- extjs 下拉框增加空选项
- LeetCode 299. Bulls and Cows
- jmeter学习记录(二):简单web测试流程
- Google官方网络框架-Volley的使用解析Json以及加载网络图片方法
- Dijkstra求最短路径