Prepend custom strings to JS files while concatenating

点点圈 提交于 2020-01-02 10:05:47

问题


I am trying to migrate our build process to gulp from existing custom bash build script. We concatenate several unminified opensource JS files like bootstrap, lazyload, ... and our own JS files. We uglify each JS file (removing their licenses as well) in an order, prepend custom license text to some of them as required and concatenate to create the output JS file. The custom license text are currently kept as strings in the bash script.

How to achieve this in gulp without creating intermediate files? Will it also be possible to selectively avoid uglifying some JS scripts?


回答1:


Ok, I spent some time learning up gulp and it's plugins and here is a working version. The points here are using the foreach on each JS retrieved from the JSON config file, pushing the streams to an array and finally using merge on the array streams.

Here are the plugins used and the JSON structure defined:

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: ''
    }]
  }
}

The build task, with caching as we will be using it in development also:

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

If you would like to debug, a good option will be to insert debug plugin like this example around the 'gulp-remember' plugin call above:

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

And here's the watch task:

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

You can use lazypipe() to reuse parts of the build:js task with normal build.



来源:https://stackoverflow.com/questions/28754685/prepend-custom-strings-to-js-files-while-concatenating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!