mirror of
https://github.com/zhigang1992/firebase-tools.git
synced 2026-04-30 04:45:27 +08:00
Support implicit init and SDK proxy in firebase serve
This commit is contained in:
@@ -6,45 +6,55 @@ var superstatic = require('superstatic').server;
|
|||||||
|
|
||||||
var Command = require('../lib/command');
|
var Command = require('../lib/command');
|
||||||
var FirebaseError = require('../lib/error');
|
var FirebaseError = require('../lib/error');
|
||||||
|
var hostingImplicitInit = require('../lib/hostingImplicitInit');
|
||||||
|
var hostingInitMiddleware = require('../lib/hostingInitMiddleware');
|
||||||
var logger = require('../lib/logger');
|
var logger = require('../lib/logger');
|
||||||
var utils = require('../lib/utils');
|
var utils = require('../lib/utils');
|
||||||
|
var requireAccess = require('../lib/requireAccess');
|
||||||
var requireConfig = require('../lib/requireConfig');
|
var requireConfig = require('../lib/requireConfig');
|
||||||
var checkDupHostingKeys = require('../lib/checkDupHostingKeys');
|
var checkDupHostingKeys = require('../lib/checkDupHostingKeys');
|
||||||
|
var scopes = require('../lib/scopes');
|
||||||
|
|
||||||
var MAX_PORT_ATTEMPTS = 10;
|
var MAX_PORT_ATTEMPTS = 10;
|
||||||
|
|
||||||
var _attempts = 0;
|
var _attempts = 0;
|
||||||
var startServer = function(options) {
|
var startServer = function(options) {
|
||||||
var config = options.config ? options.config.get('hosting') : {public: '.'};
|
var config = options.config ? options.config.get('hosting') : {public: '.'};
|
||||||
var server = superstatic({
|
|
||||||
debug: true,
|
|
||||||
port: options.port,
|
|
||||||
host: options.host,
|
|
||||||
config: config,
|
|
||||||
stack: 'strict'
|
|
||||||
}).listen(function() {
|
|
||||||
if (config.public && config.public !== '.') {
|
|
||||||
logger.info(chalk.bold('Public Directory:'), config.public);
|
|
||||||
}
|
|
||||||
logger.info();
|
|
||||||
logger.info('Server listening at: ' + chalk.underline(chalk.bold('http://' + options.host + ':' + options.port)));
|
|
||||||
});
|
|
||||||
|
|
||||||
server.on('error', function(err) {
|
return hostingImplicitInit(options).then(function(init) {
|
||||||
if (err.code === 'EADDRINUSE') {
|
var server = superstatic({
|
||||||
var message = 'Port ' + options.port + ' is not available.';
|
debug: true,
|
||||||
if (_attempts < MAX_PORT_ATTEMPTS) {
|
port: options.port,
|
||||||
utils.logWarning(message + ' Trying another port...');
|
host: options.host,
|
||||||
options.port++;
|
config: config,
|
||||||
_attempts++;
|
stack: 'strict',
|
||||||
startServer(options);
|
before: {
|
||||||
} else {
|
files: hostingInitMiddleware(init)
|
||||||
utils.logWarning(message);
|
|
||||||
throw new FirebaseError('Could not find an open port for development server.', {exit: 1});
|
|
||||||
}
|
}
|
||||||
} else {
|
}).listen(function() {
|
||||||
throw new FirebaseError('An error occurred while starting the development server:\n\n' + err.toString(), {exit: 1});
|
if (config.public && config.public !== '.') {
|
||||||
}
|
logger.info(chalk.bold('Public Directory:'), config.public);
|
||||||
|
}
|
||||||
|
logger.info();
|
||||||
|
logger.info('Server listening at: ' + chalk.underline(chalk.bold('http://' + options.host + ':' + options.port)));
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on('error', function(err) {
|
||||||
|
if (err.code === 'EADDRINUSE') {
|
||||||
|
var message = 'Port ' + options.port + ' is not available.';
|
||||||
|
if (_attempts < MAX_PORT_ATTEMPTS) {
|
||||||
|
utils.logWarning(message + ' Trying another port...');
|
||||||
|
options.port++;
|
||||||
|
_attempts++;
|
||||||
|
startServer(options);
|
||||||
|
} else {
|
||||||
|
utils.logWarning(message);
|
||||||
|
throw new FirebaseError('Could not find an open port for development server.', {exit: 1});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new FirebaseError('An error occurred while starting the development server:\n\n' + err.toString(), {exit: 1});
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,6 +63,7 @@ module.exports = new Command('serve')
|
|||||||
.option('-p, --port <port>', 'the port on which to listen (default: 5000)', 5000)
|
.option('-p, --port <port>', 'the port on which to listen (default: 5000)', 5000)
|
||||||
.option('-o, --host <host>', 'the host on which to listen (default: localhost)', 'localhost')
|
.option('-o, --host <host>', 'the host on which to listen (default: localhost)', 'localhost')
|
||||||
.before(requireConfig)
|
.before(requireConfig)
|
||||||
|
.before(requireAccess, [scopes.CLOUD_PLATFORM])
|
||||||
.before(checkDupHostingKeys)
|
.before(checkDupHostingKeys)
|
||||||
.action(function(options) {
|
.action(function(options) {
|
||||||
logger.info('Starting Firebase development server...');
|
logger.info('Starting Firebase development server...');
|
||||||
@@ -64,12 +75,12 @@ module.exports = new Command('serve')
|
|||||||
utils.logWarning('No Firebase project directory detected. Serving static content from ' + chalk.bold(options.cwd || process.cwd()));
|
utils.logWarning('No Firebase project directory detected. Serving static content from ' + chalk.bold(options.cwd || process.cwd()));
|
||||||
}
|
}
|
||||||
|
|
||||||
startServer(options);
|
return startServer(options).then(function() {
|
||||||
|
return new RSVP.Promise(function(resolve) {
|
||||||
return new RSVP.Promise(function(resolve) {
|
process.on('SIGINT', function() {
|
||||||
process.on('SIGINT', function() {
|
logger.info('Shutting down...');
|
||||||
logger.info('Shutting down...');
|
resolve();
|
||||||
resolve();
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
17
lib/hostingImplicitInit.js
Normal file
17
lib/hostingImplicitInit.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
var fetchWebSetup = require('./fetchWebSetup');
|
||||||
|
|
||||||
|
var INIT_TEMPLATE = fs.readFileSync(__dirname + '/../templates/hosting/init.js', 'utf8');
|
||||||
|
|
||||||
|
module.exports = function(options) {
|
||||||
|
return fetchWebSetup(options).then(function(config) {
|
||||||
|
var configJson = JSON.stringify(config, null, 2);
|
||||||
|
return {
|
||||||
|
js: INIT_TEMPLATE.replace('{/*--CONFIG--*/}', configJson),
|
||||||
|
json: configJson
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
28
lib/hostingInitMiddleware.js
Normal file
28
lib/hostingInitMiddleware.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var request = require('request');
|
||||||
|
|
||||||
|
var SDK_PATH_REGEXP = /^\/__\/firebase\/([^/]+)\/([^/]+)$/;
|
||||||
|
|
||||||
|
module.exports = function(init) {
|
||||||
|
return function(req, res, next) {
|
||||||
|
var match = req.url.match(SDK_PATH_REGEXP);
|
||||||
|
if (match) {
|
||||||
|
var url = 'https://www.gstatic.com/firebasejs/' + match[1] + '/' + match[2];
|
||||||
|
var preq = request(url).on('response', function(pres) {
|
||||||
|
if (pres.statusCode === 404) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
return preq.pipe(res);
|
||||||
|
});
|
||||||
|
} else if (req.url === '/__/firebase/init.js') {
|
||||||
|
res.setHeader('Content-Type', 'application/javascript');
|
||||||
|
res.end(init.js);
|
||||||
|
} else if (req.url === '/__/firebase/init.json') {
|
||||||
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
res.end(init.json);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
2
templates/hosting/init.js
Normal file
2
templates/hosting/init.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
if (typeof firebase === 'undefined') throw new Error('hosting/init-error: Firebase SDK not detected. You must include it before /__/firebase/init.js');
|
||||||
|
firebase.initializeApp({/*--CONFIG--*/});
|
||||||
Reference in New Issue
Block a user