【问题标题】:Prepend custom strings to JS files while concatenating在连接时将自定义字符串添加到 JS 文件中
【发布时间】:2015-04-29 13:15:01
【问题描述】:

我正在尝试将我们的构建过程从现有的自定义 bash 构建脚本迁移到 gulp。我们连接了几个未压缩的开源 JS 文件,如 bootstrap、lazyload ......以及我们自己的 JS 文件。我们按顺序对每个 JS 文件(也删除它们的许可证)进行 uglify,根据需要将自定义许可证文本添加到其中一些文件,然后连接以创建输出 JS 文件。自定义许可证文本当前在 bash 脚本中保存为字符串。

如何在不创建中间文件的情况下在 gulp 中实现这一点? 是否也可以选择性地避免丑化一些 JS 脚本?

【问题讨论】:

    标签: gulp gulp-concat gulp-uglify


    【解决方案1】:

    好的,我花了一些时间学习 gulp 和它的插件,这是一个工作版本。这里的要点是在从 JSON 配置文件中检索到的每个 JS 上使用 foreach,将流推送到数组,最后在数组流上使用合并。

    以下是使用的插件和定义的 JSON 结构:

    var gulp = require('gulp');
    
    var each = require('foreach');
    var debug = require('gulp-debug');
    var gulpif = require('gulp-if');
    var jshint = require('gulp-jshint');
    var uglify = require('gulp-uglify');
    var concat = require('gulp-concat-util');
    
    var es = require('event-stream');
    var cache = require('gulp-cached');
    var remember = require('gulp-remember');
    
    // Structure that holds the various JS files and their handling
    var Config = {
      js: {
        output_dir: 'path/to/output/file/',
        output_file: 'outputfile.js',
        src: [{
          name: 'bootstrap',
          src: ['path/to/bootstrap.js'],
          run_lint: false,
          run_uglify: true,
          license: '/* bootstrap license */'
        }, {
          name: 'lazyload',
          src: ['path/to/lazyload.js'],
          run_lint: false,
          run_uglify: true,
          license: '/* lazyload license */'
        }, {
          name: 'inhouse-js',
          src: ['path/to/inhouse/ih-1.js', 'path/to/inhouse/ot/*.js'],
          run_lint: true,
          run_uglify: true,
          license: ''
        }]
      }
    }
    

    构建任务,我们将在开发中使用缓存:

    gulp.task('build', ['build:js']);
    
    gulp.task('build:js', function() {
      var streams = [];
    
      each(Config.js.src, function(val, key, array) {
        var stream = gulp.src(val.src)
          .pipe(cache('scripts'))
          .pipe(gulpif(val.run_lint, jshint('.jshintrc')))
          .pipe(gulpif(val.run_lint, jshint.reporter('jshint-stylish')))
          .pipe(gulpif(val.run_uglify, uglify({
                                         compress: {
                                           drop_console: true
                                         }
          })))
          .pipe(concat.header(val.license + '\n'));
    
        streams.push(stream);
      });
    
      es.merge.apply(this, streams)
        .pipe(remember('scripts')) // add back all files to the stream
        .pipe(concat(Config.js.output_file))
        .pipe(gulp.dest(Config.js.output_dir));
    });
    

    如果您想调试,一个不错的选择是在上面的“gulp-remember”插件调用周围插入调试插件,如下例所示:

    .pipe(debug({title: 'before remember:'}))
    .pipe(remember('scripts')) // add back all files to the stream
    .pipe(debug({title: 'after remember:'}))
    

    这是监视任务:

    gulp.task('watch', function() {
      var watch_list = [];
      each(Config.js.src, function(val, key, array) {
        watch_list.push.apply(watch_list, val.src);
      });
    
      // Watch .js files
      var watcher = gulp.watch(watch_list, ['build']);
    
      watcher.on('change', function(event) {
        console.log('File '+ event.path +' was '+ event.type +', running tasks..');
        if (event.type === 'deleted') { // if a file is deleted, forget it
          delete cache.caches['scripts'][event.path];
          remember.forget('scripts', event.path);
        }
      })
    });
    

    您可以使用lazypipe() 在正常构建中重用部分 build:js 任务。

    【讨论】:

    • 一年后转给你,对于其他阅读本文的人:我认为这不是一个好方法,原因有很多。 1)没有任务分离。在不使文件丑化的情况下对文件进行 lint 是不可能的。 2) 不会返回任何流,并且永远不会调用 done,因此 gulp 不知道任务何时完成(有时它可能会“挂起”很长时间什么都不做,即使看起来所有处理都已完成) 3) gulp-if 正在使用,但这里不需要。 ...等
    • 我帮助 npm 打包类似这样的东西 npmjs.com/package/gulp-inject-string
    • @sabertababaeeyazdi 谢谢。我一直在使用它,但没有更新上面的这个答案。事实上,上面的代码在我的生产服务器上已经成功运行了几年,并有轻微的更新;附注。
    猜你喜欢
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 2016-11-13
    • 2023-03-12
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    相关资源
    最近更新 更多