Gulp学习笔记

一、Grunt Gulp区别

参考
Grunt 新手一日入门
gulp VS grunt
Grunt 就是小明想的这样一种自动化任务处理工具,它就是一个工具框架,有很多插件扩展它的功能。Grunt 基于 Node.js ,用 JS 开发,这样就可以借助 Node.js 实现跨系统跨平台的桌面端的操作,例如文件操作等等。此外,Grunt 以及它的插件们,都作为一个 包 ,可以用 NPM 安装进行管理。所以 NPM 生成的package.json 项目文件,里面可以记录当前项目中用到的 Grunt 插件,而 Grunt 会调用 Gruntfile.js 这个文件,解析里面的任务(task)并执行相应操作。

需要注意,因为使用 -g 命令会安装到全局,可能会涉及到系统敏感目录,如果用 Windows 的话,可能需要你用管理员权限,如果用 OS X / Linux 的话,你可能需要加上 sudo 命令。

除了 Grunt 之外,同类型比较火的还有 Gulp 这个工具。其实两个东西的功能是一样的,只不过是任务配置 JS 的语法不同,Gulp 的 Gulpfile.js 的写法更加通俗易懂,上手更快。但是 Gulp 的插件等感觉不如 Grunt,Grunt 官方提供了一些常见的插件,满足大部分日常工作,而且可靠值得信赖,而 Gulp 好像没有太多官方出品,各种插件不太规范。简单的说,Grunt 和 Gulp 就像 iPhone 与 Android 一样,一个质量高学习难一点,一个学起来简单但是有点那个,你懂得。

二、Gulp使用简记

参考
gulp详细入门教程
前端构建工具gulpjs的使用介绍及技巧
Gulp折腾之路(II)

1.gulp的全局安装和本地安装
首先确保你已经正确安装了nodejs环境。使用cnpm init生成package.json,然后以全局方式安装gulp:
npm install -g gulp
全局安装gulp后,还需要在每个要使用gulp的项目中都单独安装一次。把目录切换到你的项目文件夹中,然后在命令行中执行:
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。大体就是为了版本的灵活性,但如果没理解那也不必太去纠结这个问题,只需要知道通常我们是要这样做就行了。
细心的你可能会发现,我们全局安装了gulp,项目也安装了gulp,全局安装gulp是为了执行gulp任务,本地安装gulp则是为了调用gulp插件的功能。
如果已经有了package.json却没有node_modules文件夹,可以直接运行cnpm install来恢复

生成package.json

安装gulp 和gulp插件

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等工具),然后在命令行中执行gulp命令就行了,gulp后面可以加上要执行的任务名,例如gulp task1,如果没有指定任务名,则会执行任务名为default的默认任务。
3、gulp的API介绍
使用gulp,仅需知道4个API即可:gulp.task(),gulp.src(),gulp.dest(),gulp.watch()
3.1 gulp.src()

//使用数组的方式来匹配多种文件
gulp.src(['js/*.js','css/*.css','*.html'])
gulp.src([*.js,'!b*.js']) //匹配所有js文件,但排除掉以b开头的js文件

3.2 gulp.dest()
gulp.dest(path)生成的文件路径是我们传入的path参数后面再加上gulp.src()中有通配符开始出现的那部分路径。

gulp.src('script/avalon/avalon.js') //没有通配符出现的情况
    .pipe(gulp.dest('dist')); //最后生成的文件路径为 dist/avalon.js

//有通配符开始出现的那部分路径为 **/underscore.js
gulp.src('script/**/underscore.js')
    //假设匹配到的文件为script/util/underscore.js
    .pipe(gulp.dest('dist')); //则最后生成的文件路径为 dist/util/underscore.js

gulp.src('script/*') //有通配符出现的那部分路径为 *
    //假设匹配到的文件为script/zepto.js    
    .pipe(gulp.dest('dist')); //则最后生成的文件路径为 dist/zepto.js

当我们没有在gulp.src()方法中配置base属性时,base的默认值为通配符开始出现之前那部分路径,例如:
gulp.src('app/src/**/*.css') //此时base的值为 app/src
上面我们说的gulp.dest()所生成的文件路径的规则,其实也可以理解成,用我们给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参数,此时默认的base路径为script/lib
    //假设匹配到的文件为script/lib/jquery.js
    .pipe(gulp.dest('build')) //生成的文件路径为 build/jquery.js

gulp.src(script/lib/*.js, {base:'script'}) //配置了base参数,此时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));
});

另外,在我发布版本的时候,去config.js里读取当前版本号,然后自增1作为发布版本号。而且发布完成后,发布出来的config.js和项目里原来的config.js的版本号值都要变成最新的。也就是出现一个新需求,如何用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方法用来定义任务

//只要执行default任务,就相当于把one,two,three这三个任务执行了
gulp.task('default',['one','two','three']);

关于异步,原文提供了三种方法,其中第一种比较方便:在异步操作完成后执行一个回调函数来通知gulp这个异步任务已经完成,这个回调函数就是任务函数的第一个参数,也就是例子中的cb

var gulp = require('gulp');
gulp.task('one',function(cb){
  //one是一个异步执行的任务
  setTimeout(function(){
    console.log('one is done');
    cb();
  },5000);
});

//two任务虽然依赖于one任务,但并不会等到one任务中的异步操作完成后再执行
gulp.task('two',['one'],function(){
  console.log('two is done');
});

gulp.task('default', ['two']);

3.4 gulp.watch()
gulp.watch()用来监视文件的变化,当文件发生变化后,我们可以利用它来执行相应的任务,例如文件压缩等。

gulp.task('uglify',function(){
  //do something
});
gulp.task('reload',function(){
  //do something
});
gulp.watch('js/**/*.js', ['uglify','reload']);

第一个参数glob 为要监视的文件匹配模式,规则和用法与 gulp.src() 方法中的 glob 相同。
上面是使用tasks方式,还可以使用回调函数的方式

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()可以传入参数,比如

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/'));
});

具体参数含义参考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 变为 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.minimistyargs
参考 minimist轻量级的命令行参数解析引擎
这个插件,简单来说就是从命令行当中提取参数。
开发中经常会遇到的应用场景是提供不同的参数,即动态参数,对应到gulp中,如果我们需要在命令行中手动输入某个参数,此时就可以用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中文网-从命令行传递参数

// 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())) // 仅在生产环境时候进行压缩
    .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
将目标文件,发送至FTP服务器,这边有5个参数是必填的,分别为:
host:服务器地址(必须)
port:服务器端口(必须)
user:ftp账户(必须) // 如果FTP没有访问限制,可以不填
pass:ftp账户密码(必须)// 如果FTP没有访问限制,可以不填
remote: 对应的服务器文件地址(必须)
logger:输出文件列表名称,默认在项目根目录生成文件(可选,默认:logger.txt)
froot: 提单文件前缀(可选,默认:/usr/local/imgcache/htdocs)
exp:体验环境地址(可选,默认null)
pro:正式环境地址(可选,默认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就是一个很好的选择,他可以让多个任务按照写入顺序执行,同时可以控制哪些任务并行跑,哪些按照顺序跑。

 var runSequence = require('run-sequence');
gulp.task('publish', function (callback) {
  runSequence('clean',['html', 'js','less', 'copy'],'zip_new',callback);
});

比如上述代码,执行顺序为1、'clean'。2、['html', 'js','less', 'copy']。3、'zip_new'。
当然也可以在gulp中使用依赖注入的方法。比如:

gulp.task('two', ['one'], function() {
    //任务two,会在任务one结束之后执行
});

但个人还是更喜欢,用run-sequence因为一旦依赖项变多之后,普通的注入,相互之间依赖过后,可读性就会变差,而sequence会让代码看起来更优雅,写起来也更简单。

gulp.task('publish', function (callback) {
  runSequence(['html', 'js','less', 'copy'],'zip_new',ftp,callback);
});

这里有两点需要注意:
a.run-sequence里面的任务,按顺序执行(方括号里面4个任务,算作一个任务),而且前一个跑完才会跑后一个,方括号里的是异步的,即不一定哪个先完成。
b.要想达到第一点里面的同步执行(一个任务完成才开始下一个),一定要保证前面的所有任务,即除了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
另外,我在实际使用中发现如果是读取文件配置后再做某些操作,用sequence不行,原因不明。最后还是用了回调.

  1. 图片压缩,参考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)               // 返回到未过滤执行的所有文件
    .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时执行uglify(), else 执行concat('all.js')
    .pipe(gulpif(condition, uglify(), concat('all.js')))
    .pipe(gulp.dest('./dist/'));

15.gulp-filtergulp-ifgulp-ignore区别使用
参考gulp排除已压缩文件思路

  1. gulp-base64
    参考Gulp系列教程:图片转换成Base64编码
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("已经处理完毕!"));
  1. gulp-print
    这个插件的作用很简单,打印出stream里面的所有文件名,通常调试的时候比较需要。

19.gulp-bytediff
这是一个统计文件大小变化的工具,通常与压缩类工具放在一起实用,比如

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.start()和.bytediff.stop(callback),即可统计压缩前后文件的变化。在callback中传入的参数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.接受参数
参考CMD接受输入参数(定时关机小例子)

@echo off  
set /p time=请输入关机时间:  
shutdown -s -f -t %time%

@echo off ,DOS会依次执行文件中的命令,并将执行的命令自动输出在DOS中,如果我们不想将执行的命令显示出来,就可以使用echo off来关闭自动输出。但是,echo off本身也是一条命令,也会显示出来,如果我们连echo off都不想显示,那就要在echo off前面加上@。所以总的来说,这条命令的作用就是,关闭执行命令的输出。
@set /p time=请输入关机时间:,set /p varName="string", 的作用是定义一个变量,变量的值让用户输入,后面的字符串string,是显示在命令窗口中的提示。
%time%,获取变量的值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容

  • gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学...
    依依玖玥阅读 3,152评论 7 55
  • 对网站资源进行优化,并使用不同浏览器测试并不是网站设计过程中最有意思的部分,但是这个过程中的很多重复的任务能够使用...
    懵逼js阅读 1,067评论 0 8
  • gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学...
    小裁缝sun阅读 928评论 0 3
  • gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学...
    build1024阅读 528评论 0 0
  • 1、gulp的安装 首先确保你已经正确安装了nodejs环境。然后以全局方式安装gulp: npm install...
    F_imok阅读 2,377评论 1 11