Grunt Livereload and MAMP - gruntjs

I'm trying to use gruntjs livereload with a wordpress theme development.
For WP theme development I would normally use MAMP and view the site at localhost in the browser.
If I'm using grunt to create a server do I still need MAMP running.
Do I still need the wordpress folder in the MAMP root folder to connect to the database.
I'm using this simple gruntfile.js that is in the root of the wordpress folder but if I run grunt the browser loads but loads a search engine searching for 0.0.0.0
'use strict';
module.exports = function(grunt){
require('load-grunt-tasks')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
connect: {
options: {
port: 9000,
},
livereload: {
options: {
open: true,
}
}
}
});
grunt.registerTask('default', ['connect']);
}
Is it possible to use grunt livereload with Wordpress without using MAMP.
I've been trying to work this out all day - any help would be greatly appreicated.

Hey so I was also running into this issue and I couldn't get it to work? I feel it has something to do with the fact that MAMP runs your PHP server on a different port. Perhaps you can make your default to port 35729 because that's where the script lives
A really hackish workaround I did was I created a little PHP script that inserts itself when on localhost. I also check to make sure a variable is declared.
livereload.php
<?php
// Live reload script added only on localhost and if $livereload set to true
// add specific whitelist options
$whitelist = array(
'127.0.0.1',
'::1',
'localhost'
);
if(in_array($_SERVER['REMOTE_ADDR'], $whitelist) && isset($livereload)){
echo '<script src="http://localhost:35729/livereload.js?snipver=1"></script>';
}
?>
In my main PHP file, I would do something like
index.php
<?php
$livereload = true;
?>
// Markup, content
<?php
include_once('livereload.php');
?>
Hope this helps.

I'm not sure I understood your problem completely, but you won't be able to run wordpress on "grunt" server, cause node server is in JS and does not support PHP nor mysql (out of the box at least), i can help you to have a working mamp + watch setup
so to have a proper setup including mamp and grunt taking your example as a basis
'use strict';
module.exports = function(grunt){
require('load-grunt-tasks')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: {
livereload: true,
},
files: {
files: ['theDirYouWantToReload/*.scss'], // or whaterver globbing pattern you would need
tasks: ['yourNeededTask'],
},
}
});
grunt.registerTask('default', ['watch']);
}
you should have a look at grunt-watch-repo for additional information on how watch and reload works.
this was the grunt part, on the WP side you should add the livereload script to your pages
2 solution here, use the browser's extension of LR, and activate it on the browser when you look at these pages, or add the live reload script to WP enqueue
the default address of the script is http://localhost:35729/livereload.js?snipver=1
this is a barebone example, you can fine grain actions on the watch task.

Related

Running grunt sub task inside a custom module

I'm building a grunt module to help me to initialize, create default folder/files and build some WebProjects. I create a custom Grunt module including some custom tasks.
So My module is oshell.grunt and inside this module I've a task InitializeLibrary. This InitializeLibrary is a custom task that request some input from the user before creating the files/folder structure. I use grunt-prompt for this.
My problem is when I run the custom module inside my main project, the task prompt is not found. Can you please share your experience regarding this because I suppose some developers were faced to the same problem
Custom module structure
oshell.grunt
tasks
InitializeLibrary.js
After installing the custom module inside the Main projects
Main projects
oshell.core
node_modules
oshell.grunt
tasks
InitializeLibrary.js
It seems to be ok.
InitializeLibrary.js
module.exports = function(
grunt
){
"use strict";
grunt.initConfig({
"prompt": {
"libraryInfo": {
options: {
questions: [
{
config: "InitializeOpenShellLibrary.version",
type: "input",
message: "Initial version of the library",
default: "0.1.0"
}
]
}
}
}
});
require("load-grunt-subtasks")(grunt);
grunt.registerTask(
"InitializeLibrary",
[
"prompt:libraryInfo"
]
);
}
Main web project grunt file
module.exports = function(
grunt
){
"use strict";
grunt.loadNpmTasks("oshell.grunt");
grunt.registerTask("default", ["InitializeLibrary"]);
};
When I run this grunt in my main project I get this result.
Warning: Task "prompt:libraryInfo" not found. Use --force to continue.
I expected the task prompt to run inside the custom module for having a prompt for the library information.
Thanks a lot for your answers guys.
please install https://www.npmjs.com/package/grunt-prompt and add this code in grunt config file:
grunt.loadNpmTasks('grunt-prompt');

Gulp's browser-sync with MAMP, images are not loaded

I'm new with gulp and I hope I explain myself clearly.
I'm using gulp's browser-sync with MAMP to create a WordPress theme. When browser-sync is executed through gulp task, my WordPress site opens under localhost:3000/mytheme but without images because images are inside localhost:8888... What I'm doing wrong?
gulpfile.js is inside my theme folder:
htdocs/wordpress/wp-content/themes/mytheme/gulpfile.js
MAMP settings,
Apache port: 8888 / Nginx port: 8888 / MySQL port: 8889
gulpfile.js
var gulp = require('gulp'),
watch = require('gulp-watch'),
postcss = require('gulp-postcss'),
autoprefixer = require('autoprefixer'),
cssvars = require('postcss-simple-vars'),
nested = require('postcss-nested'),
cssImport = require('postcss-import'),
browserSync = require('browser-sync').create();
gulp.task('style', function(){
return gulp.src('./modules/style/style.css')
.pipe(postcss([cssImport, cssvars, nested, autoprefixer]))
.pipe(gulp.dest('./'));
});
gulp.task('browser-sync', function () {
var files = [
'./*.php',
'./style.css'
];
browserSync.init(files, {
proxy: "localhost:8888/my-theme",
});
});
gulp.task('watch', function(){
watch('./modules/style/**/*.css', function(){
gulp.start('style');
});
});
gulp.task('default', ['style', 'browser-sync', 'watch'], function(){
gulp.watch('./modules/style/**//**.css', ['watch']);
});
Now I can run Mamp/Wordpress with Gulp and here is how I've done...
Firstly I setted up a vhost with Mamp. These tutorials explain well the steps.
http://www.dennisdeacon.com/web-design/virtual-hosts-for-mamp-based-local-web-development-on-macos-sierra/
https://www.taniarascia.com/setting-up-virtual-hosts/
After setting up a virtual host, I could access to my local site via http://localhost/your-theme/ and http://my-theme.test/.
Next, I installed npm and gulp inside a WP theme folder (Node.js is installed globally) as I mentioned in my question. But I'm not sure if it's better to install these tools inside the htdocs folder or inside a WP theme folder. I did inside a theme folder because it seems easier for me.
To run the browser-sync, I used vhost url for proxy.
After this step, I could access to my site via http://localhost:3000/ with browser-sync.
To set up a vhost, I had to prepare a new WP environment with a new database inside Mamp.
Once a site is opend via localhost:8888, I could not reopen via vhost url. The site is redirected to the localhost:8888 url.
Now I can access to my site (front page) via http://localhost:3000/, but once I go to another pages, my site is redirected to http://localhost/your-theme/another-page and not http://localhost:3000/another-page. That means I can't run browser-sync task outside the front page and I don't know what is the solution...

Gulp - BrowserSync doesn't reload page

I'm following a basic tutorial for Gulp from here and I got stuck on the browser-sync implementation. I have copied the code exactly as it is in the example, however when I run the watch task, even though sass task executes no problem (new version of the css file is created), the browser doesn't want to refresh! Here is my code:
var gulp = require('gulp');
var sass = require('gulp-sass');
var browserSync = require('browser-sync').create();
gulp.task('sass', function() {
return gulp.src('app/scss/**/*.scss') // Gets all files ending with .scss in app/scss
.pipe(sass())
.pipe(gulp.dest('app/css'))
.pipe(browserSync.reload({stream: true}));
});
gulp.task('browserSync', ['sass'], function() {
browserSync.init({
server: {
baseDir: 'app'
},
})
})
gulp.task('watch', ['browserSync'], function() {
gulp.watch('app/scss/**/*.scss', ['sass']);
// Other watchers
});
And here is my index.html
<!doctype html>
<html>
<head>
<title>test</title>
<link href="css/styles.css" rel="stylesheet" type="text/css" />
</head>
<body></body>
</html>
My styles.scss files has only one style:
body {
background: blue;
}
And here is the output from the console window when I update the styles.scss
So I can see that the browser-sync is aware of the change being made, but it doesn't reload the page in the browser. Why is that? I have looked through the comments under the tutorial and no one seemed to face similar issue. I have also seen couple of other tutorials, but none of them works for me. I use latest version of chrome as my default browser, browser-sync version 5.6.0 and gulp version 3.9.1
I've never heard of piping files through browserSync.reload as a way to reload the dev server, and couldn't find any examples of that particular technique in the browserSync documentation. That doesn't necessarily mean that the method is invalid, but maybe the API has changed since CSS-Tricks published their tutorial in 2015? Three years can be an eternity in tooling time.
Anyway, I know I've used Gulp/browserSync/SASS successfully before so I dug up the code relevant to your situation from one of my old gulpfiles.
//watch task
gulp.task('watch', function () {
//spin up dev server
browserSync.init({
server: {
baseDir: "./"
},
});
//when scss files change, run sass task first and reload browserSync second
gulp.watch('./sass/*.scss', ['sass']).on('change', function () {
browserSync.reload();
});
});
//call watch task
gulp.task('default', ['watch']);
Basically when you call the watch task it immediately spins up the development server and then listens for changes to your scss files. When a change is detected, it calls the sass task as a dependency and runs whatever code you have for preprocessing (which you said is currently working in your file). After the sass task is completed, browserSync.reload is called via the .on method.
I haven't used this particular configuration in awhile but let me know if it works and if not I'd be happy to troubleshoot it with you. It's good boilerplate for any dev to have on hand.
EDIT: The above snippet was taken from a much larger gulpfile and upon second inspection I identified some parts that prevented it from working in a standalone context. Edited snippet to correct this.
I am running a MAMP site and this worked for me
//define task
gulp.task('bsync', function () {
//spin up dev server
browserSync.init({
proxy: "dev.sitename.local",
hostname: "dev.sitename.local",
port: 3000, //even if apache is running on 80 or something else
});
//when css files change, reload browserSync
gulp.watch('./css/*.css').on('change', function () {
browserSync.reload();
});
});
//call task with 'gulp runbsync'
gulp.task('runbsync', ['bsync']);
https://gist.github.com/petergus/31d75a5145e062d4eaa42eb04ce23aea

references to css and javascript from html don't work only on localhost

I am automatically inserting references to css and js files into html head with help of grunt-link-html plugin, but when viewing the page on http://localhost:9000/ files are not found ('Cannot GET'). The styles and scripts are referenced relatively and are showing when viewing the file by double-clicking from harddrive:
<!-- begin:css -->
<link rel="stylesheet" type="text/css" href="../deploy/css/myproject.min.css">
<!-- end:css -->
<!-- begin:js -->
<script src="../deploy/js/myproject.min.js"></script>
<!-- end:js -->
I'm new to Grunt, what am I missing? Thanks for any help
project structure:
MyProject
_build
node_modules
Gruntfile.js
package.json
deploy
css
myproject.min.css
js
myproject.min.js
src
css
myproject.css
js
myproject.js
index.html
extracts from the gruntfile:
express: {
all: {
options: {
port: 9000,
hostname: "0.0.0.0",
bases: ['C:/Users/user1/MyProject/src']
}
}
},
open: {
all: {
path: 'http://localhost:<%= express.all.options.port%>',
app: 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
}
},
link_html: {
your_target: {
jsFiles: ['../deploy/js/portfolio.min.js'],
cssFiles: ['../deploy/css/portfolio.min.css'],
targetHtml: ['../src/index.html'],
options: {
cwd: '../deploy'
}
}
}
grunt.registerTask('server', ['connect', 'express', 'open', 'watch']);
The .. at the beginning of the CSS & JS file paths are correct for Grunt if run from _build subdir, but not for the page, because index.html is at the project root directory.
I would move the Grunt stuff from _build to project's root folder and remove the .. from Gruntfile.js, too.
After a Grunt rerun it should work, then.
I am not familiar with these spesific grunt modules, but I am guessing the problem is that you define the "bases" of express.all as your src folder, and not your "myProject" folder.
So when your server wants to serve you files (like your css and js) it only looks in the /src folder, where you dont have a "../deploy/" folder.
Try changing your bases to ['C:/Users/user1/MyProject/deploy'] and your jsFiles and cssFiles, remove the "../deploy", they should now reside in the "/js" and "/css" folders.
Hope this helps :)
Just a thought or two:
1.Try using the same separator in all links, as there is a difference between "\" and "/" in some environnements (browsers vs editor vs os vs anything else).
2. (dumb question ?!) Are you sure you have read/write/execute rights on the files you are accessing ?

Grunt: `contrib-watch` Fire livereload event after `grunt-nodemon` has restarted when server-side `.coffee` files are compiled

I've been having an issue with Grunt.js and a few plugins, notably: grunt-contrib-watch, grunt-nodemon and grunt-contrib-coffee. I've been trying to figure this out for two days now but I don't think my knowledge of Grunt is sufficient to solve it at this point.
The problem I'm experiencing is simply that I want my server-side .coffee files to compile and then have nodemon restart the server and THEN only have livereload work. Right now, Livereload works as intended for everything but server-side coffee files. contrib-watch detects the change, runs coffee and fires off a livereload event, but then nodemon restarts.
Is there a way to get nodemon to restart before the page reloads so that what I see on the screen is up-to-date with what's going on in my server-side code?
I've been presented with the option of just running nodemon in a separate terminal tab, but I'm on Windows and would much prefer to keep one terminal running for this purpose and is the whole reason I'm using grunt-concurrent.
Here's my Gruntfile, it's quite early in it's stages (as I try to figure all this out). If you would prefer I compile it to JavaScript, then just leave a comment and request so, I will be happy to.
module.exports = (grunt) ->
# configuration
grunt.initConfig
pkg: grunt.file.readJSON 'package.json'
# watch task
watch:
css:
files: ['src/assets/styles/**/*.styl']
tasks: ['stylus']
options:
livereload: true
coffee:
files: ['src/**/*.coffee']
tasks: ['coffee']
js:
files: ['**/*.js']
options:
livereload: true
jade:
files: ['views/**/*.jade']
options:
livereload: true
# compile coffeescript to javascript
coffee:
compile:
options:
sourceMap: true
files: [
expand: true
cwd: 'src/'
src: ['**/*.coffee']
dest: ''
ext: '.js'
]
# compile stylus to css
stylus:
compile:
files: [
expand: true
cwd: 'src/assets/styles/'
src: ['**/*.styl']
dest: 'assets/styles/'
ext: '.css'
]
# run server
nodemon:
dev:
options:
file: 'server.js'
watchedExtensions: ['js', 'json']
ignoredFiles: [
'assets/**',
'node_modules/**',
'**/.js.map'
]
# run tasks concurrently for fast builds
concurrent:
first:
tasks: ['coffee', 'stylus']
options:
logConcurrentOutput: true
second:
tasks: ['nodemon', 'watch']
options:
logConcurrentOutput: true
# load dependencies
require('load-grunt-tasks') grunt
# register tasks
grunt.registerTask 'default', [
'concurrent:first',
'concurrent:second'
]
I've not used this myself but I came across it a while ago: grunt-rerun. Used in combination with a watch task you can pause a long running task such as express (but probably would work with nodemon as well), run some tasks, then start the task again. The sample config looks like so:
grunt.initConfig({
watch: {
dev: {
files: ['server/*.js'],
//Note the :go flag used for sending the reload message to the rerun server
tasks: ['clean','rerun:dev:express:go']
},
},
express: {
dev: {
options: {
port: 3000,
bases: ['/public'],
keepalive: true,
server: path.resolve('./server/app.js')
}
}
},
// Configuration to be run (and then tested).
rerun: {
dev: {
options: {
tasks: ['express']
},
},
}
})
https://npmjs.org/package/grunt-rerun
I'm not entirely sure about the live reload thing. My guess would be because it shuts down the process, by spawning a new one it would load the page afresh, but I haven't used this personally so I'm not sure.
The second alternative is yes, to use a command prompt that supports multiple tabs, such as Console. I'm a Mac user and so I use iTerm 2 which has multiple panes; most of the time I have four open per project, for watch, testem, a php server and a shell for everything else. You may find that this is a lot quicker and a lot less hassle.
Just a quick note on Coffeescript, a lot of JavaScript developers don't use it, so to get a wider audience to understand your source code, it may be good practice to compile coffee into js before you post your question.
I used watch for watching server files and a simple '2SecDelay' task that gives nodemon time to restart the server.
So, I got a patch, but it's ugly:
grunt.registerTask '2SecDelay', 'just taking some time', ->
done = #async()
setTimeout((() -> done()), 2000)
...
nodemon:
server:
... run server and watch server related files ...
watch:
server:
files: ... same files as the nodemon watches ...
tasks: ['2SecDelay']
concurrent:
server:
['nodemon', 'watch']
```
Why should you livereloading the coffee/stylus/jade files?
Just livereload the compiled changes instead! I guess you have a public folder with the compiled output from your .coffee/.styl/.jade files
This is my Gruntfile example:
module.exports = (grunt) ->
grunt.config.init
...
watch:
css:
files: ['src/assets/styles/**/*.styl']
tasks: ['stylus']
coffee:
files: ['src/**/*.coffee']
tasks: ['coffee']
jade:
files: ['views/**/*.jade']
livereload:
files: ['public/**/*.*']
options:
livereload: true
...
This way you will also trigger livereloading for non js/css file changes, like images, fonts, and so on. And you are always sure that livereload will be triggered
I added the following http request to tiny-lr when my server starts.
var server = app.listen(process.env.PORT || 3000, function() {
debug('Koa server listening on port ' + server.address().port);
require('http').get({host: 'localhost', port: 35729, path: '/changed?files=app.js'},
function (response){
console.log('Restart');
});
});
I have Webstorm running nodemon so this seems like an easy way to communicate between nodemon and the livereload server implementation that I'm using.
I tried running nodemon from a Gulp task and having the http call there in order to keep my code clean but nodemon doesn't seem to have an event that fires after the server has started - its 'restart' event fires before the restart.
The app's own listen event seems to be the best place to trigger a refresh as you that know at that point the server is ready to start handling requests.
These aren't the technologies specified in the question but the principle should be applicable just the same.

Resources