moved devServer into a module so that it can be used programmatically
This commit is contained in:
parent
cac3fd6dbb
commit
50f0368a72
10
package.json
10
package.json
|
@ -6,22 +6,22 @@
|
||||||
"main": "Gulpfile.js",
|
"main": "Gulpfile.js",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"bluebird": "~2.0.7",
|
||||||
|
"connect": "~2.19.5",
|
||||||
|
"event-stream": "~3.1.5",
|
||||||
"expect.js": "~0.2.0",
|
"expect.js": "~0.2.0",
|
||||||
"grunt": "~0.4.2",
|
"grunt": "~0.4.2",
|
||||||
"grunt-cli": "~0.1.13",
|
|
||||||
"grunt-contrib-connect": "~0.6.0",
|
|
||||||
"grunt-contrib-jade": "~0.10.0",
|
"grunt-contrib-jade": "~0.10.0",
|
||||||
"grunt-contrib-jshint": "~0.8.0",
|
"grunt-contrib-jshint": "~0.8.0",
|
||||||
"grunt-contrib-less": "~0.10.0",
|
"grunt-contrib-less": "~0.10.0",
|
||||||
"grunt-contrib-requirejs": "~0.4.4",
|
"grunt-contrib-requirejs": "~0.4.4",
|
||||||
"grunt-contrib-watch": "~0.5.3",
|
"grunt-contrib-watch": "~0.5.3",
|
||||||
"grunt-mocha": "~0.4.10",
|
"grunt-mocha": "~0.4.10",
|
||||||
|
"http-proxy": "~1.1.4",
|
||||||
"istanbul": "~0.2.4",
|
"istanbul": "~0.2.4",
|
||||||
"load-grunt-config": "~0.7.0",
|
"load-grunt-config": "~0.7.0",
|
||||||
"lodash": "~2.4.1",
|
"lodash": "~2.4.1",
|
||||||
"bluebird": "~1.2.4",
|
"mocha": "~1.17.1"
|
||||||
"mocha": "~1.17.1",
|
|
||||||
"event-stream": "~3.1.5"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "grunt test",
|
"test": "grunt test",
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
module.exports = function (grunt) {
|
|
||||||
var instrumentationMiddleware = require('../utils/instrumentation');
|
|
||||||
var amdRapperMiddleware = require('../utils/amd_rapper');
|
|
||||||
|
|
||||||
return {
|
|
||||||
dev: {
|
|
||||||
options: {
|
|
||||||
hostname: '0.0.0.0',
|
|
||||||
middleware: function (connect, options, stack) {
|
|
||||||
stack = stack || [];
|
|
||||||
|
|
||||||
var root = grunt.config.get('root');
|
|
||||||
|
|
||||||
// when a request for an intrumented file comes in (?instrument=true)
|
|
||||||
// and it is included in `pattern`, it will be handled
|
|
||||||
// by this middleware
|
|
||||||
stack.push(instrumentationMiddleware({
|
|
||||||
// root that files should be served from
|
|
||||||
root: root,
|
|
||||||
|
|
||||||
// make file names easier to read
|
|
||||||
displayRoot: grunt.config.get('src'),
|
|
||||||
|
|
||||||
// filter the filenames that will be served
|
|
||||||
filter: function (filename) {
|
|
||||||
// return true if the filename should be
|
|
||||||
// included in the coverage report (results are cached)
|
|
||||||
return grunt.file.isMatch([
|
|
||||||
'**/src/**/*.js',
|
|
||||||
'!**/src/bower_components/**/*',
|
|
||||||
'!**/src/kibana/utils/{event_emitter,next_tick}.js'
|
|
||||||
], filename);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
// minimize code duplication (especially in the istanbul reporter)
|
|
||||||
// by allowing node_modules to be requested in an AMD rapper
|
|
||||||
stack.push(amdRapperMiddleware({
|
|
||||||
root: root
|
|
||||||
}));
|
|
||||||
|
|
||||||
// standard static middleware reading from the root
|
|
||||||
stack.push(connect.static(root));
|
|
||||||
|
|
||||||
stack.push(function (req, res, next) {
|
|
||||||
if (req.method !== 'HEAD' || req.url !== '/') return next();
|
|
||||||
res.statusCode === 200;
|
|
||||||
res.setHeader('Pong', 'Kibana 4 Dev Server');
|
|
||||||
res.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
// redirect requests for '/' to '/src/'
|
|
||||||
stack.push(function (req, res, next) {
|
|
||||||
if (req.url !== '/') return next();
|
|
||||||
res.statusCode = 303;
|
|
||||||
res.setHeader('Location', '/src/');
|
|
||||||
res.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
// allow browsing directories
|
|
||||||
stack.push(
|
|
||||||
function (req, res, next) {
|
|
||||||
// prevent chrome's stupid "this page is in spanish"
|
|
||||||
res.setHeader('Content-Language', 'en');
|
|
||||||
next();
|
|
||||||
},
|
|
||||||
connect.directory(root)
|
|
||||||
);
|
|
||||||
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -19,7 +19,7 @@ module.exports = function (grunt) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function onError() {
|
function onError() {
|
||||||
grunt.task.run(['connect:dev']);
|
grunt.task.run(['server']);
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
grunt.registerTask('server', ['connect:dev:keepalive']);
|
grunt.registerTask('server', function () {
|
||||||
|
var done = this.async();
|
||||||
|
var DevServer = require('../test/utils/dev_server');
|
||||||
|
var server = new DevServer();
|
||||||
|
server.listen(8000, function () {
|
||||||
|
console.log('visit http://localhost:8000');
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
106
test/utils/dev_server/index.js
Normal file
106
test/utils/dev_server/index.js
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
/* jshint node:true */
|
||||||
|
|
||||||
|
var connect = require('connect');
|
||||||
|
var http = require('http');
|
||||||
|
var Promise = require('bluebird');
|
||||||
|
|
||||||
|
var instrumentationMiddleware = require('./_instrumentation');
|
||||||
|
var amdRapperMiddleware = require('./_amd_rapper');
|
||||||
|
var rel = require('path').join.bind(null, __dirname);
|
||||||
|
|
||||||
|
var proxy = require('http-proxy').createProxyServer({});
|
||||||
|
var ROOT = rel('../../../');
|
||||||
|
var SRC = rel('../../../src');
|
||||||
|
|
||||||
|
module.exports = function DevServer(opts) {
|
||||||
|
opts = opts || {};
|
||||||
|
|
||||||
|
var server = this;
|
||||||
|
var app = connect();
|
||||||
|
var httpServer = http.createServer(app);
|
||||||
|
|
||||||
|
app.use(instrumentationMiddleware({
|
||||||
|
root: ROOT,
|
||||||
|
displayRoot: SRC,
|
||||||
|
filter: function (filename) {
|
||||||
|
return filename.match(/.*\/src\/.*\.js$/)
|
||||||
|
&& !filename.match(/.*\/src\/bower_components\/.*\.js$/)
|
||||||
|
&& !filename.match(/.*\/src\/kibana\/utils\/(event_emitter|next_tick)\.js$/);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use(amdRapperMiddleware({
|
||||||
|
root: ROOT
|
||||||
|
}));
|
||||||
|
|
||||||
|
app.use('/es-proxy', function (req, res) {
|
||||||
|
req.url = req.url.replace(/^\/es-proxy/, '');
|
||||||
|
proxy.web(req, res, { target: 'http://localhost:' + (process.env.ES_PORT || 9200) });
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(connect.static(ROOT));
|
||||||
|
|
||||||
|
// respond to the "maybe_start_server" pings
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
if (req.method !== 'HEAD' || req.url !== '/') return next();
|
||||||
|
res.statusCode === 200;
|
||||||
|
res.setHeader('Pong', 'Kibana 4 Dev Server');
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
if (req.url !== '/') return next();
|
||||||
|
res.statusCode = 303;
|
||||||
|
res.setHeader('Location', '/src/');
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
// prevent chrome's stupid "this page is in spanish" on the directories page
|
||||||
|
app.use(function (req, res, next) {
|
||||||
|
res.setHeader('Content-Language', 'en');
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
// allow browsing directories
|
||||||
|
app.use(connect.directory(ROOT));
|
||||||
|
|
||||||
|
server.listenOnFirstOpenPort = function (ports) {
|
||||||
|
var options = ports.slice(0);
|
||||||
|
|
||||||
|
// wrap this logic in an IIFE so that we can call it again later
|
||||||
|
return (function attempt() {
|
||||||
|
var port = options.shift();
|
||||||
|
if (!port) return Promise.reject(new Error('None of the supplied options succeeded'));
|
||||||
|
|
||||||
|
return server.listen(port)
|
||||||
|
// filter out EADDRINUSE errors and call attempt again
|
||||||
|
.catch(function (err) {
|
||||||
|
if (err.code === 'EADDRINUSE') return attempt();
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
server.listen = function (port) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var done = function (err) {
|
||||||
|
httpServer.removeListener('error', done);
|
||||||
|
httpServer.removeListener('listening', done);
|
||||||
|
|
||||||
|
// pass the error along
|
||||||
|
if (err) return reject(err);
|
||||||
|
|
||||||
|
resolve(server.port = httpServer.address().port);
|
||||||
|
};
|
||||||
|
|
||||||
|
// call done with an error
|
||||||
|
httpServer.on('error', done, true);
|
||||||
|
// call done without any args
|
||||||
|
httpServer.on('listening', done, true);
|
||||||
|
|
||||||
|
httpServer.listen(port);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
server.close = httpServer.close.bind(httpServer);
|
||||||
|
};
|
Loading…
Reference in a new issue