Closed josephdburdick closed 9 years ago
Does express need to be handled within the gulpfile? or does the live reloading of LESS or SASS need to be handled within keystone.init()?
have you read https://github.com/vohof/gulp-livereload ?
@morenoh149 Yes I have tried both liveReload and BrowserSync implementations inside of Keystone, listening to file changes with gulp watch. I have also tried to capture the express instance via Gulp but I believe now that I might have it backwards and need to trigger the live reloading from Keystone.init(). I feel that my lack of middleware knowledge is preventing me from seeing this completely through. If you have any pointers, anything that would enlighten me I would be very grateful.
TL,DR; Is there some kind of explanation on how Middleware would be the interface for auto-reloading instead of rigging the present gulpfile?
The closest tutorial I've found is this: https://community.nitrous.io/tutorials/setting-up-gulp-with-livereload-sass-and-other-tasks Since it accesses express from Gulp. But my gut tells me that I shouldn't mess with express because Keystone handles that so my next instinct is to find out how to control this with middleware. Has anyone used middleware to capture the sass compilation event? This event could then trigger the injection/reload.
Have you tried something like this?
if(process.env.NODE_ENV==="development") {
keystone.app.use(require('node-sass-middleware'));
}
Haven't got the time to spike it, but this is how I'd approach it.
@josephdburdick I feel like doing livereload may be prohibitively difficult because keystone is running its own webserver. I did however get sass file watching working and regenerated locally so you can just refresh the browser in development. I'll be submitting this to the https://github.com/keystonejs/generator-keystone project soon
Ok, @morenoh149, thanks for the attempt. I was also able to have keystone regenerate sass on save and be able to see changes after refreshing. I guess I've been spoiled by front-end workflows the past couple years and also my development with Meteor.js. Keystone looks like it should be able to achieve the same kind of refresh but I just can't figure out how. I see other contributors focusing on React, maybe the potential reactivity will naturally produce more demand for a feature like this.
Some thoughts.
If you don't want to pay for livereload you're directed to https://github.com/guard/guard-livereload which is a ruby based tool. I think it wouldn't be welcome to add such a dependency (encourage is the same thing) to a javascript project like keystone.
We'd sooner use something like the webpack dev server https://webpack.github.io/docs/webpack-dev-server.html or something custom working with browserify. Closing because I don't think livereload specifically is the correct tool. But you're welcome to make a new issue requesting browsersync/webpack/etc. This thread should probably also be moved to the generator repo as it's concerned with usage rather than an issue with keystone itself.
oh wait I misread the issue title. I thought you were insisting on using livereload. We should explore browserSync in proxy mode.
I'm on a rollercoaster of emotion. Yeah, I think Browserify should be able to handle it somehow.
Jumping off from the suggestion of @creynders above, the following worked for me. I assume by live reload you just want to watch for source changes, not automatically reload the browser window.
I've placed this right before keystone.start();
in keystone.js.
if (keystone.get('env') === 'development') {
keystone.app.use(sassMiddleware({
src: path.join(__dirname, 'public'),
dest: path.join(__dirname, 'public'),
debug: true,
force: true
}));
}
UPDATE
This is more succinct. (And avoids the need to import the sass-middleware and path modules.)
if (keystone.get('env') === 'development') {
keystone.set('sass options', {
debug: true,
force: true
});
}
Just to clarify, when I say live reloading I am mean injecting style changes when CSS files are generated. This means upon generating a new css file from sass, less, stylus, etc the style would change in the page without refreshing or changing state. @dlwalsh I'll give your method a shot when I return to my machine.
@josephdburdick the following gulpfile does what you want. Adding this task the gulpfile in generator-keystone
will wait until I get my previous PR merged.
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var jshintReporter = require('jshint-stylish');
var watch = require('gulp-watch');
var sass = require('gulp-sass');
var shell = require('gulp-shell')
var bs = require('browser-sync').create();
var paths = {
'src':['./models/**/*.js','./routes/**/*.js', 'keystone.js', 'package.json'],
'style': {
all: './public/styles/**/*.scss',
output: './public/styles/'
}
};
// gulp lint
gulp.task('lint', function(){
gulp.src(paths.src)
.pipe(jshint())
.pipe(jshint.reporter(jshintReporter));
});
// gulp watcher for lint
gulp.task('watch:lint', function () {
gulp.src(paths.src)
.pipe(watch())
.pipe(jshint())
.pipe(jshint.reporter(jshintReporter));
});
gulp.task('sass', function(){
gulp.src(paths.style.all)
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest(paths.style.output))
.pipe(bs.stream());
});
gulp.task('watch:sass', function () {
gulp.watch(paths.style.all, ['sass']);
});
gulp.task('browser-sync', function(){
bs.init({
proxy: 'http://localhost:3000',
port: '4000'
});
});
gulp.task('runKeystone', shell.task('node keystone.js'));
gulp.task('watch', ['watch:sass', 'watch:lint']);
gulp.task('default', ['watch', 'runKeystone', 'browser-sync']);
usage, run gulp
Wow, I can't wait to try this. I'll report back the results today. Thanks! :metal:
@morenoh149 I followed your directions and got the following error:
➜ keystone-adoptive gulp
[15:41:40] Using gulpfile /Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/gulpfile.js
[15:41:40] Starting 'watch:sass'...
[15:41:40] Finished 'watch:sass' after 78 ms
[15:41:40] Starting 'watch:lint'...
[15:41:40] Finished 'watch:lint' after 25 ms
[15:41:40] Starting 'watch'...
[15:41:40] Finished 'watch' after 5.9 μs
[15:41:40] Starting 'runKeystone'...
[15:41:40] Starting 'browser-sync'...
[15:41:40] Finished 'browser-sync' after 12 ms
/Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/models/Enquiry.js
line 24 col 27 Unexpected 'default'.
line 24 col 27 Expected an identifier and instead saw 'default' (a reserved word).
✖ 2 problems
[BS] [info] Proxying: http://localhost:3000
[BS] Access URLs:
-----------------------------------
Local: http://localhost:4000
External: http://10.0.1.202:4000
-----------------------------------
UI: http://localhost:3001
UI External: http://10.0.1.202:3001
-----------------------------------
/Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/models/Gallery.js
line 15 col 31 Unexpected 'default'.
line 15 col 31 Expected an identifier and instead saw 'default' (a reserved word).
✖ 2 problems
/Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/models/Post.js
line 16 col 70 Unexpected 'default'.
line 16 col 70 Expected an identifier and instead saw 'default' (a reserved word).
✖ 2 problems
/Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/routes/views/blog.js
line 33 col 61 Expected an identifier and instead saw 'in' (a reserved word).
line 73 col 26 Expected an identifier and instead saw 'in' (a reserved word).
✖ 2 problems
/Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/routes/emails.js
line 38 col 0 Identifier 'enquiry_url' is not in camel case.
✖ 1 problem
/Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/keystone.js
line 43 col 10 Expected an identifier and instead saw 'import' (a reserved word).
line 65 col 0 Identifier 'logo_src' is not in camel case.
line 66 col 0 Identifier 'logo_width' is not in camel case.
line 67 col 0 Identifier 'logo_height' is not in camel case.
line 69 col 0 Identifier 'email_bg' is not in camel case.
line 70 col 0 Identifier 'link_color' is not in camel case.
line 73 col 0 Identifier 'background_color' is not in camel case.
line 74 col 0 Identifier 'border_color' is not in camel case.
line 87 col 34 Expected '===' and instead saw '=='.
line 90 col 34 Expected '===' and instead saw '=='.
✖ 10 problems
[15:41:42] ../../15 files was added from pipe
dyld: lazy symbol binding failed: Symbol not found: _node_module_register
Referenced from: /Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/node_modules/keystone/node_modules/watchify/node_modules/chokidar/node_modules/fsevents/build/Release/fse.node
Expected in: dynamic lookup
dyld: Symbol not found: _node_module_register
Referenced from: /Applications/MAMP/htdocs/Code/Github/josephdburdick/js/node/apps/keystone-adoptive/node_modules/keystone/node_modules/watchify/node_modules/chokidar/node_modules/fsevents/build/Release/fse.node
Expected in: dynamic lookup
[15:41:44] 'runKeystone' errored after 3.42 s
[15:41:44] Error in plugin 'gulp-shell'
Message:
Command `node keystone.js` failed with exit code
Any thoughts?
Solution found, as referenced here: https://github.com/BrowserSync/browser-sync/issues/443
I can confirm that sass reloading now works as long as viewing on port 4000 despite the console stating the site is ready on port 3000.
@josephdburdick right, because the keystone webserver is still at 3000 and browsersync is simply proxying it to 4000. We could fix that if many users want to use this setup.
Cool, good to know. So I guess the only thing I didn't have right was the proxy part. Thanks for inspecting this, I'm looking forward to your PR being merged in the generator!
Has there been any movement on this? Thanks.
@niallobrien you get it when you use the generator https://github.com/keystonejs/generator-keystone/blob/master/app/templates/_gulpfile.js#L65
@morenoh149 Thanks for clarifying.
@morenoh149 I'm trying to use your gulp file with keystone 4.0 beta. I've installed the requirements. Can't figure out how to fix this...
% gulp
[14:17:01] Using gulpfile ~/Sites/keystone/gulpfile.js
[14:17:01] Starting 'watch:sass'...
[14:17:01] Finished 'watch:sass' after 69 ms
[14:17:01] Starting 'watch:lint'...
[14:17:01] 'watch:lint' errored after 14 ms
[14:17:01] Error in plugin 'gulp-watch'
Message:
glob argument required
Using gulp 3.9.1 and node 5.9.0
var gulp = require('gulp');
var server = require('gulp-express');
var browserSync = require('browser-sync').create();
gulp.task('serve', function() {
server.run(['keystone.js']);
setTimeout(function() {
browserSync.init({
proxy: 'http://localhost:3000',
port: '4000'
});
}, 3000); //Gotta let the Keystone Server actually begin ( you may need to increase this value depending on computer power)
});
Obviously anything using setTimeout is just... bad, but this'll work. Depending on your system you may want to increase the timeout. run with gulp serve
Just run it in a separate terminal session after you've started Keystone and remove the setTimeout()
.
I have LiveReload working for both styles and templates here is my gulpfile.js just run gulp and yes you must install LiveReload plugin for chrome.
var gulp = require('gulp');
var jslint = require('gulp-jslint');
var watch = require('gulp-watch');
var sass = require('gulp-sass');
var process = require('process');
var livereload = require('gulp-livereload');
var nodemon = require('nodemon');
var gulphb = require('gulp-handlebars');
var paths = {
'src':['./models/**/*.js','./routes/**/*.js', 'keystone.js', 'package.json'],
'templates':['./templates/**/*.hbs'],
'style': {
all: './public/styles/**/*.scss',
output: './public/styles/'
}
};
gulp.task('lint', function(){
gulp.src(paths.src)
.pipe(jslint())
});
gulp.task('watch:lint', function () {
gulp.src(paths.src)
.pipe(watch())
.pipe(jslint())
});
gulp.task('sass', function(){
gulp.src(paths.style.all)
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest(paths.style.output))
.pipe(livereload());
});
gulp.task('templates', function(){
gulp.src('./templates/**/*.hbs')
.pipe(gulphb())
.pipe(livereload());
});
gulp.task('watch', function () {
livereload.listen();
gulp.watch(paths.style.all, ['sass']);
gulp.watch(paths.templates, ['templates']);
gulp.watch([paths.src], ['lint']);
nodemon({
script: 'keystone.js',
stdout: false
}).on('readable', function() {
this.stdout.on('data', function(chunk) {
if (/^listening/.test(chunk)) {
livereload.reload()
}
process.stdout.write(chunk)
})
})
});
gulp.task('default', ['lint', 'watch']);
@morenoh149
AssertionError [ERR_ASSERTION]: Task function must be specified , on running gulp
Hi, I've done this with Gulp projects before but it seems like no matter what I try I cannot get live reloading to work with Keystone. If there is documentation on this somewhere you could direct me to, I'll gladly inspect.
So far the gulpfile.js in my project looks like this:
Running
gulp start
fires everything off.