shama / webpack-stream

:tropical_drink: Run webpack through a stream interface
MIT License
1.4k stars 123 forks source link

Add a `watch` option. E.g. webpack({watch: true}) #18

Open koistya opened 10 years ago

koistya commented 10 years ago

With this flag set to true, the plugin would run bundler in a watch mode - bundler.watch(..), instead of bundler.run(..).

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

gulp.task('bundle', function () {
  return gulp.src('src/app.jsx')
    .pipe(webpack({watch: true}))
    .pipe(gulp.dest('./build'));
});
koistya commented 10 years ago

It seems like the 'watch' option is already there just not documented? Can you please add an example to README.md showing how to use it?

escapedcat commented 10 years ago

This supported by webpack in the first place anyway, right? http://webpack.github.io/docs/configuration.html#watch The gulp plugin is just passing through the config. I assumed whatever I find on the webpack configuration page I can use with this plugin as well. I don't think this plugin needs to mention this option again. I'm just thinking if the watch shouldn't be done by gulp in the first place. But I'm not there yet.

escapedcat commented 10 years ago

Sorry if this is off topic but wanted to share it

Ok, no, using gulp watch is re-starting the webpack task every time which is slower than using the webpack watch task itself. Should have known it before... using the watch option now.

But I think the output information of that option is limited in a way. Using the config option of webpack inside gulp...

        {
            output: {
                filename: "bundle.js"
            },
            devtool: "#source-map",
            watch: true
        }

...I get this:

[05:38:55] Version: webpack 1.4.3
        Asset     Size  Chunks             Chunk Names
    bundle.js  2074974       0  [emitted]  main
bundle.js.map  2426209       0  [emitted]  main

If I use the CLI of webpack I get more info on the watch process. Like this for example: webpack ./app/js/main.js ./app/js/bule.js --progress --colors -d --watch With this I get:

Time: 5559ms
        Asset     Size  Chunks             Chunk Names
    bundle.js  2077879       0  [emitted]  main
bundle.js.map  2426260       0  [emitted]  main
   [0] ./app/js/main.js 588 {0} [built]
   [1] ./app/js/app.js 999 {0} [built]
   [2] ./app/js/controllers.js 341 {0} [built]
    + 7 hidden modules

The progress option does not seem to be supported using the config-object.

stream7 commented 10 years ago

I tried the watch option with v1.0.0 and it works great :+1:

Devric commented 10 years ago

is there a way i can trigger watch to stop

im trying to use gulp-watch to glob the files, so that it can rerun webpack when adding new files

tinchoz49 commented 9 years ago

Using something like this:

gulp.task('webpack:build-dev', function() {
  return gulp.src('index.js')
    .pipe(webpack({watch: true}))
    .pipe(gulp.dest('dist/'));
});

I get this on my termina:

[23:51:20] Webpack is watching for changes
[23:51:20] Webpack is watching for changes
[23:51:20] Webpack is watching for changes
[23:51:20] Webpack is watching for changes
[23:51:20] Webpack is watching for changes
[23:51:20] Webpack is watching for changes
[23:51:20] Webpack is watching for changes
[23:51:20] Webpack is watching for changes

.....

I don't know why but the watch is not working ok.

frank-weindel commented 9 years ago

I'm getting the repeated console output that @tinchoz49 mentioned. The watch seems to be working though, but it causes webpack's actual output to quickly scroll off screen.

moimikey commented 9 years ago

i did mine this way:

var extend = require('lodash').extend;

gulp.task('build', ['lint'], function() {
  return gulp.src(settings.paths.source.lib)
    .pipe(plugin.plumber())
    .pipe(plugin.webpack(webpack))
    .pipe(gulp.dest(settings.paths.destination.bundle));
});

gulp.task('watch', ['lint'], function() {
  return gulp.src(settings.paths.source.lib)
  .pipe(plugin.plumber())
  .pipe(plugin.webpack(extend({}, webpack, { watch: true })))
  .pipe(gulp.dest(settings.paths.destination.bundle));
});
MadLittleMods commented 9 years ago

.pipe(webpack({watch: true})) works but it seems to stop(never run on file changes) my separate other gulp.watch tasks. My watch tasks work completely fine when I don't run the gulp-webpack task.

I would really like to use webpacks's watch ecosystem for the speed.

alex6o commented 9 years ago

hi! I am also searching for an working example how to use the watch function together with webpack-stream. At the moment I have the problem that the first pass generates the expected output, further changes are detected but the updates are not written into the file!

iby commented 8 years ago

:+1:

julius-retzer commented 8 years ago

+1

yu521088 commented 8 years ago

I tried this way:

var webpack = require('webpack');
var path = require('path');
// var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');

module.exports = {
  entry: {
    index: ['webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/dev-server',
    './src/js/index.js']
    // index: './src/js/index.js'
  },
  output: {
    path: path.resolve(__dirname, 'build/js/'),
    filename: '[name].js'
  },
  resolve: {
    extensions: ['', '.js', '.jsx', '.less']
  },
  module: {
    loaders: [{
      test: /\.js$/,
      include: [path.join(__dirname, 'src')],
      loaders: ['react-hot', 'babel-loader?presets[]=react,presets[]=es2015']
    },
    { test: /\.css$/, loader: "style!css" },
    { test: /\.less$/, loader: "style!css!less" }]
  },
  watch: true,
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ]
  // plugins: [commonsPlugin]
};

and add gulp task:

gulp.task('webpack-dev-server', function(callback) {
    // modify some webpack config options
    var myConfig = Object.create(webpackConfig);
    myConfig.devtool = 'eval';
    myConfig.debug = true;

    // Start a webpack-dev-server
    new WebpackDevServer(webpack(myConfig), {
        // publicPath: '/' + myConfig.output.publicPath,
    contentBase: './build/',
        stats: {
            colors: true
        },
    hot: true
    }).listen(8080, 'localhost', function(err) {
        if(err) throw new gutil.PluginError('webpack-dev-server', err);
        gutil.log('[webpack-dev-server]', 'http://localhost:8080/webpack-dev-server/index.html');
    });
});

It doesn't work, it only works for gulp watch, which is not what i want and it's quit slow:

gulp.task('build-dev', ['html-minify', 'webpack:build-dev'], function() {
     gulp.watch(['src/**/*'], ['webpack:build-dev']);
});
gregorybolkenstijn commented 8 years ago

I also can't seem to find a way to get the watch working with Gulp. Only the first run works, after that nothing happens and it blocks my other tasks.

MarkLeMerise commented 8 years ago

I am experiencing the same issue as @gregorybolkenstijn. I can pass in watch: true and I get a console message saying that webpack is watching but it blocks the rest of my pipeline. I tried using gulp-plumber per @moimikey's suggestion but saw the same results.

ElsewhereGames commented 8 years ago

@MarkLeMerise Are you return-ing the gulp pipeline? Instead of:

gulp.task(
  'deploy-typescript',
  function() {
    return gulp.src('app.js')
      .pipe(webpackStream(webpackConfiguration))
      .pipe(gulp.dest('bundle.js'));
  }
);

Try:

gulp.task(
  'deploy-typescript',
  function() {
    gulp.src('app.js')
      .pipe(webpackStream(webpackConfiguration))
      .pipe(gulp.dest('bundle.js'));
  }
);
ElsewhereGames commented 8 years ago

I just noticed that what I suggest will only work when you intend to run an actual server, since that task never returns. If you just want to a one-off build, the task will block indefinitely.

dlebedynskyi commented 8 years ago

having simmilar issue. with watch:true webpack crushed on first error and terminates whole task. gulp-webpack could still continue working

samanime commented 8 years ago

I did some testing.

With just {watch:true} passed to the call, it built and watched.

With this config passed:

{
    watch: true,
    context: __dirname + "/app/www/scripts",
    entry: "./app.js",
    output: {
        path: __dirname + "/dist/www/scripts",
        filename: "app.js"
    }
}

it built but did NOT watch.

With this config:

watch: true,
    entry: __dirname + "/app/www/scripts/app.js",
    output: {
        path: __dirname + "/dist/www/scripts",
        filename: "app.js"
    },

it built and watched. Notice the lack of context and the changed entry value.

It seems like the watcher gets some wires crossed with context.

On a side note, the "watch" portion of the documentation (http://webpack.github.io/docs/configuration.html#watch) gets removed with JavaScript for some reason. If you disable JavaScript and load the page, it's there. No clue what that's about.

MarkLeMerise commented 8 years ago

@ElsewhereGames Yes, I was returning the pipeline.

abjrcode commented 8 years ago

Hey gents, I use the watch option and it was working fine, until I started passing an array of configurations to webpack and then it doesn't work anymore. Is that supported for an array of configurations ?

I have something like this:

gulp.task('webpack', ['clean'], function() {

  return webpack([gonfigA, gonfigB, gonfigC], function(err, stats) {

      if (err) throw new gutil.PluginError("webpack", err);

      gutil.log("[webpack]", stats.toString({
        chunks: false,
        colors: true
      }));

      gutil.log("[webpack]", "Gonna sit around and watch for file changes. CTRL^C to kill me");
  });

});

NOTE: I am not using the webpack dev server and don't have the intention to.

wphampton commented 8 years ago

Perhaps this will help someone else. I thought I'd share since the above conversation helped me out along my way. https://github.com/shama/webpack-stream/issues/105#issuecomment-219740738

zaqqaz commented 8 years ago
if (errors.length) {
        var errorMessage = errors.reduce(function (resultMessage, nextError) {
          resultMessage += nextError.toString();
          return resultMessage;
        }, '');

        self.emit('error', new gutil.PluginError('webpack-stream', errorMessage));
      }

If use ts-loader , after first error in watch mode, code above emit error, after that, dest pipe (all below) no longer work, while webpack is watching for changes.

.pipe(webpackStream(webpackOptions, null, webpackChangeHandler))
.pipe(gulpDest)
jmurzy commented 8 years ago

For those of you who are still having issues with Weback watch, I created a PR that should address this in a more gulp friendly way. See #109. Let me know how this works for you guys.

🍺

riccardolardi commented 8 years ago

Sorry, newbie here - so am I right, there's currently no way to use webpack in cached & therefore fast watch mode from within gulp? My ideal workflow involves using webpack just for transpiling and module loading and then gulp for building and bundling etc. Hope @jmurzy's PR gets accepted to solve the issue!

mikemcguire commented 8 years ago

@alberto2000 You can, just use separate tasks. If you have a watch-styles task and a watch-js task, you then make them a dependency on a watch task that will run both of them separately.

AlesRFK commented 7 years ago

If you cancel --watch function how long does it take to cancel? Mine is like 60s or more.

cowwoc commented 3 years ago

@shama While I appreciate @jmurzy trying to help by contributing #109 it doesn't really solve the problem. In my view it only makes matters worse by leading users to the wrong solution.

If you try running webpack.watch() without this plugin versus using this plugin with the approach in #109 you will notice a 10x performance decrease. On my end, webpack.watch() takes 100ms and #109 takes 1-2 seconds.

There is a lingering problem with passing watch: true using this plugin: https://github.com/shama/webpack-stream/issues/230

Once that's fixed we should be good to go.

julianmesa-gitkraken commented 3 years ago

@shama @MarkLeMerise @cowwoc Finally I have found the problem about watch. You have to call to the callback to close the task and contnue the pipeline Can you update the readme? Example:

const gulp = require('gulp');
const webpack = require('webpack-stream');
gulp.task('default', function(cb) {
  gulp.src('src/entry.js')
    .pipe(webpack({
    watch: true,
    ............
    }))
    .pipe(gulp.dest('dist/'));
  cb();
});