一逗宜、Grunt Gulp區(qū)別
參考
Grunt 新手一日入門
gulp VS grunt
Grunt 就是小明想的這樣一種自動化任務處理工具奶段,它就是一個工具框架澎胡,有很多插件擴展它的功能垦垂。Grunt 基于 Node.js 沪哺,用 JS 開發(fā)隅俘,這樣就可以借助 Node.js 實現(xiàn)跨系統(tǒng)跨平臺的桌面端的操作邻奠,例如文件操作等等。此外为居,Grunt 以及它的插件們碌宴,都作為一個 包 ,可以用 NPM 安裝進行管理蒙畴。所以 NPM 生成的package.json 項目文件贰镣,里面可以記錄當前項目中用到的 Grunt 插件,而 Grunt 會調用 Gruntfile.js 這個文件膳凝,解析里面的任務(task)并執(zhí)行相應操作碑隆。
需要注意,因為使用 -g 命令會安裝到全局蹬音,可能會涉及到系統(tǒng)敏感目錄上煤,如果用 Windows 的話,可能需要你用管理員權限著淆,如果用 OS X / Linux 的話劫狠,你可能需要加上 sudo 命令。
除了 Grunt 之外永部,同類型比較火的還有 Gulp 這個工具独泞。其實兩個東西的功能是一樣的,只不過是任務配置 JS 的語法不同苔埋,Gulp 的 Gulpfile.js 的寫法更加通俗易懂懦砂,上手更快。但是 Gulp 的插件等感覺不如 Grunt,Grunt 官方提供了一些常見的插件孕惜,滿足大部分日常工作愧薛,而且可靠值得信賴,而 Gulp 好像沒有太多官方出品衫画,各種插件不太規(guī)范毫炉。簡單的說,Grunt 和 Gulp 就像 iPhone 與 Android 一樣削罩,一個質量高學習難一點瞄勾,一個學起來簡單但是有點那個,你懂得弥激。
二进陡、Gulp使用簡記
參考
gulp詳細入門教程
前端構建工具gulpjs的使用介紹及技巧
Gulp折騰之路(II)
1.gulp的全局安裝和本地安裝
首先確保你已經正確安裝了nodejs環(huán)境。使用cnpm init生成package.json,然后以全局方式安裝gulp:
npm install -g gulp
全局安裝gulp后微服,還需要在每個要使用gulp的項目中都單獨安裝一次趾疚。把目錄切換到你的項目文件夾中,然后在命令行中執(zhí)行:
npm install gulp
如果想在安裝的時候把gulp寫進項目package.json文件的依賴中以蕴,則可以加上--save-dev:
npm install --save-dev gulp
這樣就完成了gulp的安裝糙麦。至于為什么在全局安裝gulp后,還需要在項目中本地安裝一次丛肮,有興趣的可以看下stackoverflow上有人做出的回答:why-do-we-need-to-install-gulp-globally-and-locally
赡磅、what-is-the-point-of-double-install-in-gulp滞项。大體就是為了版本的靈活性眷射,但如果沒理解那也不必太去糾結這個問題,只需要知道通常我們是要這樣做就行了撤防。
細心的你可能會發(fā)現(xiàn)习劫,我們全局安裝了gulp咆瘟,項目也安裝了gulp,全局安裝gulp是為了執(zhí)行gulp任務榜聂,本地安裝gulp則是為了調用gulp插件的功能搞疗。
如果已經有了package.json卻沒有node_modules文件夾,可以直接運行cnpm install來恢復
2.開始使用gulp
2.1 建立gulpfile.js文件
就像gruntjs需要一個Gruntfile.js文件一樣须肆,gulp也需要一個文件作為它的主文件匿乃,在gulp中這個文件叫做gulpfile.js。新建一個文件名為gulpfile.js的文件豌汇,然后放到你的項目目錄中幢炸。之后要做的事情就是在gulpfile.js文件中定義我們的任務了。下面是一個最簡單的gulpfile.js文件內容示例拒贱,它定義了一個默認的任務宛徊。
var gulp = require('gulp');
gulp.task('default',function(){
console.log('hello world');
});
此時我們的目錄結構是這樣子的:
├── gulpfile.js
├── node_modules
│ └── gulp
└── package.json
2.2 運行gulp任務
要運行gulp任務佛嬉,只需切換到存放gulpfile.js文件的目錄(windows平臺請使用cmd或者Power Shell等工具),然后在命令行中執(zhí)行gulp命令就行了闸天,gulp后面可以加上要執(zhí)行的任務名暖呕,例如gulp task1,如果沒有指定任務名苞氮,則會執(zhí)行任務名為default的默認任務湾揽。
3、gulp的API介紹
使用gulp笼吟,僅需知道4個API即可:gulp.task(),gulp.src(),gulp.dest(),gulp.watch()
3.1 gulp.src()
//使用數(shù)組的方式來匹配多種文件
gulp.src(['js/*.js','css/*.css','*.html'])
gulp.src([*.js,'!b*.js']) //匹配所有js文件库物,但排除掉以b開頭的js文件
3.2 gulp.dest()
gulp.dest(path)生成的文件路徑是我們傳入的path參數(shù)后面再加上gulp.src()中有通配符開始出現(xiàn)的那部分路徑。
gulp.src('script/avalon/avalon.js') //沒有通配符出現(xiàn)的情況
.pipe(gulp.dest('dist')); //最后生成的文件路徑為 dist/avalon.js
//有通配符開始出現(xiàn)的那部分路徑為 **/underscore.js
gulp.src('script/**/underscore.js')
//假設匹配到的文件為script/util/underscore.js
.pipe(gulp.dest('dist')); //則最后生成的文件路徑為 dist/util/underscore.js
gulp.src('script/*') //有通配符出現(xiàn)的那部分路徑為 *
//假設匹配到的文件為script/zepto.js
.pipe(gulp.dest('dist')); //則最后生成的文件路徑為 dist/zepto.js
當我們沒有在gulp.src()方法中配置base屬性時贷帮,base的默認值為通配符開始出現(xiàn)之前那部分路徑戚揭,例如:
gulp.src('app/src/**/*.css') //此時base的值為 app/src
上面我們說的gulp.dest()所生成的文件路徑的規(guī)則,其實也可以理解成撵枢,用我們給gulp.dest()傳入的路徑替換掉gulp.src()中的base路徑民晒,最終得到生成文件的路徑。
gulp.src('app/src/**/*.css') //此時base的值為app/src,也就是說它的base路徑為app/src
//設該模式匹配到了文件 app/src/css/normal.css
.pipe(gulp.dest('dist')) //用dist替換掉base路徑锄禽,最終得到 dist/css/normal.css
所以改變base路徑后镀虐,gulp.dest()生成的文件路徑也會改變
gulp.src(script/lib/*.js) //沒有配置base參數(shù),此時默認的base路徑為script/lib
//假設匹配到的文件為script/lib/jquery.js
.pipe(gulp.dest('build')) //生成的文件路徑為 build/jquery.js
gulp.src(script/lib/*.js, {base:'script'}) //配置了base參數(shù)沟绪,此時base路徑為script
//假設匹配到的文件為script/lib/jquery.js
.pipe(gulp.dest('build')) //此時生成的文件路徑為 build/lib/jquery.js
看我自己的例子,為了復制過來空猜,仍然保持libs/min的文件夾路徑
//直接復制的文件,必須是bin/libs/min下的JS
var copyLibsMinSrc = [
// 'libs/min/vconsole.min.js',
'libs/min/socket.io.min.js'
];
gulp.task('copyLibsMin', function() {
for(var i = 0; i < copyLibsMinSrc.length; i ++){
copyLibsMinSrc[i] = options.binPath + '/' + copyLibsMinSrc[i];
}
gulp.src(copyLibsMinSrc,{base:options.binPath + '/'})
.pipe(gulp.dest(options.releasePath));
});
另外绽慈,在我發(fā)布版本的時候,去config.js里讀取當前版本號辈毯,然后自增1作為發(fā)布版本號坝疼。而且發(fā)布完成后,發(fā)布出來的config.js和項目里原來的config.js的版本號值都要變成最新的谆沃。也就是出現(xiàn)一個新需求钝凶,如何用Gulp更改原文件?
參考
使用gulp replace怎么替換原文件唁影,而不是生成新文件耕陷?
Can Gulp overwrite all src files?
我使用了第一種方式:{base:'./'}
gulp.src(options.binPath+'/'+options.configFile,{base:'./'})
.pipe(replace(/version:\".*\"/gi, 'version:\"'+options.version+'\"'))
.pipe(gulp.dest(''));
3.3 gulp.task()
gulp.task方法用來定義任務
//只要執(zhí)行default任務,就相當于把one,two,three這三個任務執(zhí)行了
gulp.task('default',['one','two','three']);
關于異步,原文提供了三種方法据沈,其中第一種比較方便:在異步操作完成后執(zhí)行一個回調函數(shù)來通知gulp這個異步任務已經完成,這個回調函數(shù)就是任務函數(shù)的第一個參數(shù)哟沫,也就是例子中的cb
var gulp = require('gulp');
gulp.task('one',function(cb){
//one是一個異步執(zhí)行的任務
setTimeout(function(){
console.log('one is done');
cb();
},5000);
});
//two任務雖然依賴于one任務,但并不會等到one任務中的異步操作完成后再執(zhí)行
gulp.task('two',['one'],function(){
console.log('two is done');
});
gulp.task('default', ['two']);
3.4 gulp.watch()
gulp.watch()用來監(jiān)視文件的變化,當文件發(fā)生變化后锌介,我們可以利用它來執(zhí)行相應的任務嗜诀,例如文件壓縮等猾警。
gulp.task('uglify',function(){
//do something
});
gulp.task('reload',function(){
//do something
});
gulp.watch('js/**/*.js', ['uglify','reload']);
第一個參數(shù)glob 為要監(jiān)視的文件匹配模式,規(guī)則和用法與 gulp.src() 方法中的 glob 相同隆敢。
上面是使用tasks方式发皿,還可以使用回調函數(shù)的方式
gulp.watch("js/**/*.js", function(event){
//變化類型added為新增,deleted為刪除拂蝎,changed為改變
console.log(event.type);
//變化的文件的路徑
console.log(event.path);
});
關于插件watchify穴墅,參考Browserify + watchify
三、gulp常用插件
安裝插件例子:cnpm i -D gulp-zip//–save-dev可以簡寫成-D
參考
gulp自動化打包(上)
gulp自動化打包(下)
精通gulp常用插件
常用gulp插件介紹(一)
常用gulp插件介紹(二)
1.合并壓縮 gulp-concat gulp-uglify
var gulp = require('gulp');
var concat = require("gulp-concat");
var uglify = require('gulp-uglify');
gulp.task('concat', function() {
gulp.src(['js/*.js','!js/ui/layaUI.max.all.js']) //要合并的文件
//gulp.src(['js/APage.js','js/BPage.js']) //要合并的文件
.pipe(concat('all.js')) // 合并匹配到的js文件并命名為 "all.js"
//.pipe(uglify())
.pipe(gulp.dest('dest'));
});
gulp.task('default', ['concat']);
uglify()可以傳入參數(shù)匣屡,比如
gulp.task('minimize', ['lint', 'build'], function () {
let options = {
sourceMap: true,
sourceMapIncludeSources: true,
sourceMapRoot: './src/',
mangle: true,
compress: {
sequences: true,
dead_code: true,
conditionals: true,
booleans: true,
unused: true,
if_return: true,
join_vars: true
}
};
return gulp.src('dist/flv.js')
.pipe(rename({extname: '.min.js'}))
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify(options))
.on('error', console.error.bind(console))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('./dist/'));
});
具體參數(shù)含義參考UglifyJS中文文檔
2.建服務器gulp-connect
用 gulp 建一個服務器
用gulp建立一個服務器
var gulp = require('gulp'),
connect = require('gulp-connect');
gulp.task('webserver', function() {
connect.server({port:'9000'});
//connect.server({root:'../BGH5Video/bin',port:'9000'});
});
gulp.task('default', ['webserver']);
不過封救,還是沒有anywhere方便
3.文件內容修改gulp-replace
gulp.task("replace", function () {
var date = new Date().getTime();
gulp.src('../main.html')
.pipe(replace(/_VERSION_/gi, date))
.pipe(gulp.dest(option.buildPath + '/'))
})
//main.html文件
<!DOCTYPE html>
<html ng-app="app">
<head lang="en">
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
<meta name="format-detection" content="telephone=no"/>
<link rel="stylesheet" href="style/base.css?v=_VERSION_"/>
<link rel="stylesheet" href="style/index.css?v=_VERSION_"/>
</head>
<body>
<ui-view></ui-view>
</body>
<script src="js/config/config.js?v=_VERSION_"></script>
<script src="js/app.js?v=_VERSION_"></script>
<script src="js/service/TrackDataService.js?v=_VERSION_"></script>
<script src="js/service/APIService.js?v=_VERSION_"></script>
<script src="js/service/DService.js?v=_VERSION_"></script>
<script src="js/controllers/indexCtrl.js?v=_VERSION_"></script>
<script src="js/directive/lazy.js?v=_VERSION_"></script>
<script src="js/directive/slider.js?v=_VERSION_"></script>
<script src="js/filter/filters.js?v=_VERSION_"></script>
</html>
另外參考將 buffer 變?yōu)?stream (內存中的內容)
4.gulp git
下面是一段獲取git倉庫中tag為v1.0.0的代碼(也可以checkout分支名):
var git = require('gulp-git');
gulp.task('checkout', function () {
git.checkout('v1.0.0', function (err) {
if (err) throw err;
});
})
5.gulp-htmlmin
就是一個壓縮html的插件捣作,沒什么特別要講的誉结,這邊也直接拿網上的一個常用配置來演示。
var htmlmin = require('gulp-htmlmin');
gulp.task('testHtmlmin', function () {
var options = {
removeComments: true,//清除HTML注釋
collapseWhitespace: true,//壓縮HTML
collapseBooleanAttributes: true,//省略布爾屬性的值 <input checked="true"/> ==> <input />
removeEmptyAttributes: true,//刪除所有空格作屬性值 <input id="" /> ==> <input />
removeScriptTypeAttributes: true,//刪除<script>的type="text/javascript"
removeStyleLinkTypeAttributes: true,//刪除<style>和<link>的type="text/css"
minifyJS: true,//壓縮頁面JS
minifyCSS: true//壓縮頁面CSS
};
gulp.src('src/html/*.html')
.pipe(htmlmin(options))
.pipe(gulp.dest('dist/html'));
});
6.minimist或yargs
參考 minimist輕量級的命令行參數(shù)解析引擎
這個插件券躁,簡單來說就是從命令行當中提取參數(shù)惩坑。
開發(fā)中經常會遇到的應用場景是提供不同的參數(shù),即動態(tài)參數(shù)也拜,對應到gulp中以舒,如果我們需要在命令行中手動輸入某個參數(shù),此時就可以用minimist把他從命令行“提取”出來慢哈。
var argv = require('minimist')(process.argv.slice(2));
gulp.task('checkout', function () {
var gitTag = argv.tag;
git.checkout(gitTag, function (err) {
if (err) throw err;
});
})
cmd中輸入gulp checkout --tag v1.0.0
文檔解釋也是一個‘-’為key,之后為value蔓钟。但個人實際操作為兩個‘-’為key。
此時卵贱,gitTag就會被賦值為v1.0.0滥沫。
關于process.argv,參考Node.js process.argv
以下例子參考gulp中文網-從命令行傳遞參數(shù)
// npm install --save-dev gulp gulp-if gulp-uglify minimist
var gulp = require('gulp');
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');
var minimist = require('minimist');
var knownOptions = {
string: 'env',
default: { env: process.env.NODE_ENV || 'production' }
};
var options = minimist(process.argv.slice(2), knownOptions);
gulp.task('scripts', function() {
return gulp.src('**/*.js')
.pipe(gulpif(options.env === 'production', uglify())) // 僅在生產環(huán)境時候進行壓縮
.pipe(gulp.dest('dist'));
});
然后键俱,通過如下命令運行 gulp:
$ gulp scripts --env development
7.gulp-del
刪除目標目錄兰绣,目標文件
var del=require('gulp-del')
gulp.task('clean',function(){
return del(config.dist.basePath);
})
另外,參考gulp中文網-刪除文件和文件夾
你也許會想要在編譯文件之前刪除一些文件编振。由于刪除文件和文件內容并沒有太大關系缀辩,所以,我們沒必要去用一個 gulp 插件踪央。最好的一個選擇就是使用一個原生的 node 模塊臀玄。
因為 del 模塊支持多個文件以及 globbing,因此杯瞻,在這個例子中镐牺,我們將使用它來刪除文件:
$ npm install --save-dev del
假想有如下的文件結構:
.
├── dist
│ ├── report.csv
│ ├── desktop
│ └── mobile
│ ├── app.js
│ ├── deploy.json
│ └── index.html
└── src
在 gulpfile 中,我們希望在運行我們的編譯任務之前魁莉,將 mobile 文件的內容先清理掉:
var gulp = require('gulp');
var del = require('del');
gulp.task('clean:mobile', function (cb) {
del([
'dist/report.csv',
// 這里我們使用一個通配模式來匹配 `mobile` 文件夾中的所有東西
'dist/mobile/**/*',
// 我們不希望刪掉這個文件睬涧,所以我們取反這個匹配模式
'!dist/mobile/deploy.json'
], cb);
});
gulp.task('default', ['clean:mobile']);
8.gulp-zip
將src中的各種文件募胃,打成一個zip包,演示代碼:
var zip = require('gulp-zip');
gulp.task('zip', () {
gulp.src('src/*')
.pipe(zip('zipName.zip'))
.pipe(gulp.dest('dist'));
});
9.gulp-ftp
將目標文件畦浓,發(fā)送至FTP服務器痹束,這邊有5個參數(shù)是必填的,分別為:
host:服務器地址(必須)
port:服務器端口(必須)
user:ftp賬戶(必須) // 如果FTP沒有訪問限制讶请,可以不填
pass:ftp賬戶密碼(必須)// 如果FTP沒有訪問限制祷嘶,可以不填
remote: 對應的服務器文件地址(必須)
logger:輸出文件列表名稱,默認在項目根目錄生成文件(可選,默認:logger.txt)
froot: 提單文件前綴(可選,默認:/usr/local/imgcache/htdocs)
exp:體驗環(huán)境地址(可選夺溢,默認null)
pro:正式環(huán)境地址(可選论巍,默認null)
gulp.task('ftp', function () {
return gulp.src("dist_zip/*")
.pipe(ftp({
host: 'testHost',
port: 21,
//user: 'anonymous',
//pass:null,
remotePath: "path/"
}));
});
10.run-sequence
一個串行方式跑gulp任務的插件,在實際場景中风响,不允許我們同時跑很多任務嘉汰,因為任務之間往往是相互依賴的,此時run-sequence就是一個很好的選擇状勤,他可以讓多個任務按照寫入順序執(zhí)行鞋怀,同時可以控制哪些任務并行跑持搜,哪些按照順序跑密似。
var runSequence = require('run-sequence');
gulp.task('publish', function (callback) {
runSequence('clean',['html', 'js','less', 'copy'],'zip_new',callback);
});
比如上述代碼葫盼,執(zhí)行順序為1残腌、'clean'。2贫导、['html', 'js','less', 'copy']废累。3、'zip_new'脱盲。
當然也可以在gulp中使用依賴注入的方法。比如:
gulp.task('two', ['one'], function() {
//任務two,會在任務one結束之后執(zhí)行
});
但個人還是更喜歡日缨,用run-sequence因為一旦依賴項變多之后钱反,普通的注入,相互之間依賴過后匣距,可讀性就會變差面哥,而sequence會讓代碼看起來更優(yōu)雅,寫起來也更簡單毅待。
gulp.task('publish', function (callback) {
runSequence(['html', 'js','less', 'copy'],'zip_new',ftp,callback);
});
這里有兩點需要注意:
a.run-sequence里面的任務尚卫,按順序執(zhí)行(方括號里面4個任務,算作一個任務)尸红,而且前一個跑完才會跑后一個吱涉,方括號里的是異步的刹泄,即不一定哪個先完成。
b.要想達到第一點里面的同步執(zhí)行(一個任務完成才開始下一個)怎爵,一定要保證前面的所有任務特石,即除了ftp任務,其余的方法一定要是return出來的(but make sure they either return a stream or promise, or handle the callback)鳖链,即:
正確寫法:
gulp.task('js', function (done) {
return gulp.src(config.input.js)
.pipe(ngAnnotate({single_quotes: true}))
.pipe(uglify())
.pipe(concat('index.min.js'))
.pipe(gulp.dest(config.output.dist))
});
錯誤寫法:
gulp.task('js', function (done) {
gulp.src(config.input.js)
.pipe(ngAnnotate({single_quotes: true}))
.pipe(uglify())
.pipe(concat('index.min.js'))
.pipe(gulp.dest(config.output.dist))
});
前邊都要這樣寫姆蘸,最后一項不加return,在本例中芙委,即ftp的方法不用返回
關于并行串行逞敷,可以參考gulp- run-sequence
另外,我在實際使用中發(fā)現(xiàn)如果是讀取文件配置后再做某些操作灌侣,用sequence不行推捐,原因不明。最后還是用了回調.
- 圖片壓縮顶瞳,參考Laya 圖片壓縮(pngquant,tinypng,limitPNG)
12.gulp-rename
描述:重命名文件玖姑。
var rename = require("gulp-rename");
gulp.src('./hello.txt')
.pipe(rename('gb/goodbye.md')) // 直接修改文件名和路徑
.pipe(gulp.dest('./dist'));
gulp.src('./hello.txt')
.pipe(rename({
dirname: "text", // 路徑名
basename: "goodbye", // 主文件名
prefix: "pre-", // 前綴
suffix: "-min", // 后綴
extname: ".html" // 擴展名
}))
.pipe(gulp.dest('./dist'));
13.gulp-filter
描述:在虛擬文件流中過濾文件。
var filter = require('gulp-filter');
const f = filter(['**', '!*/index.js']);
gulp.src('js/**/*.js')
.pipe(f) // 過濾掉index.js這個文件
.pipe(gulp.dest('dist'));
const f1 = filter(['**', '!*/index.js'], {restore: true});
gulp.src('js/**/*.js')
.pipe(f1) // 過濾掉index.js這個文件
.pipe(uglify()) // 對其他文件進行壓縮
.pipe(f1.restore) // 返回到未過濾執(zhí)行的所有文件
.pipe(gulp.dest('dist')); // 再對所有文件操作慨菱,包括index.js
14.gulp-if
描述:有條件地運行一個任務焰络。
var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var condition = true;
gulp.src('./js/*.js')
// condition為true時執(zhí)行uglify(), else 執(zhí)行concat('all.js')
.pipe(gulpif(condition, uglify(), concat('all.js')))
.pipe(gulp.dest('./dist/'));
15.gulp-filter、gulp-if符喝、gulp-ignore區(qū)別使用
參考gulp排除已壓縮文件思路
body {
background-color: #fdfdfd;
background-image: url("/assets/images/patterns/light_grey.png");
background-size: 301px 621px;
}
任務運行后闪彼,CSS如下:
body {
background-color: #fdfdfd;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAloAAATaBAMAAAB4FdU7AAAAFVBM...);
background-size: 301px 621px;
}
//gulp/config.js
base64: {
src: developmentAssets + '/css/*.css',
dest: developmentAssets + '/css',
options: {
baseDir: build,
extensions: ['png'],
maxImageSize: 20 * 1024, // bytes
debug: false
}
}
我只替換了小于20KB的PNG。這樣高分辨率圖不會嵌入CSS中协饲。
// gulp/tasks/development/base64.js
var gulp = require('gulp');
var base64 = require('gulp-base64');
var config = require('../../config').base64;
/**
* Replace urls in CSS fies with base64 encoded data
*/
gulp.task('base64', ['sass'], function() {
return gulp.src(config.src)
.pipe(base64(config.options))
.pipe(gulp.dest(config.dest));
});
17.gulp util
var gutil = require('gulp-util');
//gulp多功能的插件畏腕,可以替換擴展名,log顏色日志茉稠,模板
gutil.log( gutil.colors.red(i) , gutil.colors.green("已經處理完畢描馅!"));
-
gulp-print
這個插件的作用很簡單,打印出stream里面的所有文件名而线,通常調試的時候比較需要铭污。
19.gulp-bytediff
這是一個統(tǒng)計文件大小變化的工具,通常與壓縮類工具放在一起實用膀篮,比如
gulp.src('**/*.html')
.pipe($.bytediff.start())
.pipe($.minifyHtml({empty: true}))
.pipe($.bytediff.stop(bytediffFormatter))
.pipe(gulp.dest('dist'));
function bytediffFormatter (data) {
var difference = (data.savings > 0) ? ' smaller.' : ' larger.';
return data.fileName + ' went from ' +
(data.startSize / 1000).toFixed(2) + ' kB to ' +
(data.endSize / 1000).toFixed(2) + ' kB and is ' +
formatPercent(1 - data.percent, 2) + '%' + difference;
}
在壓縮的pipe前后加上.bytediff.stop(callback)嘹狞,即可統(tǒng)計壓縮前后文件的變化。在callback中傳入的參數(shù)data上誓竿,可以訪問到很多變量磅网,如文件名,變化前后的大小筷屡,變化百分比等等涧偷。
20.gulp-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腥放,在一些場景下還是非常有用的泛啸。
21.gulp-order
gulp在合并js文件時,需要注意合并的順序秃症,可以使用gulp-order插件
var gp = require('gulp');
var concat = require('gulp-concat');
var order = require("gulp-order");
gp.task("minifyJs", function(){
gp.src('./scripts/*.js')
.pipe(order([
'scripts/1.js',
'scripts/2.js',
'scripts/3.js',
'scripts/*.js'
]))
.pipe(concat('main.js'))
.pipe(gp.dest('./dist/js'));
});
注意:order中的js路徑不要包含 ./ 否則會報錯
22.gulp-sourcemaps
參考
gulp-sourcemaps的用法
SourceMap 使用教程
// 引入gulp
var gulp = require('gulp');
// 引入gulp-concat插件
var concat = require('gulp-concat');
// 引入gulp-uglify插件
var uglify = require('gulp-uglify');
// 引入gulp-sourcemaps插件
var sourceMap = require('gulp-sourcemaps');
gulp.task('sourcemap',function() {
gulp.src('./src/*.js')
.pipe( sourceMap.init() )
.pipe( concat('all.js') )
.pipe( uglify() )
.pipe( sourceMap.write('../maps/',{addComment: false}) )
.pipe( gulp.dest('./dist/') )
})
sourcemaps.init({
loadMaps: true, //是否加載以前的 .map
largeFile: true, //是否以流的方式處理大文件
})
sourceMap.write( path )候址,將會在指定的 path,生成獨立的sourcemaps信息文件种柑。如果指定的是相對路徑岗仑,是相對于 all.js 的路徑。無法指定路徑為 src 目錄聚请,否則荠雕,sourcemaps文件會生成在 dist 目錄下。
addComment : true / false ; 是控制處理后的文件(本例是 all.js )驶赏,尾部是否顯示關于sourcemaps信息的注釋炸卑。不加這個屬性,默認是true煤傍。設置為false的話盖文,就是不顯示。
四蚯姆、結合cmd
1.接受參數(shù)
參考CMD接受輸入參數(shù)(定時關機小例子)
@echo off
set /p time=請輸入關機時間:
shutdown -s -f -t %time%
@echo off 椅寺,DOS會依次執(zhí)行文件中的命令,并將執(zhí)行的命令自動輸出在DOS中蒋失,如果我們不想將執(zhí)行的命令顯示出來,就可以使用echo off來關閉自動輸出桐玻。但是篙挽,echo off本身也是一條命令,也會顯示出來镊靴,如果我們連echo off都不想顯示铣卡,那就要在echo off前面加上@链韭。所以總的來說,這條命令的作用就是煮落,關閉執(zhí)行命令的輸出敞峭。
@set /p time=請輸入關機時間:,set /p varName="string"蝉仇, 的作用是定義一個變量旋讹,變量的值讓用戶輸入,后面的字符串string轿衔,是顯示在命令窗口中的提示沉迹。
%time%,獲取變量的值