金钱观的给文件链接增加版本号的秘技是应用gulp-rev,这里提议的应用方案是利用python来代表gulp-rev。
将上述代码另存成auto_version.py文件后,新建auto_version.bat文件,写入以下内容:
var gulp = require('gulp'),
imagemin = require('gulp-imagemin');
gulp.task('testImagemin', function () {
gulp.src('src/img/*.{png,jpg,gif,ico}')
.pipe(imagemin({
optimizationLevel: 5, //类型:Number 默认:3 取值范围:0-7(优化等级)
progressive: true, //类型:Boolean 默认:false 无损压缩jpg图片
interlaced: true, //类型:Boolean 默认:false 隔行扫描gif进行渲染
multipass: true //类型:Boolean 默认:false 多次优化svg直到完全优化
}))
.pipe(gulp.dest('dist/img'));
});
python ./auto_version.py "D:your project dir"
修改好.bat文件里的路子后,双击运行就能够。
import os
import re
import uuid
import sys
def file_extension(path):
return os.path.splitext(path)[1]
basePath = sys.argv[1]
if len(sys.argv)==1:
sys.exit()
html_list = []
def find_html(path):
files = os.listdir(path=path)
for item in files:
abs_path = os.path.join(path, item)
if not os.path.isdir(abs_path) and file_extension(abs_path) == ".html":
html_list.append(abs_path)
if (os.path.isdir(abs_path)):
find_html(abs_path)
def deal_html(html_list):
for html_path in html_list:
html_file = open(html_path, "r+", encoding='UTF-8')
content = html_file.read()
# print(html_file.read())
# res = re.sub(r'<link (.*) href="(.*).css".*>',r'<link 1 href="2.css?v=1"3>',content)
res1 = re.sub(r'<link (.*) href="(.*).css.*"(.*)>', lambda x: '<link ' + x.group(1) + ' href="' + x.group(
2) + '.css?v=' + uuid.uuid1().hex + '"' + x.group(3) + '>', content)
res2 = re.sub(r'<script src="(.*).js.*"></script>',
lambda x: '<script src="'%20+%20x.group(1)%20+%20'.js?v='%20+%20uuid.uuid1().hex%20+%20'"></script>', res1)
html_file.seek(0)
html_file.truncate()
html_file.write(res2)
html_file.close()
if __name__ == '__main__':
find_html(basePath)
deal_html(html_list)
把小图片的U翼虎L替换为Base64编码图片。
wiredep就是wire
dependence的情致,它的作用正是把bower.json中声称的dependence自动的蕴含到HTML中去。
要插入文件,wiredep要求解决五个难点:
布署的地点:wiredep通过辨认HTML中的注释来甄别插入地点,如
<!-- bower:css -->
<!-- endbower -->
<!-- bower:js -->
<!-- endbower -->
不等类其余文书被插入到区别的区块。
插入什么文件:要插入的文本列表自然来自bower.json,每种bower安装的正视库,根目录上边都有一个投机的bower.json文件,当中的main字段指明了使用那几个库须求包涵的文本,wiredep最后富含的文本列表就出自这些字段。有个别情形下,库自个儿的bower.json的main字段只怕会多含有文件或少包涵文件,要是想要定制这么些列表,则足以在温馨的bower.json中动用overrides字段,如下面包车型客车代码覆盖了mdi这几个库的main字段。
"overrides": {
"mdi": {
"main": [
"css/materialdesignicons.css"
]
}
},
wiredep插件援助广大参数,常用的机要有五个:
bowerJson:钦定bower.json的内容,注意那几个字段不是bower.json文件的岗位,这些参数要求动用require后的结果赋值:require(‘bower.json’)。
directory:内定贮存bower安装后的正视性包的不二等秘书诀,平常是bower_components。注意最后插入到HTML中的文件列表的路子是index.html文件绝对于本文件夹的相对路线。
接收wiredep也比较轻松,直接把它传到到stream中就能够,如gulp.src(‘index.html’).pipe(wiredep(options))。
减掉图片文件(蕴涵PNG、JPEG、GIF和SVG图片卡塔尔国
github:https://github.com/sindresorhus/gulp-imagemin
民用明白: 正是把 css,js全体采纳这一个插件增添到 index.html
页面里,无需手动去丰硕
<script src="../bower_components/jquery/dist/jquery.js"></script>
<link src="css/index.css"/>
<!-- inject:js -->
<script src="scripts/app.js"></script>
<!-- endinject -->
url:https://www.npmjs.com/package/gulp-useref
谈起优化的时候,大家要求想到:压缩,拼接。也正是减掉体量和HTTP次数。
开辟者面没有错显要难点是很难根据科学的后生可畏后生可畏归拢文件。
<body>
<!-- other stuff -->
<script src="js/lib/a-library.js"></script>
<script src="js/lib/another-library.js"></script>
<script src="js/main.js"></script>
</body>
是因为文件路线的的两样,使用 https://www.npmjs.com/package/gulp-concat
等插件极其艰难。
庆幸的是, gulp-useref
搞定了那一个难点。
gulp-useref
会将八个公文拼接成单一文件,并出口到对应目录。
<!-- build:<type> <path> -->
... HTML Markup, list of script / link tags.
<!-- endbuild -->
能够是js,css,可能remove。要是您设为remove,Gulp将不会转移文书。
点名产出路线。
作者们想最终现身main.min.js。能够那样写:
<!--build:js js/main.min.js -->
<script src="js/lib/a-library.js"></script>
<script src="js/lib/another-library.js"></script>
<script src="js/main.js"></script>
<!-- endbuild -->
组合使用以gulp-inject正确的各种注入您的AngularJS应用程序文件(脚本卡塔 尔(阿拉伯语:قطر,以脱位全部Uncaught
Error:
[$injector:modulerr]。为了科学职业,每一个角度文件必要具有独一命名的模块和setter语法(带括号卡塔 尔(阿拉伯语:قطر,即angular.module(‘myModule’,
[])。
gulp.task('build-app-js', function () {
return gulp.src('src/app/**/*.js')
.pipe(ngAnnotate({single_quotes: true}))
.pipe(gulp.dest(buildDir + '/js/app'));
});
健康大家写angular代码是那样子的
angular.module('app', [])
.controller('AppCtrl', ['$scope', function($scope) {
// 别的代码
}])
但选取了这一个插件之后,每三个依据注入的项就不用再写一遍了,如
angular.module('app', [])
.controller('AppCtrl', function($scope) {
// 别的代码
})
gulp-ng-annotate会帮大家生成带中括号的写法
,那样子是否省去了众多再度专门的学业吧?越发是在注入的劳动非常多的时候,能够少写过多代码,何况也不用顾忌顺序有未有写错。
调整和收缩图片时相比耗费时间,在重重情景下大家只改过了几许图片,未有供给降低全部图片,使用”gulp-cache”只压缩改正的图纸,未有改造的图纸间接从缓存文件读取(C:Userswww.2979.com ,AdministratorAppDataLocalTempgulp-cache)。
var gulp = require('gulp'),
imagemin = require('gulp-imagemin'),
pngquant = require('imagemin-pngquant'),
//确保本地已安装gulp-cache [cnpm install gulp-cache --save-dev]
cache = require('gulp-cache');
gulp.task('testImagemin', function () {
gulp.src('src/img/*.{png,jpg,gif,ico}')
.pipe(cache(imagemin({
progressive: true,
svgoPlugins: [{removeViewBox: false}],
use: [pngquant()]
})))
.pipe(gulp.dest('dist/img'));
});
只顾:它只担负统生龙活虎,不担当压缩
本地整理,留作备份。
gulp-util带有相当多实惠的函数,当中最常用的应该就是log了。$.util.log()辅助传入八个参数,打印结果会将三个参数用空格连接起来。它与console.log的界别正是持有$.util.log的结果会自动带上时间前缀。其余,它还帮助颜色,如$.util.log($.util.colors.magenta(‘123’));打字与印刷出来的123是品深黑的。其实$.util.colors就是二个chalk的实例,而chalk是专程用来管理命令行打字与印刷着色的三个工具。
var gulp = require('gulp'),
uglify = require('gulp-uglify');
gulp.task('jsmin', function () {
gulp.src('src/js/index.js')
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
怎么使用
var gulp = require('gulp'),
imagemin = require('gulp-imagemin');
gulp.task('testImagemin', function () {
gulp.src('src/img/*.{png,jpg,gif,ico}')
.pipe(imagemin())
.pipe(gulp.dest('dist/img'));
});
功用如下:
"/css/base.css" => "/dist/css/base.css?v=1d87bebe"
"/js/mod.js" => "/dist/mod.js?v=61e0be79"
"g.png" => "g.png?v=35c3af8134"
var gulp = require('gulp'),
uglify= require('gulp-uglify');
gulp.task('jsmin', function () {
//压缩src/js目录下的所有js文件
//除了test1.js和test2.js(**匹配src/js的0个或多个子文件夹)
gulp.src(['src/js/*.js', '!src/js/**/{test1,test2}.js'])
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});
var gulp = require('gulp'),
uglify= require('gulp-uglify');
gulp.task('jsmin', function () {
gulp.src(['src/js/*.js', '!src/js/**/{test1,test2}.js'])
.pipe(uglify({
//mangle: true,//类型:Boolean 默认:true 是否修改变量名
mangle: {except: ['require' ,'exports' ,'module' ,'$']}//排除混淆关键字
}))
.pipe(gulp.dest('dist/js'));
});
gulp
的错误管理有一些坑,假设发生错误进程就挂了。绝对的化解办法不菲,但是那些是自己个人相比较推荐的,比特么在容易失误的地点写错误监听可靠。所以这一个插件能够阻碍
gulp 插件产生错误招致进度退出并出口错误日志。
gulp-useref 与 gulp-rev、gulp-rev-replace
那四个工具之所以放在一块儿讲,是因为它们平常都以联合使用的。它们要解决哪些难点啊?通过地点的wiredep也好,gulp-inject也好,插入了一批JS、CSS文件到HTML中,大器晚成旦铺排驾临蓐条件,这么多文件必然是要统生龙活虎压缩的。光是压缩还缺乏,为了缓和缓慰难点,每一遍合併压缩后要给末了的文件加hash,这样每一次文件内容豆蔻梢头变动,hash也会随着变动,就官样文章浏览器依旧采取缓存的老文件的主题材料。那样拿到终极的文件之后,断定还要将那几个文件替换回HTML中去,一大堆的script和link标签替换来最终合并压缩带hash的版本。
后面罗里吧嗦的一大堆专门的职业正是那八个插件要缓和的难题了。首先,gulp-useref遵照注释将HTML中要求联合压缩的区块搜索来,对区块内的持有文件举办联合。注意:它只担任统生机勃勃,不肩负压缩!所以集结出来的文本大家要活动压缩,压缩以往调用gulp-rev肩负在文书名后追加hash。最后调用gulp-rev-replace肩负把最终的文件名轮流回HTML中去。扯了大半天,依旧一贯上例子吗。先来拜访HTML中的注释:
<!-- build:css static/styles/lib.css -->
<!-- bower:css -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:css static/styles/app.css -->
<!-- inject:css -->
<!-- endinject -->
<!-- endbuild -->
<!-- build:js static/js/lib.js -->
<!-- bower:js -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:js static/js/app.js -->
<!-- inject:js -->
<!-- endinject -->
<!-- endbuild -->
gulp-useref识别的正是build伊始的注脚,build前边首先跟的是项目扩展名,然后前面包车型客车渠道正是build区块中的全部文件进行合并后的文书路线,这么些相对路径是周旋于那么些HTML的路子。上边的例证中大家用build区块把bower和inject进来的文件包起来,那几个文件就能够被gulp-useref合并了。再来看gulp中useref相关task的概念:
var assets = $.useref.assets({searchPath: 'app/src/'});
var cssFilter = $.filter('**/*.css');
var jsAppFilter = $.filter('**/app.js');
var jslibFilter = $.filter('**/lib.js');
return gulp
.src('index.html')
.pipe(assets)
.pipe(cssFilter)
.pipe($.csso())
.pipe(cssFilter.restore())
.pipe(jsAppFilter)
.pipe($.uglify())
.pipe(getHeader())
.pipe(jsAppFilter.restore())
.pipe(jslibFilter)
.pipe($.uglify())
.pipe(jslibFilter.restore())
.pipe($.rev())
.pipe(assets.restore())
.pipe($.useref())
.pipe($.revReplace())
.pipe(gulp.dest('dist'));
首先意气风发上来,先调用$.useref.assets()函数,这么些函数重返一个stream,包涵已经联合后的文本。能够尝尝在第9行后面加上前边介绍过的gulp-print插件.pipe($.print()),打字与印刷出stream里的文件,发掘正是日前HTML中4个build注释块前边的4个文件。注意这里调用的时候跟了一个searchPath的参数,它的用项就是钦点从哪些路线始于搜寻build区块底下的文件。举个例子build区块底下有这么大器晚成行<script
src=”static/js/a.js”></script>,那最终gulp-useref将从那些路线app/src/static/js/a.js找到这些文件。第3到5行定义了3个filter,那关键是为着前边压缩策动的。下边正式看stream的pipe流程。先选出要处理的HTML文件,然后调用刚才获得的assets得到统风流倜傥后的4个文件,第10到12行筛选出归拢后的CSS文件实行压缩(压缩类插件下篇著作再讲卡塔 尔(英语:State of Qatar),第13到16行筛选出app.js实行压缩,第17到19行筛选出lib.js进行压缩。之所以要有别于对待app.js和lib.js,是因为app.js是大家同心合力写的代码,压缩后要抬高header(第15行,使用前边介绍过的gulp-header插件卡塔 尔(阿拉伯语:قطر,而lib.js是第三方的各类库,直接压缩就能够。后边调用gulp-rev给减弱后的4个公文加hash,然后调用assets.restore()将src源换回HTML文件,这是为了后边调用$.useref(),因为$.useref()做替换的src源是HTML文件,相似前面调用gulp-rev-replace将带hash的公文替换回HTML,它必要的src源也必得是HTML文件。这里的依次很主要,因为那多少个插件选用的源不一样,gulp-rev选用的是JS、CSS文件,而gulp-useref和gulp-rev-replace选拔的是HTML。还或然有六个标题:gulp-rev-replace是怎么精通gulp-rev举行hash前后的文件名对应涉及呢?其实gulp-rev会生成八个manifest的文书,内容是看似上边包车型大巴JSON:
{
"static/styles/lib.css": "static/styles/lib-d41d8cd98f.css"
"static/js/lib.js": "static/js/lib-273c2cin3f.js"
}
本来这些文件默许是不会生成在文件系统里的,可以通过.pipe($.rev.manifest())将以此文件保留到地点。有了这些文件,gulp-rev-replace甚至能够退出gulp-rev独立职业啊!
例子:https://segmentfault.com/q/1010000004266922
gulp-flatten极其实用,大概知道其余库中flatten函数的同窗早就猜到它是干嘛的了。比方gulp.src(‘*/.js’)相称了众多文书,包罗a/b/c.js,d/e.js,f/g/h/i/j/k.js,l.js,那个文件的层级都不等同,风华正茂旦大家将那么些文件pipe给$.flatten(),则有着的文书夹层级都会去掉,最后的文本将是c.js,e.js,k.js,l.js,在局地处境下依旧那一个管用的。
var gulp = require('gulp'),
imagemin = require('gulp-imagemin'),
//确保本地已安装imagemin-pngquant [cnpm install imagemin-pngquant --save-dev]
pngquant = require('imagemin-pngquant');
gulp.task('testImagemin', function () {
gulp.src('src/img/*.{png,jpg,gif,ico}')
.pipe(imagemin({
progressive: true,
svgoPlugins: [{removeViewBox: false}],//不要移除svg的viewbox属性
use: [pngquant()] //使用pngquant深度压缩png图片的imagemin插件
}))
.pipe(gulp.dest('dist/img'));
});
var gulp = require('gulp'),
uglify= require('gulp-uglify');
gulp.task('jsmin', function () {
gulp.src(['src/js/*.js', '!src/js/**/{test1,test2}.js'])
.pipe(uglify({
mangle: true,//类型:Boolean 默认:true 是否修改变量名
compress: true,//类型:Boolean 默认:true 是否完全压缩
preserveComments: 'all' //保留所有注释
}))
.pipe(gulp.dest('dist/js'));
});
Example:https://github.com/hjzheng/CUF_meeting_knowledge_share/blob/master/2015-11-10/gulpfile.js
gulp-filter能够把stream里的文本依据早晚的规规矩矩进行筛选过滤。比如gulp.src中传唱相配符相称了无尽文书,能够把这么些文件pipe给gulp-filter作一遍筛选,如gulp.src(‘*/.js’).pipe($.filter(/a/*.js)),本来选中了全体子文件下的js文件,经过筛选后化作名字为a的子文件夹下的js文件。那有人要问了,为啥不直接将索要的筛选传入gulp.src,干嘛要多筛选一步呢?这里面有三种状态:
gulp.src与$.filter中间大概须求别的管理,举例笔者对具有文件做了操作1未来,还索要筛选出一些做操作2。
其次种情形就要聊起gulp-filter的别的五个风味:挑选之后还足以restore回去。比如作者对持有文件做了操作1,筛选了黄金年代局地做操作2,最终要把全体的公文都拷贝到最后的任务。代码如下:
var filter = $.filter('**/a/*.js');
gulp.src('**/*.js')
.pipe(action1())
.pipe(filter)
.pipe(action2())
.pipe(filter.restore())
.pipe(gulp.dest('dist'))
能够见见,若无restore那些操作,那么拷贝到最终地点的文书将只含有被过滤出来的文本,这样意气风发restore,全部的文本都被拷贝了。
var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer');
gulp.task('testAutoFx', function () {
gulp.src('src/css/index.css')
.pipe(autoprefixer({
browsers: ['last 2 versions', 'Android >= 4.0'],
cascade: true, //是否美化属性值 默认:true 像这样:
//-webkit-transform: rotate(45deg);
// transform: rotate(45deg);
remove:true //是否去掉不必要的前缀 默认:true
}))
.pipe(gulp.dest('dist/css'));
});
var gulp = require('gulp'),
uglify = require('gulp-uglify');
gulp.task('jsmin', function () {
gulp.src(['src/js/index.js','src/js/detail.js']) //多个文件以数组形式传入
.pipe(uglify())
.pipe(gulp.dest('dist/js'));
});