gulp-community / gulp-concat

Streaming concat middleware for gulp
MIT License
792 stars 127 forks source link

Producing concatenated and minified scripts #72

Closed ilanbiala closed 9 years ago

ilanbiala commented 9 years ago

How can I produce an app.js and app.min.js file in from the same source files from the same stream?

SirZach commented 9 years ago

I am attempting to do the exact same thing.

SirZach commented 9 years ago
gulp.task('js+minify', function () {
  return gulp.src(jsPathArray)
      .pipe(concat('app.js'))
      .pipe(gulp.dest(targetPath + 'scripts/'))
      .pipe(concat('app.min.js'))
      .pipe(uglify())
      .pipe(gulp.dest(targetPath + 'scripts/'));
});

Seems to work.

ilanbiala commented 9 years ago

Ah you can have multiple gulp.dest's. I'll try that.

yocontra commented 9 years ago

Use gulp-rename

ilanbiala commented 9 years ago

In the same task and stream?

ilanbiala commented 9 years ago

@contra where does the rename('app.min.js') go? As a .pipe(), or from a new gulp.src()?

yocontra commented 9 years ago

@ilanbiala Have you tried reading any of the docs or recipes?

ilanbiala commented 9 years ago

Yeah, but there is nothing wrong with missing seven words when searching all of gulp on github and on the Internet. You could have just said that there is a recipe in the gulp docs, would have been much less condescending.

yocontra commented 9 years ago

@ilanbiala I was actually just making sure we aren't missing docs for this (very common) use case. I don't know if we have a recipe for it, which is why I asked

ilanbiala commented 9 years ago

Ah, sorry about that. Usually people just refer assuming you didn't RTFM. Sincerest apologies! :)

yocontra commented 9 years ago

@ilanbiala gulp lets you keep piping to stuff as a part of the same pipeline, so you can create many versions of a file pretty easily

var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var minify = require('gulp-uglify');

gulp.task('js', function(){
  return gulp.src('files/lib/*.js')
    /* app.js */
    .pipe(concat('app.js')) // merge all files into one
    .pipe(gulp.dest('public')) // write the in-memory file to public/app.js

    /* app.min.js */
    .pipe(rename('app.min.js')) // when done writing, file gets renamed in-memory to app.min.js
    .pipe(minify()) // in-memory file has its contents minified
    .pipe(gulp.dest('public')); // in-memory file written to public/app.min.js
});

You could keep adding more steps for every different version of the file you wanted. Let's say you want to have a app.min.with.license.js file too

var header = require('gulp-header'); // add this new plugin

gulp.task('js', function(){
  return gulp.src('files/lib/*.js')
    /* app.js */
    .pipe(concat('app.js')) // merge all files into one
    .pipe(gulp.dest('public')) // write the in-memory file to public/app.js

    /* app.min.js */
    .pipe(rename('app.min.js')) // when done writing, file gets renamed in-memory to app.min.js
    .pipe(minify()) // in-memory file has its contents minified
    .pipe(gulp.dest('public')) // in-memory file written to public/app.min.js

    /* app.min.with.license.js */
   .pipe(rename('app.min.with.license.js')) // when done writing, file gets renamed in-memory to app.min.with.license.js
   .pipe(header('/* this is a licensed thing dont abuse it */')) // in-memory file has header added to contents
   .pipe(gulp.dest('public')); // in-memory file written to public/app.min.with.license.js
});

Still one read of input files, but three outputs. This is where gulp really excels - in grunt you would have read those input files 3 times, then outputted 3 times. Since we have in-memory pipelines of transformations we don't need to do that.

tl;dr gulp is fast because we don't read or write more than absolutely needed

ilanbiala commented 9 years ago

Yeah that's why I like it so much. How stable is Gulp 4? I know it's still being developed, but I'd like to play around with it a little, it looks like a nice upgrade.

yocontra commented 9 years ago

@ilanbiala You can play around with it now - just switch over to the 4.0 branch. We need more testing and a few more issues fixed (regarding error management in pipelines and incremental build stuff which is mostly done) and then it'll be launched

ilanbiala commented 9 years ago

I tried doing .pipe(rename('app.min.js')) and .pipe(rename({ extname: '.min.js' }), but neither persist app.js to disk. I only end up with app.js.map, app.min.js, and app.min.js.map.

Also, naming the task function as function sass() {} causes an error:

gulp.task('sass', function() {
    gulp.src([
            'public/sass/**/*.scss'
        ], {
            read: false
        })
        .pipe(sass())
        .pipe(gulp.dest('public/styles'));

    gulp.src([
            'public/modules/**/*.scss'
        ], {
            read: false
        })
        .pipe(sass())
        .pipe(rename(function renameScssFiles(path) {
            path.dirname = path.dirname.replace('sass', 'styles');
        }))
        .pipe(gulp.dest('public/modules/'));
});

screenshot 2014-12-08 18 32 33

It seems that a named function with the same name as a gulp task cannot simultaneously exist, is that for a reason?

yocontra commented 9 years ago

@phated ^

yocontra commented 9 years ago

@ilanbiala Can you open a new issue about the collision of task names and named functions causing an infinite loop on gulpjs?

phated commented 9 years ago

@contra look at the stack trace, it still says Orchestrator. Not a problem in undertaker

ilanbiala commented 9 years ago

Opened as #813

@contra @phated any thoughts on the .pipe(rename) not working?

ilanbiala commented 9 years ago

@contra any thoughts? The package still works for you, right? When I do .pipe(rename('app.min.js')) it doesn't produce an app.min.js file, but it does produce an app.js.map sourcemap in addition to an app.min.js.map sourcemap.

ilanbiala commented 9 years ago

It also doesn't get fixed if I remove sourcemaps.init() and sourcemaps.write('./) from the pipe.

ilanbiala commented 9 years ago

My concat task doesn't produce any output, it doesn't even seem to run anymore, though all the other tasks run properly..renaming the task doesn't fix anything either...

yocontra commented 9 years ago

@ilanbiala Can you try the 4.0 branch

ilanbiala commented 9 years ago

Sure, can you give me a sample gulpfile? Or maybe a link to the new docs?

yocontra commented 9 years ago

@ilanbiala If you view the 4.0 branch on github there are docs there

ilanbiala commented 9 years ago

I tried it with 4.0, and it still didn't work. I also created a new task that just grabs one file and pipes it to a new place and that didn't work either. Could my local Gulp installation be messed up or is it possible that something in recent versions of gulp and/or the plugins has changed.

gulp.task('move', function() {
    return gulp.src([
            'modules/app.js'
        ])
        .pipe(gulp.dest('./public'));
});
yocontra commented 9 years ago

@ilanbiala And you're calling gulp move on the CLI to trigger that task?

ilanbiala commented 9 years ago

Yes.

yocontra commented 9 years ago

Well your environment is wrecked. I need your node version, OS, gulp local and global versions, and log output when you type that command.

ilanbiala commented 9 years ago

Node version: 0.10.32 npm version: 1.4.28 OS: Mac OS X 10.9.5 Gulp local: 4.0 resolved a7a20403190e920639c6f02c38d6269b6208fe59 Gulp global: 4.0 resolved a7a20403190e920639c6f02c38d6269b6208fe59 log output:

$ gulp concat
  [17:36:59] Using gulpfile ~/Development/hths-lunch/gulpfile.js
  [17:36:59] Starting 'concat'...
  [17:36:59] Finished 'concat' after 25 ms
$ 

I only ran npm install gulp#4.0 for that project, I'm not really sure how it updated the global, too. Also, those Gulp versions are from _resolved, I think npm did some stuff in the background.

yocontra commented 9 years ago

@ilanbiala ~/Development/hths-lunch/modules/app.js exists?

ilanbiala commented 9 years ago

Yep. Running the task now works though, but still the gulp concat task doesn't work...

gulp.task('concat', function() {
    del.sync('public/app.js');

    return gulp.src([
            'public/modules/app.js'
        ], {
            read: false
        })
        .pipe(concat('app.min.js'))
        .pipe(gulp.dest('public'));

Should I just try setting up Node from scratch? I'm fine with doing that, especially if I can get npm 2.x instead of 1.4.28, because Node still comes bundled with 1.4.x for some reason...

yocontra commented 9 years ago

@ilanbiala No, your task is just wrong. read: false means that contents will be empty. Why are you doing that?

gulp.task('concat', function() {
  del.sync('public/app.js')
  return gulp.src([
    'public/modules/app.js'
  ])
    .pipe(concat('app.min.js'))
    .pipe(gulp.dest('public'));
});
ilanbiala commented 9 years ago

You are amazing! I thought that read: false meant that the file wouldn't be opened or buffered or anything, just streamed. What can I do to prevent Gulp from taking so long and consuming so much memory?

yocontra commented 9 years ago

@ilanbiala No that isn't what read: false does.

To answer your question I would need to see your entire gulpfile. gulp is extremely fast but you need to use it properly.

ilanbiala commented 9 years ago

Is there general performance guide that I can look through first to see what I can do on my own?

yocontra commented 9 years ago

@ilanbiala No not really, it's a little more complicated than that. If you have any more questions you can use StackOverflow, this issue seems to be resolved.

ilanbiala commented 9 years ago

Yep, thanks for the help!

stringparser commented 9 years ago

@ilanbiala did you open a stackoverflow question? if so leave it here please ;)