Open indolering opened 10 years ago
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.
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.
@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.
+1 for properly supporting gulp
:+1: here too
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?
@shama A PR to webpack or this repo or gulp-webpack?
I see two options:
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.
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(...);
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?
@shama it's yours now.
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!
@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
@sokra Both a and b should be possible now with https://github.com/shama/gulp-webpack/commit/d4289086ef6f18ed499ccd58e009c43d52c733ea. 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
@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'));
});
@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.
@shama getting the same issue as @nschubach - it took me 2 days to realize theres an error cb, and I get the same error.
@shama @nschubach overlooked something.
Second parameter to webpack() is the webpack instance, we gave it the callback, instead of webpack(opts, null, function(..){});
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:
This is how I setup Google Closure:
Here is how I am supposed to use Web Pack with Gulp:
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.