Skip to content
This repository has been archived by the owner on Jan 16, 2018. It is now read-only.

Gulp example ignores Gulp! #5

Open
indolering opened this issue May 31, 2014 · 18 comments
Open

Gulp example ignores Gulp! #5

indolering opened this issue May 31, 2014 · 18 comments

Comments

@indolering
Copy link

The webpage "plugins" for gulp state, "No need for a gulp plugin. Just use webpack directly." but your examples don't just use WebPack directly, they miss out on the point of Gulp entirely.

For example, this is how I use Browserify:

  gulp.src('./scripts/index.js', {read: false})
    .pipe(browserify({
      insertGlobals: false,
      debug: true,
      transform: ['uglifyify'],
      'global-transform': true
    }))
    .pipe(rename('speech.js'))
    .pipe(gulp.dest('./spx/meta/'));

This is how I setup Google Closure:

  gulp.src('./babel/babel.js')
    .pipe(closure({compilation_level: 'ADVANCED_OPTIMIZATIONS'}))
    .pipe(rename('babel.mini.js'))
    .pipe(gulp.dest(location));

  gulp.src('./babel/babel.js')
    .pipe(closure({compilation_level: 'ADVANCED_OPTIMIZATIONS'}))
    .pipe(zip())
    .pipe(rename('babel.mini.js.gz'))
    .pipe(gulp.dest(location));

Here is how I am supposed to use Web Pack with Gulp:

gulp.task("webpack", function(callback) {
    // run webpack
    webpack({
        // configuration
    }, function(err, stats) {
        if(err) throw new gutil.PluginError("webpack", err);
        gutil.log("[webpack]", stats.toString({
            // output options
        }));
        callback();
    });
});

The // configuration shows that you are missing the point of Gulp: code over configuration. If you are asking me to write a bunch of foreign config then you obviously "need a plugin" because I don't want to "use Web Pack directly". I want to pass it files using a pipe and I want to direct the output to files but your examples don't tell me how to do that.

If I just wanted a task runner, I could use Grunt or WebPack directly. I choose Gulp because it makes it easier for me to iteratively build up a large number of tasks.

@sokra
Copy link
Member

sokra commented May 31, 2014

I'm not really into gulp and gulps philosophy. When you know a better way how to use webpack with gulp I really want to hear it.

@sindresorhus wrote this https://github.com/sindresorhus/gulp-webpack before I even heared about gulp. So I didn't wrote a gulp plugin. But this issue and webpack/webpack#280 make me think that you may need one.

@sindresorhus I would like to hear your optinion.

@sindresorhus
Copy link

Webpack is inherently incompatible with gulp because AFAIK it doesn't accept an array of file buffers, which is required for gulp plugins. A gulpfile is just node. This is more of a general Webpack
API issue.

@indolering
Copy link
Author

@sokra It should at processes at the pipe level, similar to the Browserify and Google Closure plugins:

var customPlugin =  new webpack.DefinePlugin({
    "process.env": {
        "NODE_ENV": JSON.stringify("production")
 }});

gulp.src('./dir/file.js')
  .pipe(webpack({
    plugins: [
      webpack.optimize.DedupePlugin({config:options}),
      webpack.optimize.UglifyJsPlugin({config:options}),
      customPlugin
  ]})
  .pipe(gulp.dest('./dist/file.js'));

@sindresorhus I think some plugins use a .tmp directory....

Whatever the backend reasons for all of this, your non-plugin-plugin is discouraging others from attempting to fix the problem and that makes me a very sad panda.

@khaled
Copy link

khaled commented Jun 2, 2014

+1 for properly supporting gulp

@nervo
Copy link

nervo commented Jun 19, 2014

👍 here too

@shama
Copy link
Member

shama commented Jun 29, 2014

I think it might be impossible for webpack to have a generic node stream interface like browserify and closure. Since webpack can output multiple files and needs to know a bit about the destination, right?

// This wont work
gulp.src('entry.js')
  .pipe(webpack())
  .pipe(rename('output.js'))
  // What about [hash].js? 1.output.js, 2.output.js?
  .pipe(gulp.dest('./dist/file.js'));

Although a stream interface might be possible by outputting virtual files using vinyl which gulp uses (and later Grunt will too).

@sokra Are you open to a PR implementing a vinyl based stream implementation?

@sokra
Copy link
Member

sokra commented Jun 29, 2014

@shama A PR to webpack or this repo or gulp-webpack?

@shama
Copy link
Member

shama commented Jun 29, 2014

I see two options:

  1. A PR to webpack that implements a stream interface where one could pipe in a single or multiple entry points. Then stream out virtual files using vinyl that webpack would normally write to the file system.
  2. Modify the webpack node API to emit the contents of the files instead of writing them (unless an option for this already exists?) Then a PR to gulp-webpack that uses that API to write the contents to vinyl based streams.

Or some other option I'm completely missing. I think the main issue is some users just want the contents of the outputted files instead of being first written to the file system.

@sokra
Copy link
Member

sokra commented Jul 2, 2014

This way you can stream out webpacks assets:

var File = require('vinyl');
var MemoryFileSystem = require("memory-fs");

var compiler = webpack({...});

var stream = new Stream.Readable();
var fs = compiler.outputFileSystem = new MemoryFileSystem();
compiler.plugin("after-emit", function(compilation, callback) {
  compilation.assets.forEach(function(asset) {
    var path = fs.join(compiler.outputPath, asset.name);
    var contents = fs.readFileSync(path);
    stream.push(new File({
      base: compiler.outputPath,
      path: path,
      contents: contents
    });
  });
  callback();
});
compiler.watch(200, ...);
// or: compiler.run(...);

@shama
Copy link
Member

shama commented Jul 2, 2014

Wow thanks @sokra! I didn't know compiler.outputFileSystem was a thing.

@sindresorhus Would you mind if I gave you a PR for this implementation on gulp-webpack?

@sindresorhus
Copy link

@shama it's yours now.

@shama
Copy link
Member

shama commented Jul 2, 2014

Thanks @sindresorhus!

Using https://github.com/shama/gulp-webpack you can now do:

var gulp = require('gulp');
var webpack = require('gulp-webpack');
gulp.task('default', function() {
  return gulp.src('src/entry.js')
    .pipe(webpack())
    .pipe(gulp.dest('dist/'));
});

Let me know of any issues!

@sokra
Copy link
Member

sokra commented Jul 3, 2014

@shama We didn't discussed the streaming in part. There are two options to do it:

a) stream -> multi entry point (you implemented this one)

b) stream -> multiple entry points


Example: streamed in files a.js, b.js, dir/c.js

a)

entry: ["/abs/path/a.js", "/abs/path/b.js", "/abs/path/dir/c.js"]

b)

entry {
  a: "/abs/path/a.js",
  b: "/abs/path/b.js",
  "dir/c": "/abs/path/dir/c.js"
}

I would favor b) because I think this is more common.


In addition to this there need to be a way to manually provide a entry option without streaming in files:

var webpack = require("gulp-webpack");

webpack({
  entry: "./manual"
}).pipe(gulp.dest("dist/"));

So depending of the existance of the entry option, gulp-webpack need to be a transform stream or a readable-stream.


Support watch via watch option. This means you cannot end the stream when a single compilation finished in watch mode.


Any optinions on this?

@mnichols @lmartins @jhnns

@shama
Copy link
Member

shama commented Jul 3, 2014

@sokra Both a and b should be possible now with shama/webpack-stream@d428908. It will preference the entry given in the config over the entry files piped in. See https://github.com/shama/gulp-webpack/blob/master/index.js#L41

So the following is now possible (I'll update the readme adding this example too):

gulp.task('webpack', function() {
  return webpack({
      entry: {
        a: "/abs/path/a.js",
        b: "/abs/path/b.js",
        "dir/c": "/abs/path/dir/c.js"
      }
    }))
    .pipe(gulp.dest('tmp/'));
});

I'll look into support for watch mode. FWIW, the current seems to work great used in tandem with gulp's watch: https://github.com/shama/gulp-webpack/blob/master/gulpfile.js

@nschubach
Copy link

@shama I assume this is broken now. I just tried something like your code above and gulp-webpack returns undefined:

[14:42:15] TypeError: Cannot set property 'outputFileSystem' of undefined
at Stream.<anonymous> (e:\node_modules\gulp-webpack\index.js:127:40)
at _end (e:\node_modules\gulp-webpack\node_modules\through\index.js:65:9)
at Stream.stream.end (e:\node_modules\gulp-webpack\node_modules\through\index.js:74:5)
at module.exports (e:\node_modules\gulp-webpack\index.js:146:12)
at Gulp.<anonymous> (e:\gulpfile.js:21:9)

Since I have this on a gulp watch, it's silently failing. The only way I got something back was to add an error callback on webpack:

gulp.task('default', function() {
    gulp.watch(paths.scripts, ['webpack']);
});
gulp.task('webpack', function() {
return webpack(
        {
            entry: 'simulation/Simulation.js',
            output: {
                filename: "app.js"
            },
            resolve: {
                modulesDirectories: ['node_modules']
            }
        }, function(err, stats) {
            console.log(arguments);
        }
    )
    .pipe(gulp.dest('/js'));
});

@shama
Copy link
Member

shama commented Feb 16, 2015

@nschubach Feel free to open an issue on gulp-webpack. Although I can't duplicate your issue. That error hints towards something strange happening to your copy of webpack or gulp. compiler should definitely be defined. I recommend rm -rf node_modules && npm cache clean && npm i and make sure you're using latest versions of things.

@sokra This issue could probably be closed now.

@jeffijoe
Copy link

@shama getting the same issue as @nschubach - it took me 2 days to realize theres an error cb, and I get the same error.

@jeffijoe
Copy link

@shama @nschubach overlooked something.

Second parameter to webpack() is the webpack instance, we gave it the callback, instead of webpack(opts, null, function(..){});

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants