I have been working all day on trying to get my proxies set up in my Gruntfile. Here is my Gruntfile:
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;
module.exports = function(grunt) {
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.initConfig({
connect:{
livereload: {
options: {
middleware: function (connect) {
return [proxySnippet];
}
}
},
options: {
port: 9000,
base: 'app',
keepalive: true,
livereload: true
},
proxies: [
{
context: '/public/api',
host: 'localhost',
port: 8182,
https: false,
rewrite: {
'^/public/api': ''
}
}
]
}
});
grunt.registerTask('server', ['less', 'configureProxies', 'connect', 'connect', 'watch', 'open:dev']);
};
When I run my grunt server I can only hit my proxy. If I try to just hit anything other than the proxy I get a 404. What is giving me this issue?
I also had a lot of trouble setting up a proxy using grunt-connect-proxy.
Digging in the source code of grunt-contrib-connect, I realized that it uses the nodeJs Connect framework behind the scene.
Internally the middleware option defaults to this function:
function (connect, options) {
var middlewares = [];
if (!Array.isArray(options.base)) {
options.base = [options.base];
}
var directory = options.directory || options.base[options.base.length - 1];
options.base.forEach(function (base) {
// Serve static files.
middlewares.push(connect.static(base));
});
// Make directory browse-able.
middlewares.push(connect.directory(directory));
return middlewares;
}
Which basically adds the connect.static and the connect.directory middlewares to an array passed to the connect(middlewares) constructor.
Knowing that, we can make use of the proxy-middleware nodeJs package like this:
connect: {
server: {
options: {
port: 9002,
keepalive: true,
middleware: function (connect, options) {
// Proxy all requests to target the local application.
var proxyOptions = require('url').parse('http://localhost:8080/');
proxyOptions.route = '/api';
return [
require('proxy-middleware')(proxyOptions), // Include the proxy first.
connect.static(options.base), // Serve static files.
connect.directory(options.base) // Make empty directories browse-able.
];
}
}
}
}
Basically we are adding a middleware to the middleware array.
This new proxy middleware will translate any incoming request like http://localhost:9002/api/ into http://localhost:8080/
Related
I'm trying to add grunt-connect-proxy to my gruntfile.js in a yeoman generator-angular project (generator-angular 0.15.1) but I can't seem to get it to work since the way it's written changes and I'm inexperienced in how Grunt works.
I've read many posts about this and none are particularly up-to-date, and the gruntfile changes seemingly often in how it implements livereload middleware This makes the documentation for grunt-connect-proxy to not work in my case.
The tricky part is under livereload
This is how it looks in generator-angular gruntfile:
// The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
},
proxies: [{
context: '/api',
host: 'localhost',
port: 8080,
https: false,
xforward: false
}],
livereload: {
options: {
open: true,
// --- how the code looks like before I do anything
middleware: function (connect) {
return [
connect.static('.tmp'),
connect().use('/bower_components', connect.static('./bower_components')),
connect().use('/app/styles', connect.static('./app/styles')),
connect.static(appConfig.app)
];
}
}
},
...
When I look at the documentation it looks like this:
livereload: {
options: {
middleware: function (connect, options) {
if (!Array.isArray(options.base)) {
options.base = [options.base];
}
// Setup the proxy
var middlewares = [require('grunt-connect-proxy/lib/utils').proxyRequest];
// Serve static files.
options.base.forEach(function(base) {
middlewares.push(connect.static(base));
});
// Make directory browse-able.
var directory = options.directory || options.base[options.base.length - 1];
middlewares.push(connect.directory(directory));
return middlewares;
}
}
}
Can someone help me translate the documentation to the new way of writing the middleware part?
Thanks!!
So I got some help and this is how it was solved:
livereload: {
options: {
open: true,
middleware: function(connect) {
var middlewares = [require('grunt-connect-proxy/lib/utils').proxyRequest];
return middlewares.concat(
connect.static('.tmp'),
connect().use('/bower_components', connect.static('./bower_components')),
connect().use('/app/styles', connect.static('./app/styles')),
connect.static(appConfig.app)
);
}
}
}
Hope this helps someone else too.
I'm running an Angular.js application and all the task management are made with grunt, for now I have three components that I'm watching in live reload, bower_components, invoices and users, eventually they are going to increase in number, so I would like to know if there's a way to call an external file like components.json and iterate through its n members. Here is my code:
// The grunt server settings
connect: {
options: {
port: 9000,
hostname: 'localhost',
livereload: 35729
},
livereload: {
options: {
open: true,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect().use(
'/invoices',
connect.static(invoicesAppPathConfig.root)
),
connect().use(
'/users',
connect.static(usersAppPathConfig.root)
),
connect.static(secureAppPathConfig.app)
];
}
}
},
dist: {
options: {
open: true,
base: '<%= main.dist %>'
}
}
}
I have already created the component.json file:
{"data":[
{
"resource":"/bower_components",
"config":"./bower_components"
},
{
"resource":"/invoices",
"config":"invoicesAppPathConfig.root"
},
{
"resource":"/users",
"config":"usersAppPathConfig.root"
}
]}
And in the Gruntfile.js I created this variables, having in mind that I need to iterate in the content of data:
var components = require('./components.json');
var data = components.data;
Now I have the question, how can I do it this in the code?
middleware: function (connect) {
return [
connect.static('.tmp'),
// Here comes the data iteration
connect.static(secureAppPathConfig.app)
];
}
Thanks in advance.
Sure you can:
grunt.initConfig({
components: grunt.file.readJSON('components.json'),
[...]
});
More info on grunt.file here
You can also require it:
var components = require('./components.json');
Create the next variables:
var components = require('./components.json');
var data = components.data;
var arrayComponents = [];
Then in the options for livereload iterate the json data and add it to arrayComponents:
middleware: function (connect){
arrayComponents.push(connect.static('.tmp'));
// The modules to be watched are added
for(var i in data){
arrayComponents.push(connect().use(data[i].resource, connect.static(data[i].config)));
}
arrayComponents.push(connect.static(secureAppPathConfig.app));
return arrayComponents;
}
It works, but maybe it is not the most elegant solution.
I got nothing wrong in the terminal but Chrome doesn't answer to change on my html files and don't automatically reload the page.
I include 'livereload.js' in my index.html but i'm not sure if it's required.
Thanks for your help.
module.exports = function(grunt) {
// Load Grunt tasks declared in the package.json file
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
// Configure Grunt
grunt.initConfig({
// Grunt express - our webserver
// https://github.com/blai/grunt-express
express: {
all: {
options: {
bases: ['/Users/antoine/Dropbox/prog/projets/antoine/'],
port: 8080,
hostname: "localhost",
livereload: true
}
}
},
// grunt-watch will monitor the projects files
// https://github.com/gruntjs/grunt-contrib-watch
watch: {
all: {
files: '**/*.html',
options: {
livereload: true,
interval: 1500,
}
}
},
// grunt-open will open your browser at the project's URL
// https://www.npmjs.org/package/grunt-open
open: {
all: {
path: 'http://localhost:8080/index.html'
}
}
});
// Creates the `server` task
grunt.registerTask('server', [
'express',
'open',
'watch'
]);
};
My code is pretty simple, and the grunt file is,
module.exports = function(grunt) {
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;
grunt.initConfig({
connect: {
server: {
options: {
hostname: "localhost",
keepalive: true,
base:['../web/'],
port: 8080,
middleware: function(connect, options) {
return [proxySnippet];
},
debug: true
}
}
}
});
// grunt.loadNpmTasks('grunt-connect-proxy');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.registerTask('default', [
'connect:server'
]);
};
there's an index.html, and the path is "../web/index.html". When I open
"http://localhost:8080"
it gives "Cannot GET /". Any idea why this is happening?
For directory structure like the following:
-node_modules
-templates
---index.html
---login.html
-Gruntfile.js
connect: {
options: {
port: 9000,
livereload: true,
hostname: 'localhost',
},
livereload: {
options: {
open: true,
base: ['templates/']
}
}
}
This open the complete directory structure of templates on the browser to navigate to any html page.
Remove the middleware proxy, like this:
module.exports = function(grunt) {
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;
grunt.initConfig({
connect: {
server: {
options: {
hostname: "localhost",
keepalive: true,
base:['../web/'],
port: 8081,
debug: true
}
}
}
});
// grunt.loadNpmTasks('grunt-connect-proxy');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.registerTask('default', [
'connect:server'
]);
};
And must work.
I am using the code bellow for arguments which are using in protractor configuration file
protractor: {
options: {
keepAlive: true,
configFile: "test/config.js",
args:{
params:{
user:"user1",
password:"password1"
}
}
},
and retrieving in protractor conf file as browser.params.user,browser.params.password
These are working files.
I want to change the user and password values from command.
How to change the values?
This is a simple work around:
When you pass a parameter to your grunt task:
grunt e2e --user=alex --password=password
it's available as
grunt.option('user')
You can then edit the values you have in the config using:
var protConfig = grunt.config.get('protractor');
protConfig.options['someKey']=newValue;
grunt.config('protractor', protConfig);
grunt.task.run('protractor');
Not sure this is the best way to go about it, but it's working fine for me.
Also notice that we're wrapping the protractor task rather than calling it right away
how to fetch --user argument in protractor Specs?
In the code below I register a task "myprotractor" and whatever comes after the task as argument will go as parameter into the anonymous function:
grunt myprotractor:dev:pwd
module.exports = function(grunt) {
grunt.registerTask('myprotractor', function(user, pwd) {
console.log(user + pwd);
grunt.config('protractor', {
options: {
keepAlive: true,
configFile: "test/config.js",
args: {
params: {
user: user,
password: pwd
}
}
}
});
//here I am running the task
grunt.task.run([
'protractor'
]);
});
};
If you need you can configure 2 targets for protractor, having some common configuration and the args being set depending if you wish them from cmd or from config.
grunt myprotractor:cmd:dev:pwd
module.exports = function(grunt) {
grunt.registerTask('myprotractor', function(target, user, pwd) {
console.log(user + pwd);
grunt.config('protractor', {
options: {
keepAlive: true,
configFile: "test/config.js"
},
cmd: {
options: {
args: {
params: {
user: user,
password: pwd
}
}
}
},
config: {}
});
//here I am running the task with a target
grunt.task.run([
'protractor:' + target
]);
});
};