Reputation: 4413
I'm trying to set up my Gruntfile to use the grunt connect npm module. I'm having an issue when trying to start up my server with the command grunt clean server
. It errors with the line:
Warning: root path must be a string Use --force to continue.
I'm really not sure what configuration I've messed up and could use another set of eyes. This is my Gruntfile:
/* global module, conf */
var modRewrite = require('connect-modrewrite');
var mountFolder = function(connect, dir) {
return connect.static(require('path').resolve(dir));
};
module.exports = function(grunt) {
grunt.initConfig({
copy: {
base: {
files: [
{src: "index.html", dest: "BUILD/index.html"},
{expand: true, src: "app/**", dest: "BUILD/"},
{expand: true, src: "assets/**", dest: "BUILD/"}
]
}
},
connect: {
proxies: [
{
context: "/wwff",
host: "localhost",
port: "8080"
}
],
/**
* Task defines a server at 9000,
* watching the BUILD directory
*/
dev: {
options: {
port: "9000",
hostname: '*',
base: "BUILD",
middleware: function(connect, options) {
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;
return [
// include the proxy first
proxySnippet,
modRewrite([
'!\\.html|\\.js|\\.swf|\\.json|\\.xml|\\.css|\\.png|\\.jpg|\\.gif|\\.ico|\\.aff|\\.msi|\\.zip|\\.dic$ /index.html [L]'
]),
// serve static files
connect.static(options.base),
// make empty directories browsable
connect.directory(options.base)
];
}
}
}
},
/*
* This task watches the application and asset directories and
* deploys any changes to the dev server
*/
watch: {
static: {
files: [ "app/**/*.js", "app/**/*.html"],
tasks: ["build"]
}
},
clean: {
build: ["BUILD/"],
temp: ["tmp"]
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-connect-proxy');
grunt.loadNpmTasks('grunt-contrib-clean');
/*
* Main BUILD Task
*/
grunt.registerTask("build", "Copies app and asset files to the BUILD directory.", function() {
grunt.task.run("copy:base");
});
grunt.registerTask("server", "Stand up a node server for development.", function() {
grunt.task.run(["build", "configureProxies:dev", "connect:dev", "watch"]);
});
grunt.event.on('watch', function(action, filepath, target) {
grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
});
};
When I use the --verbose
flag I get the following lines:
Verifying property connect.dev exists in config...OK
File: [no files]
Options: protocol="http", port="9000", hostname="*", base="BUILD", directory=null, keepalive=false, debug=false, livereload=false, open=false, useAvailablePort=false, onCreateServer=null, middleware=undefined
It seems to me like the issue is that the middleware
is undefined
but I have no idea why it is.
Any help is appreciated.
Upvotes: 4
Views: 2798
Reputation: 66355
Bit late to the game but in newer version of grunt-connect base
is always an array. You can make your middleware compatible with either versions like so:
middleware: function (connect, options) {
// Older versions of grunt-connect.
if (!Array.isArray(options.base)) {
options.base = [options.base];
}
var middlewares = [
require('connect-livereload')()
];
// Serve static files.
options.base.forEach(function(base) {
middlewares.push(connect.static(base));
});
return middlewares;
}
For an example with grunt-connect-proxy see the docs at https://github.com/drewzboto/grunt-connect-proxy
This is better than just mounting the first base at options.base[0]
.
Upvotes: 1
Reputation: 1
The reason is that options.base is an array. options.base[0] refers to the first (and in this case only) item in the array (which is a string representing the root path).
Upvotes: 0
Reputation: 4413
Well, I don't understand how, but it seems like my options.base
in my middleware
function was becoming an array with the first value being my BUILD
directory.
So the following snippet for my middleware
function works:
middleware: function(connect, options) {
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;
return [
// include the proxy first
proxySnippet,
modRewrite(['!\\.html|\\.js|\\.swf|\\.json|\\.xml|\\.css|\\.png|\\.jpg|\\.gif|\\.ico|\\.aff|\\.msi|\\.zip|\\.dic$ /index.html [L]']),
// serve static files
connect.static(options.base[0]),
// make empty directories browsable
connect.directory(options.base[0])
];
}
The important part in the above snippet is that my options.base
is now options.base[0]
. If someone has an explanation for why this is the case, that would be much appreciated.
Upvotes: 5