BrowserSync.reload causes "write after end" during gulp task - gulp

I am trying to get browserSync to work with a watch task for a Polymer app. Here is my gulp file:
function source() {
return project.splitSource()
.pipe(gulpif('**/*.html', html.lint())).on('end', log('Linted HTML'))
.pipe(gulpif('**/*.html', html.minify())).on('end', log('Minified HTML'))
.pipe(gulpif('**/*.js', javascript.minify())).on('end', log('Minified Javascript'))
.pipe(gulpif('**/*.js', javascript.babelify())).on('end', log('Transpiled Javascript'))
.pipe(gulpif('**/*.{gif,jpg,svg}', images.minify())).on('end', log('Minified Images'))
.pipe(project.rejoin()); // Call rejoin when you're finished
}
function dependencies() {
return project.splitDependencies()
.pipe(project.rejoin());
}
gulp.task('default', gulp.series([
clean.build,
project.merge(source, dependencies),
project.serviceWorker
]));
gulp.task('reload', function(){
browserSync.reload();
} );
gulp.task('dev', gulp.series(
project.merge(source, dependencies)
));
gulp.task('browser-sync', function(){
return new Promise(function(resolve){
resolve( browserSync({
port: 5000,
notify: false,
logPrefix: 'PSK',
snippetOptions: {
rule: {
match: '<span id="browser-sync-binding"></span>',
fn: function(snippet) {
return snippet;
}
}
},
server: {
baseDir: ['./'],
}
})
)
});
})
gulp.task('watch', function(){
gulp.watch(['**/*.html'], gulp.series('dev','reload'));
gulp.watch(['**/*.js'], gulp.series('dev', 'reload'));
});
gulp.task('serve',
gulp.series(
'dev',
gulp.parallel('browser-sync','watch')), function(){
return gulp.src('**/*.html', {passthrough:true})
}
);
The project.splitSource is a polymer starter kit specific function that splits web components into seperate html , css, js entities so you can perform whatever tasks you need on them.
When I run 'gulp serve' , the tasks complete and my app is served.
As soon as I change the contents of a file, the watch runs the 'dev' task and attempts to run the reload task, and thats where it crashes. Here is the command line messages for this entire process :
→ gulp serve
[08:53:43] Using gulpfile ~/Documents/Projects/unicef/etools-dashboard/gulpfile.js
[08:53:43] Starting 'serve'...
[08:53:43] Starting 'dev'...
[08:53:43] Starting 'output'...
[08:55:20] Linted HTML
[08:55:20] Minified HTML
[08:55:20] Minified CSS
[08:55:20] Minified Javascript
[08:55:20] Transpiled Javascript
[08:55:20] gulp-imagemin: Minified 511 images (saved 212 kB - 3.1%)
[08:55:20] Minified Images
[08:55:29] Finished 'output' after 1.75 min
[08:55:29] Finished 'dev' after 1.75 min
[08:55:29] Starting 'browser-sync'...
[08:55:29] Starting 'watch'...
[08:55:30] Finished 'browser-sync' after 551 ms
[PSK] Access URLs:
--------------------------------------
Local: http://localhost:5000
External: http://192.168.0.102:5000
--------------------------------------
UI: http://localhost:3001
UI External: http://192.168.0.102:3001
--------------------------------------
[PSK] Serving files from: ./
[08:56:20] Starting 'dev'...
[08:56:20] Starting 'output'...
[08:56:20] Finished 'output' after 288 ms
[08:56:20] Finished 'dev' after 290 ms
[08:56:20] Starting 'reload'...
[PSK] Reloading Browsers...
Error: write after end
at writeAfterEnd (_stream_writable.js:159:12)
at StreamAnalyzer.Writable.write (_stream_writable.js:204:5)
at PassThrough.ondata (/Users/Marko1/Documents/Projects/unicef/etools-dashboard/node_modules/merge-stream/node_modules/readable-stream/lib/_stream_readable.js:546:20)
at emitOne (events.js:77:13)
at PassThrough.emit (events.js:169:7)
at readableAddChunk (/Users/Marko1/Documents/Projects/unicef/etools-dashboard/node_modules/merge-stream/node_modules/readable-stream/lib/_stream_readable.js:217:18)
at PassThrough.Readable.push (/Users/Marko1/Documents/Projects/unicef/etools-dashboard/node_modules/merge-stream/node_modules/readable-stream/lib/_stream_readable.js:176:10)
at PassThrough.Transform.push (/Users/Marko1/Documents/Projects/unicef/etools-dashboard/node_modules/merge-stream/node_modules/readable-stream/lib/_stream_transform.js:123:32)
at afterTransform (/Users/Marko1/Documents/Projects/unicef/etools-dashboard/node_modules/merge-stream/node_modules/readable-stream/lib/_stream_transform.js:79:51)
at TransformState.afterTransform (/Users/Marko1/Documents/Projects/unicef/etools-dashboard/node_modules/merge-stream/node_modules/readable-stream/lib/_stream_transform.js:58:12)
[08:56:21] The following tasks did not complete: serve, <parallel>, watch, <series>, reload
[08:56:21] Did you forget to signal async completion?
Any idea why the reload causes this to crash? I've googled this "write after end" and seems like the stream needs to be returned or async actions need an explicit done cb, but I'm not sure how to do that with gulp 4. Any advice would be of great help.

Related

Why does gulp watch continuously output starting\finished to terminal

After migrating gulp to gulp 4, terminal continuously outputs "Starting" and "Finished" after a single change\save to a scss file. Is this normal? The script is doing it's job, but the infinite output does not seem right. My script is small, so maybe someone sees something that I do not. My site is running on localhost IIS 7.5 website with bindings set to IP address.
Help is much appreciated. Thanks!
The only gulp migration added is gulp.series('css')
var sitename = 'mysitename';
var gulp = require('gulp'),
autoprefixer = require('autoprefixer'),
browserSync = require('browser-sync').create(),
postcss = require('gulp-postcss'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps'),
newer = require('gulp-newer'),
// Name of working theme folder
root = '../' + sitename + '/',
scss = root + 'sass/';
// CSS via Sass and Autoprefixer
gulp.task('css', function() {
return gulp.src(scss + '{style.scss,rtl.scss}')
.pipe(sourcemaps.init())
.pipe(sass({
outputStyle: 'compressed',
indentType: 'tab',
indentWidth: '1'
}).on('error', sass.logError))
.pipe(postcss([
autoprefixer('last 2 versions', '> 1%')
]))
.pipe(sourcemaps.write(scss + 'maps'))
.pipe(gulp.dest(root + '/dist/css/'))
//.pipe(browserSync.stream());
});
// Watch everything
gulp.task('watch', function() {
browserSync.init({
open: 'external',
host: 'example.com',
proxy: 'example.com',
port: 80
});
gulp.watch([root + '**/*.css', root + '**/*.scss' ], gulp.series('css') );
gulp.watch(root + '**/*').on('change', browserSync.reload);
});
gulp.task('default', gulp.series('watch') );
If my style.scss file is saved, terminal output continues infinitely...
C:\Workspace\mysite\gulp-dev>gulp
[12:00:37] Using gulpfile
C:\Workspace\mysite\gulp-dev\gulpfile.js
[12:00:37] Starting 'default'...
[12:00:37] Starting 'watch'...
[Browsersync] Proxying: http://example.com
[Browsersync] Access URLs:
-----------------------------------
Local: http://localhost:81
External: http://example.com:81
-----------------------------------
UI: http://localhost:3001
UI External: http://example.com:3001
-----------------------------------
[12:00:48] Starting 'css'...
[12:00:48] Finished 'css' after 117 ms
[12:00:48] Starting 'css'...
[12:00:48] Finished 'css' after 32 ms
[12:00:48] Starting 'css'...
[12:00:48] Finished 'css' after 55 ms
[12:00:48] Starting 'css'...
[12:00:48] Finished 'css' after 63 ms
[12:00:49] Starting 'css'...
[12:00:49] Finished 'css' after 26 ms
It is occurring because you are watching the folder you are outputting the css to:
gulp.watch([root + '**/*.css'
.pipe(gulp.dest(root + '/dist/css/')
If a "globstar" [the **] is alone in a path portion, then it matches zero or
more directories and subdirectories searching for matches.
"And subdirectories" is the part that is catching you. So your "root/**/.css" includes "root/dist/css". Everytime the 'css' task is riggered it writes to the folder you are watching again, so the task gets retriggered...etc. This is why you don't usually watch your entire root, just wherever the src is located and then write out to a different place.
glob primer

gulp-ruby-sass not working

I did everything exactly as stated in docs:
https://github.com/sindresorhus/gulp-ruby-sass/blob/master/readme.md
This is my code in gulpfile.js:
// Sass configuration
const gulp = require('gulp');
const sass = require('gulp-ruby-sass');
const sourcemaps = require('gulp-sourcemaps');
gulp.task('sass', () =>
sass('kraater-web/src/app/css/admin/vars.scss', {sourcemap: true})
.on('error', sass.logError)
// for inline sourcemaps
.pipe(sourcemaps.write())
// for file sourcemaps
.pipe(sourcemaps.write('maps', {
includeContent: false,
sourceRoot: 'source'
}))
.pipe(gulp.dest('kraater-web/src/app/css/'))
);
gulp.task('default', ['sass'], function() {
})
When I run it, I just get this output, and no files are generated:
[15:47:25] Using gulpfile C:\wamp\www\site17\gulpfile.js
[15:47:25] Starting 'sass'...
[15:47:25] Could not find an option named "sourcemap".
[15:47:25] Usage: sass <input.scss> [output.css]
sass <input.scss>:<output.css> <input/>:<output/>
=== Input and Output ===================
--[no-]stdin Read the stylesheet from stdin.
--[no-]indented Use the indented syntax for input from stdin.
-I, --load-path=<PATH> A path to use when resolving imports.
May be passed multiple times.
-s, --style=<NAME> Output style.
[expanded (default), compressed]
--update Only compile out-of-date stylesheets.
=== Source Maps ========================
--[no-]source-map Whether to generate source maps.
(defaults to on)
--source-map-urls How to link from source maps to source files.
[relative (default), absolute]
--[no-]embed-sources Embed source file contents in source maps.
--[no-]embed-source-map Embed source map contents in CSS.
=== Other ==============================
-i, --interactive Run an interactive SassScript shell.
-c, --[no-]color Whether to emit terminal colors.
-q, --[no-]quiet Don't print warnings.
--[no-]trace Print full Dart stack traces for exceptions.
-h, --help Print this usage information.
--version Print the version of Dart Sass.
[15:47:25] Finished 'sass' after 416 ms
[15:47:25] Starting 'default'...
[15:47:25] Finished 'default' after 11 μs
Watching build tasks has finished.
Ideas how to get it to work?

How to properly end a gulp task

I'm trying to write a gulp task to execute a program and to wait for any key to be pressed to exit the program.
So far I have this:
gulp.task('runDevelopment', function (done) {
console.log('\n\n---\nPress any key to exit\n---\n');
var api = spawn('node', ['node_modules/api-gateway-server/server.js', 'etc/swagger.yaml']);
api.stdout.on('data', function (data) {
console.log(data.toString());
});
api.stderr.on('data', function (data) {
console.log(data.toString());
});
process.stdin.on('data', function () {
api.kill('SIGKILL');
done();
});
});
This runs the program, and kills it as expected but gulp never quits. I see this in the console:
20:04 $ gulp
[20:06:54] Using gulpfile ~/Development/swiki/gulpfile.js
[20:06:54] Starting 'documentCopy'...
[20:06:54] Starting 'documentZip'...
[20:06:54] Starting 'runDevelopment'...
---
Press any key to exit
---
[20:06:54] Finished 'documentCopy' after 52 ms
[20:06:54] Finished 'documentZip' after 41 ms
[20:06:54] Starting 'package'...
[20:06:54] Finished 'package' after 4.9 μs
API Gateway server listening on port 7111
[20:06:57] Finished 'runDevelopment' after 3.06 s
[20:06:57] Starting 'run'...
[20:06:57] Finished 'run' after 2.72 μs
[20:06:57] Starting 'default'...
[20:06:57] Finished 'default' after 1.16 μs
Terminated: 15
✘-TERM ~/Development/swiki [master|…6]
20:07 $
gulp gives me the Terminated: 15 only after I killall gulp in another terminal.
How can I get this to work properly?
The problem is that you're successfully terminating the child process by sending SIGKILL, but you're still listening for incoming data on process.stdin of the parent process. As long as you are doing that the parent process won't exit.
You have to explicitly tell process.stdin to no longer emit 'data' events by calling stream.pause():
process.stdin.on('data', function () {
process.stdin.pause();
api.kill('SIGKILL');
done();
});
If all else fails you can also call process.exit() as a last resort:
process.stdin.on('data', function () {
api.kill('SIGKILL');
done();
process.exit(0);
});

Gulp browser-sync not injecting styles

I'm trying to get browser-sync to inject styles using gulp. I've pretty much copied and pasted from the tutorial, but nothing happens. The sass gets compiled correctly, but the injection doesn't happen. Any ideas what I've done wrong, or how to debug this?
I'm also using MAMP if it makes any difference at all.
My Gulp file:
var gulp = require('gulp'),
sass = require('gulp-sass'),
browserSync = require('browser-sync').create();
// Proxy Server
gulp.task('serve', ['sass'], function() {
browserSync.init({
proxy: "local.website.com"
});
gulp.watch('../css/source/*.scss', ['sass']);
});
// Compile sass into CSS & auto-inject into browsers
gulp.task('sass', function() {
return gulp.src('../css/source/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('../css/build'))
.pipe(browserSync.stream());
});
gulp.task('default', ['serve']);
The response in my console:
[gulp] Starting 'default'...
[gulp] Finished 'default' after 4.61 μs
[BS] Proxying: http://local.website.com
[BS] Access URLs:
-------------------------------------
Local: http://localhost:3000
External: http://192.168.8.12:3000
-------------------------------------
UI: http://localhost:3001
UI External: http://192.168.8.12:3001
-------------------------------------
[gulp] Starting 'sass'...
[BS] 1 file changed (main.css)
[gulp] Finished 'sass' after 114 ms
[gulp] Starting 'sass'...
[BS] 1 file changed (main.css)
[gulp] Finished 'sass' after 115 ms
If it matters, here is my package.json:
{
"devDependencies": {
"browser-sync": "^2.9.11",
"gulp": "^3.9.0",
"gulp-sass": "^2.0.4"
}
}
The problem in my case was Drupal - it uses #import instead of link to add CSS files. This module solves it! https://www.drupal.org/project/link_css
You say you've copy pasted from the tutorial, but you didn't copy this part that actually notifies browserSync of changes:
gulp.watch('../css/source/*.scss').on('change', browserSync.reload);

gulp-watch works only on initial run

What I do?
Run gulp (SCSS files are being processed, I get a CSS file)
I change any SCSS file again
Expected:
CSS file from 1. is updated with the changes from 2.
What happens?
CSS file from 1. isn't changed
Command line output:
$ gulp
[09:24:28] Using gulpfile c:\Users\User\_dev\github\project\gulpfile.js
[09:24:28] Starting 'sass'...
[09:24:28] Finished 'sass' after 98 ms
[09:24:28] Starting 'default'...
[09:24:28] Finished 'default' after 7.31 μs
[09:24:35] sass-watch saw _base.scss was changed
[09:25:39] sass-watch saw _base.scss was changed
gulpfile.js:
gulp.task('sass', function() {
watch({ glob: 'css/**/*.{scss,sass}', name: 'sass-watch'})
.pipe(plumber())
.pipe(sass())
.pipe(gulp.dest('css'))
});
gulp.task('default', ['sass']);
Notes:
Issue on GitHub (gulp)
Issue on GitHub (gulp-watch)
gulpfile.js on GitHub Gist)
OS: Win7
node: 0.10.29
npm: 1.4.14
The way the source files are piped in is not important. The result stays the same when using gulp.src()
I dont think your sass task is correctly written.
Try something like this:
var gulp = require('gulp');
var sass = require('gulp-sass')
gulp.task('sass', function () {
gulp.src('PATH-TO-SASS-FILES/*.scss')
.pipe(sass())
.pipe(gulp.dest('./css'));
});