sindresorhus / gulp-rev

Static asset revisioning by appending content hash to filenames: `unicorn.css` → `unicorn-d41d8cd98f.css`
MIT License
1.54k stars 217 forks source link

Rev-manifest.json not being generated #61

Closed codekirei closed 9 years ago

codekirei commented 10 years ago

Originally reported by @tingGui in #58.

rev() is functioning as expected, but rev-manifest.json is not being created by rev.manifest(). Looks like the source is being built by RequireJS.

His code:

gulp.task('rjs', function() {
  rjs({
    baseUrl: basePath,
    mainConfigFile: basePath + 'build.js',
    removeCombined: true,
    name: 'rjs.build.main',
    out: 'libs.min.js'
  })
    .pipe(uglify())
    .pipe(rev())
    .pipe(gulp.dest('web/static/compiled/scripts'))
    .pipe(rev.manifest())
    .pipe(rename('rev-manifest.json'))
    .pipe(gulp.dest('web/static/compiled'));
});
codekirei commented 10 years ago

@tingGui

The default output of rev.manifest() is rev-manifest.json, so your rename() is unnecessary. Probably not the source of the issue, but still ;)

I'm not super familiar with RequireJS, but I'm thinking it might be acting up because of the way it's generating the source. Try using gulp-buffer as mentioned in the readme.

bobthecow commented 10 years ago

It's (likely) not the bufferness, but that rjs doesn't emit a vinyl file, it just emits a buffer or stream. To get the stream turned into a vinyl file, use vinyl-source-stream:

var source = require('vinyl-source-stream');

gulp.task('rjs', function() {
  rjs({
    baseUrl: basePath,
    mainConfigFile: basePath + 'build.js',
    removeCombined: true,
    name: 'rjs.build.main',
    out: 'libs.min.js'
  })
    .pipe(source(basePath + 'libs.min.js'))
    .pipe(uglify())
    .pipe(rev())
    .pipe(gulp.dest('web/static/compiled/scripts'))
    .pipe(rev.manifest())
    .pipe(rename('rev-manifest.json'))
    .pipe(gulp.dest('web/static/compiled'));
});
codekirei commented 10 years ago

@bobthecow My bad. That makes more sense.

Slight tangent: according to its readme, vinyl-source-stream works well with browserify, too--is there an advantage to using gulp-buffer instead, as shown in the gulp-rev readme? If not and vinyl-source-stream covers a broader use-case, would it make sense to swap out the suggestion in the readme? I understand that both plugins do different things, but functionally they seem to overlap somewhat.

Would be happy to submit a PR if you think it's a good direction.

bobthecow commented 10 years ago

gulp-buffer is only intended to transform something from a stream into a buffer. If you have a vinyl file already, and it's a stream, you'll need gulp-buffer in order to use it with gulp-rev. That said, mentioning vinyl-source-stream in conjunction with browserify and rjs would prolly be a good idea.

tingGui commented 10 years ago

I have used vinyl-source-stream before rev(),but it throws an errorStreaming not supported.

bobthecow commented 10 years ago

Then you need buffer too

tingGui commented 10 years ago

Then used buffer() beforerev(),it also throws an error TypeError: Invalid non-string/buffer chunk.

codekirei commented 10 years ago

What order are you using buffer() and source() in? Try switching them.

tingGui commented 10 years ago

Switching them ,it also does not work.

gulp.task('rjs', function() {
  rjs({
    baseUrl: basePath,
    mainConfigFile: basePath + 'build.js',
    removeCombined: true,
    name: 'rjs.build.main',
    out: 'libs.min.js'
  })
    .pipe(source(basePath + 'libs.min.js'))
    .pipe(buffer())
    .pipe(uglify())
    .pipe(rev())
    .pipe(gulp.dest('web/static/compiled/scripts'))
    .pipe(rev.manifest())
    .pipe(rename('rev-manifest.json'))
    .pipe(gulp.dest('web/static/compiled'));
});
bobthecow commented 10 years ago

Can you point us to a repo or test case so we can reproduce this?

codekirei commented 10 years ago

@tingGui This may not help, but here's another approach you could take--instead of trying to squish the rjs() output directly into a .pipe() with source() and/or buffer(), which seem to be giving you issues, you could just make another task. rjs() outputs libs.min.js to the filesystem, right? So you can just consume it with gulp.src() in a follow-up task and do whatever you want with it.

Of course, you'll need to make rjs() async so the follow-up task will wait for it to finish before consuming the output. Also, if you don't want that libs.min.js hanging around, you can delete it after you're done consuming it.

While it's admittedly somewhat hackish, I've cobbled together an example gulpfile.js that will hopefully illustrate the approach. It does the following:

  1. Create an array of source javascript files (I believe requirejs include: needs its source in an array)
  2. Concat and optimize with requirejs
  3. Consume the requirejs output in a follow-up task
  4. Delete original requirejs output
// gulpfile.js
// requires
var del  = require('del');
var fs   = require('fs');
var gulp = require('gulp');
var rjs  = require('requirejs').optimize;
var path = require('path');

// settings
var jsDir    = 'src/js';
var src      = fs.readdirSync(jsDir);
var dest     = 'dist';
var tempDir  = 'temp';
var tempFile = 'lib.js';
var rjsOut   = path.join(tempDir, tempFile);
var config   = {
    baseUrl: jsDir,
    include: src,
    out: rjsOut
};

// tasks
gulp.task('rjs1', function(cb){
    rjs(config, function(buildResponse){
        cb();
    }, cb);
});
gulp.task('rjs2', ['rjs1'], function(){
    return gulp.src(rjsOut)
        // do whatver here, e.g. rev(), uglify(), etc.
        .pipe(gulp.dest(dest));
});
gulp.task('rjs3', ['rjs2'], function(cb){
    del([tempDir],
    cb);
});
gulp.task('rjs', ['rjs1', 'rjs2', 'rjs3']);

Got some help with the callback structure here and here.

codekirei commented 10 years ago

Now that I think about it, I suppose one hiccup in that example is if there are so many js files that rjs1 starts before fs.readdirSync(jsDir) is done building the src array. So it would probably be safer to make a fourth rjs task that builds src using fs.readdir() instead, so it's async. The current rjs1 would then become rjs2 and depend on the new rjs1, and so on.

tingGui commented 10 years ago

Thank you for your help, I have found the reason is gulp-requirejs plugin, caused by the author of gulp-requirejs has fixed the async task support issue ,but not update the npm version.

sindresorhus commented 9 years ago

Try out 3.0.0. Note the API has changed. See #77.

yangnuowei88 commented 8 years ago

how to dell thiw ask? please tell me how