129 lines
4.5 KiB
JavaScript
129 lines
4.5 KiB
JavaScript
module.exports = function(grunt) {
|
|
var express = require('express'),
|
|
lockFile = require('lockfile'),
|
|
Helpers = require('./helpers'),
|
|
fs = require('fs'),
|
|
path = require('path'),
|
|
request = require('request');
|
|
|
|
/**
|
|
Task for serving the static files.
|
|
|
|
Note: The expressServer:debug task looks for files in multiple directories.
|
|
*/
|
|
grunt.registerTask('expressServer', function(target, proxyMethodToUse) {
|
|
// Load namespace module before creating the server
|
|
require('express-namespace');
|
|
|
|
var app = express(),
|
|
done = this.async(),
|
|
proxyMethod = proxyMethodToUse || grunt.config('express-server.options.APIMethod');
|
|
|
|
app.use(lock);
|
|
app.use(express.compress());
|
|
|
|
if (proxyMethod === 'stub') {
|
|
grunt.log.writeln('Using API Stub');
|
|
|
|
// Load API stub routes
|
|
app.use(express.json());
|
|
app.use(express.urlencoded());
|
|
require('../api-stub/routes')(app);
|
|
} else if (proxyMethod === 'proxy') {
|
|
var proxyURL = grunt.config('express-server.options.proxyURL'),
|
|
proxyPath = grunt.config('express-server.options.proxyPath') || '/api';
|
|
grunt.log.writeln('Proxying API requests matching ' + proxyPath + '/* to: ' + proxyURL);
|
|
|
|
// Use API proxy
|
|
app.all(proxyPath + '*', passThrough(proxyURL));
|
|
}
|
|
|
|
if (target === 'debug') {
|
|
// For `expressServer:debug`
|
|
|
|
// Add livereload middleware after lock middleware if enabled
|
|
if (Helpers.isPackageAvailable("connect-livereload")) {
|
|
var liveReloadPort = grunt.config('watch.options.livereload');
|
|
app.use(require("connect-livereload")({port: liveReloadPort}));
|
|
}
|
|
|
|
// YUIDoc serves static HTML, so just serve the index.html
|
|
app.all('/docs', function(req, res) { res.redirect(302, '/docs/index.html'); });
|
|
app.use(static({ urlRoot: '/docs', directory: 'docs' }));
|
|
|
|
// These three lines simulate what the `copy:assemble` task does
|
|
app.use(static({ urlRoot: '/config', directory: 'config' }));
|
|
app.use(static({ urlRoot: '/vendor', directory: 'vendor' }));
|
|
app.use(static({ directory: 'public' }));
|
|
app.use(static({ urlRoot: '/tests', directory: 'tests' })); // For test-helper.js and test-loader.js
|
|
app.use(static({ directory: 'tmp/result' }));
|
|
app.use(static({ file: 'tmp/result/index.html', ignoredFileExtensions: /\.\w{1,5}$/ })); // Gotta catch 'em all
|
|
} else {
|
|
// For `expressServer:dist`
|
|
|
|
app.use(lock);
|
|
app.use(static({ directory: 'dist' }));
|
|
app.use(static({ file: 'dist/index.html', ignoredFileExtensions: /\.\w{1,5}$/ })); // Gotta catch 'em all
|
|
}
|
|
|
|
var port = parseInt(process.env.PORT || 8000, 10);
|
|
if (isNaN(port) || port < 1 || port > 65535) {
|
|
grunt.fail.fatal('The PORT environment variable of ' + process.env.PORT + ' is not valid.');
|
|
}
|
|
app.listen(port);
|
|
grunt.log.ok('Started development server on port %d.', port);
|
|
if (!this.flags.keepalive) { done(); }
|
|
});
|
|
|
|
|
|
// Middleware
|
|
// ==========
|
|
|
|
function lock(req, res, next) { // Works with tasks/locking.js
|
|
(function retry() {
|
|
if (lockFile.checkSync('tmp/connect.lock')) {
|
|
setTimeout(retry, 30);
|
|
} else { next(); }
|
|
})();
|
|
}
|
|
|
|
function static(options) {
|
|
return function(req, res, next) { // Gotta catch 'em all (and serve index.html)
|
|
var filePath = "";
|
|
if (options.directory) {
|
|
var regex = new RegExp('^' + (options.urlRoot || ''));
|
|
// URL must begin with urlRoot's value
|
|
if (!req.path.match(regex)) { next(); return; }
|
|
filePath = options.directory + req.path.replace(regex, '');
|
|
} else if (options.file) {
|
|
filePath = options.file;
|
|
} else { throw new Error('static() isn\'t properly configured!'); }
|
|
|
|
fs.stat(filePath, function(err, stats) {
|
|
if (err) { next(); return; } // Not a file, not a folder => can't handle it
|
|
|
|
if (options.ignoredFileExtensions) {
|
|
if (options.ignoredFileExtensions.test(req.path)) {
|
|
res.send(404, {error: 'Resource not found'});
|
|
return; // Do not serve index.html
|
|
}
|
|
}
|
|
|
|
// Is it a directory? If so, search for an index.html in it.
|
|
if (stats.isDirectory()) { filePath = path.join(filePath, 'index.html'); }
|
|
|
|
// Serve the file
|
|
res.sendfile(filePath, function(err) {
|
|
if (err) { next(); return; }
|
|
grunt.verbose.ok('Served: ' + filePath);
|
|
});
|
|
});
|
|
};
|
|
}
|
|
|
|
function passThrough(target) {
|
|
return function(req, res) {
|
|
req.pipe(request(target+req.url)).pipe(res);
|
|
};
|
|
}
|
|
};
|