Search code examples
javascriptnode.jsstreamgulpgulp-inject

Streams/gulp-inject issue


I'm trying to call gulp-inject with dynamic targets. If an HTML file contains multiple targets each one overwrites the last, so I tried to move them out into another function. Problem is, now gulp-inject doesn't have access to the target (determined by logging where it gets to).

Code below should serve as an example (this is simplified but should show what's happening):

HTML:

<body>
  <!-- bundle1:js -->
  <!-- endinject -->

  <!-- bundle2:js -->
  <!-- endinject -->
</body>

Gulpfile.js:

var gulp = require('gulp');
var inject = require('gulp-inject');
var through2 = require('through2');
var bundles = require('./bundles');

var localInject = function () {
    return through2.obj(function (file, enc, cb) {
        if (file.isNull()) {
            return cb(null, file);
        }

        if (file.isStream()) {
            return cb(new gutil.PluginError('gulp-inject', 'Streaming not supported'));
        }

        var scriptBundles = Object.keys(bundles.scripts);
        var referencedScriptBundles = [];

        scriptBundles.forEach(function (bundle) {
            var expression = "(" + bundle + ":\w*)";
            var regex = new RegExp(expression, "ig");
            if (regex.test(file.contents.toString('utf-8'))) {
                //console.log('matched', bundle, 'in', file.path);
                referencedScriptBundles.push(bundle);
            }
        });

        if (referencedScriptBundles.length) {
            referencedScriptBundles.forEach(function(bundle) {
                inject(gulp.src(bundles.scripts[bundle], {
                    read: false
                }), {
                    name: bundle
                });
            });
            cb(null, file);
        } else {
            cb(null, file);
        }
    });
};

gulp.task('inject:dev', function () {
    return gulp.src('./Views/**/*.cshtml', { base: './' })
        .pipe(debug())
        .pipe(localInject())
        .pipe(gulp.dest('.'));
});

Bundles.js:

module.exports = {
  scripts: {
    bundle1: ['blah/**/*.js'],
    bundle2: ['otherblah/**/*.js']
  }
};

Probably a lack of knowledge on my part of streams, but everything works fine except inside gulp-inject, where it doesn't appear to be getting the file chunks. The plugin finds the right bundles in my views, and scripts from my bundle file to inject, just doesn't seem to have the reference to the target file.


Solution

  • I'm sure I already tried this before posting, but I fixed it by piping the current stream to inject, and using async.seriesEach.

    this.pipe(inject(...));
    

    Always the simple things!