mirror of https://github.com/status-im/metro.git
Automatically watches the metro configuration file
Reviewed By: BYK Differential Revision: D6408358 fbshipit-source-id: d167534c9c51c3c079148d982ef4ab44c8be0d75
This commit is contained in:
parent
b282031517
commit
5cc0939454
|
@ -19,12 +19,20 @@ import type {ConfigT} from './Config';
|
|||
|
||||
const METRO_CONFIG_FILENAME = 'metro.config.js';
|
||||
|
||||
exports.findMetroConfig = async function(
|
||||
filename: ?string,
|
||||
): Promise<$Shape<ConfigT>> {
|
||||
exports.watchFile = async function(
|
||||
filename: string,
|
||||
callback: () => *,
|
||||
): Promise<void> {
|
||||
fs.watchFile(filename, () => {
|
||||
callback();
|
||||
});
|
||||
|
||||
await callback();
|
||||
};
|
||||
|
||||
exports.findMetroConfig = async function(filename: ?string): Promise<?string> {
|
||||
if (filename) {
|
||||
// $FlowFixMe: We want this require to be dynamic
|
||||
return require(path.resolve(process.cwd(), filename));
|
||||
return path.resolve(process.cwd(), filename);
|
||||
} else {
|
||||
let previous;
|
||||
let current = process.cwd();
|
||||
|
@ -33,14 +41,25 @@ exports.findMetroConfig = async function(
|
|||
const filename = path.join(current, METRO_CONFIG_FILENAME);
|
||||
|
||||
if (fs.existsSync(filename)) {
|
||||
// $FlowFixMe: We want this require to be dynamic
|
||||
return require(filename);
|
||||
return filename;
|
||||
}
|
||||
|
||||
previous = current;
|
||||
current = path.dirname(current);
|
||||
} while (previous !== current);
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
exports.fetchMetroConfig = async function(
|
||||
filename: ?string,
|
||||
): Promise<$Shape<ConfigT>> {
|
||||
const location = await exports.findMetroConfig(filename);
|
||||
if (location) {
|
||||
// $FlowFixMe: We want this require to be dynamic
|
||||
return require(location);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ const MetroApi = require('..');
|
|||
|
||||
const os = require('os');
|
||||
|
||||
const {findMetroConfig, makeAsyncCommand} = require('../cli-utils');
|
||||
const {fetchMetroConfig, makeAsyncCommand} = require('../cli-utils');
|
||||
|
||||
import typeof Yargs from 'yargs';
|
||||
|
||||
|
@ -52,6 +52,6 @@ exports.builder = (yargs: Yargs) => {
|
|||
|
||||
// eslint-disable-next-line no-unclear-flowtypes
|
||||
exports.handler = makeAsyncCommand(async (argv: any) => {
|
||||
argv.config = await findMetroConfig(argv.config);
|
||||
await MetroApi.runBuild(argv);
|
||||
const config = await fetchMetroConfig(argv.config);
|
||||
await MetroApi.runBuild({...argv, config});
|
||||
});
|
||||
|
|
|
@ -16,7 +16,13 @@ const MetroApi = require('..');
|
|||
|
||||
const os = require('os');
|
||||
|
||||
const {findMetroConfig, makeAsyncCommand} = require('../cli-utils');
|
||||
const {
|
||||
findMetroConfig,
|
||||
fetchMetroConfig,
|
||||
watchFile,
|
||||
makeAsyncCommand,
|
||||
} = require('../cli-utils');
|
||||
const {promisify} = require('util');
|
||||
|
||||
import typeof Yargs from 'yargs';
|
||||
|
||||
|
@ -49,15 +55,44 @@ exports.builder = (yargs: Yargs) => {
|
|||
|
||||
// eslint-disable-next-line no-unclear-flowtypes
|
||||
exports.handler = makeAsyncCommand(async (argv: any) => {
|
||||
argv.config = await findMetroConfig(argv.config);
|
||||
let server = null;
|
||||
let restarting = false;
|
||||
|
||||
await MetroApi.runServer({
|
||||
...argv,
|
||||
onReady(server) {
|
||||
console.log(
|
||||
`The HTTP server is ready to accept requests on ${server.address()
|
||||
.address}:${server.address().port}`,
|
||||
);
|
||||
},
|
||||
});
|
||||
async function restart() {
|
||||
if (restarting) {
|
||||
return;
|
||||
} else {
|
||||
restarting = true;
|
||||
}
|
||||
|
||||
if (server) {
|
||||
console.log('Configuration changed... restarting the server...');
|
||||
await promisify(server.close).call(server);
|
||||
}
|
||||
|
||||
const config = await fetchMetroConfig(argv.config);
|
||||
|
||||
server = await MetroApi.runServer({
|
||||
...argv,
|
||||
config,
|
||||
onReady,
|
||||
});
|
||||
|
||||
restarting = false;
|
||||
}
|
||||
|
||||
function onReady(server) {
|
||||
console.log(
|
||||
`The HTTP server is ready to accept requests on ${server.address()
|
||||
.address}:${server.address().port}`,
|
||||
);
|
||||
}
|
||||
|
||||
const metroConfigLocation = await findMetroConfig(argv.config);
|
||||
|
||||
if (metroConfigLocation) {
|
||||
await watchFile(metroConfigLocation, restart);
|
||||
} else {
|
||||
await restart();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -145,8 +145,13 @@ exports.createConnectMiddleware = async function(
|
|||
watch: true,
|
||||
});
|
||||
|
||||
return (req: IncomingMessage, res: ServerResponse) => {
|
||||
return metroServer.processRequest(req, res);
|
||||
return {
|
||||
middleware(req: IncomingMessage, res: ServerResponse) {
|
||||
return metroServer.processRequest(req, res);
|
||||
},
|
||||
end() {
|
||||
metroServer.end();
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -163,13 +168,13 @@ type RunServerOptions = {|
|
|||
exports.runServer = async (options: RunServerOptions) => {
|
||||
const serverApp = connect();
|
||||
|
||||
const metroMiddleware = exports.createConnectMiddleware({
|
||||
const {middleware, end} = await exports.createConnectMiddleware({
|
||||
config: options.config,
|
||||
maxWorkers: options.maxWorkers,
|
||||
projectRoots: options.projectRoots,
|
||||
});
|
||||
|
||||
serverApp.use(metroMiddleware);
|
||||
serverApp.use(middleware);
|
||||
|
||||
let httpServer;
|
||||
|
||||
|
@ -185,7 +190,6 @@ exports.runServer = async (options: RunServerOptions) => {
|
|||
httpServer = Http.createServer(serverApp);
|
||||
}
|
||||
|
||||
// $FlowFixMe: The port parameter IS optional
|
||||
httpServer.listen(options.port, options.host, () => {
|
||||
options.onReady && options.onReady(httpServer);
|
||||
});
|
||||
|
@ -195,15 +199,15 @@ exports.runServer = async (options: RunServerOptions) => {
|
|||
// timeout of 120 seconds to respond to a request.
|
||||
httpServer.timeout = 0;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
httpServer.on('error', error => {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
httpServer.on('close', () => {
|
||||
resolve();
|
||||
});
|
||||
httpServer.on('error', error => {
|
||||
end();
|
||||
});
|
||||
|
||||
httpServer.on('close', () => {
|
||||
end();
|
||||
});
|
||||
|
||||
return httpServer;
|
||||
};
|
||||
|
||||
type RunBuildOptions = {|
|
||||
|
|
Loading…
Reference in New Issue