From 5af650d7bcd3eb0c5721b10a0bd22e71d5b5d7d2 Mon Sep 17 00:00:00 2001 From: Varayut Lerdkanlayanawat Date: Thu, 17 Mar 2016 23:05:16 +0700 Subject: [PATCH] Automatically restart GraphQL server and Relay server when files are changed --- server/index.js | 48 ++++++++++++++++++++++++--------- server/utils/requireUncached.js | 4 +++ server/utils/updateSchema.js | 6 +++-- 3 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 server/utils/requireUncached.js diff --git a/server/index.js b/server/index.js index 6fc9578..8ba450a 100644 --- a/server/index.js +++ b/server/index.js @@ -4,23 +4,28 @@ import express from 'express'; import graphQLHTTP from 'express-graphql'; import WebpackDevServer from 'webpack-dev-server'; import gaze from 'gaze'; +import requireUncached from './utils/requireUncached'; import webpackConfig from '../webpack.config'; import config from './config/environment'; import schema from './data/schema'; import updateSchema from './utils/updateSchema'; -if (config.env === 'development') { - // Launch GraphQL +let graphQLServer; +let relayServer; + +function startGraphQLServer(schema) { const graphql = express(); graphql.use('/', graphQLHTTP({ graphiql: true, pretty: true, schema })); - graphql.listen(config.graphql.port, () => console.log(`GraphQL is listening on port ${config.graphql.port}`)); + graphQLServer = graphql.listen(config.graphql.port, () => console.log(`GraphQL is listening on port ${config.graphql.port}`)); +} +function startRelayServer() { // Launch Relay by using webpack.config.js - const app = new WebpackDevServer(webpack(webpackConfig), { + relayServer = new WebpackDevServer(webpack(webpackConfig), { contentBase: '/build/', proxy: { '/graphql': `http://localhost:${config.graphql.port}` @@ -33,21 +38,38 @@ if (config.env === 'development') { }); // Serve static resources - app.use('/', express.static(path.join(__dirname, '../build'))); - app.listen(config.port, () => console.log(`Relay is listening on port ${config.port}`)); + relayServer.use('/', express.static(path.join(__dirname, '../build'))); + relayServer.listen(config.port, () => console.log(`Relay is listening on port ${config.port}`)); +} + +if (config.env === 'development') { + // Start GraphQL and Relay servers + startGraphQLServer(schema); + startRelayServer(); // Watch JavaScript files in the data folder for changes, and update schema.json and schema.graphql gaze(path.join(__dirname, 'data/*.js'), (err, watcher) => { if (err) console.error('Error: Watching files in data folder'); - watcher.on('all', () => { - updateSchema(); + watcher.on('all', async() => { + try { + // Close the GraphQL server, update the schema.json and schema.graphql, and start the server again + graphQLServer.close(); + await updateSchema(); + const newSchema = requireUncached(path.join(__dirname, './data/schema')).default; + startGraphQLServer(newSchema); + + // Close the Relay server, and start it again + relayServer.listeningApp.close(); + startRelayServer(); + } catch (e) { + console.error(e.stack); + } }); }); } else if (config.env === 'production') { // Launch Relay by creating a normal express server - const app = express(); - app.use('/', express.static(path.join(__dirname, '../build'))); - app.use('/graphql', graphQLHTTP({ schema })); - app.listen(config.port, () => console.log(`App is listening on port ${config.port}`)); + relayServer = express(); + relayServer.use('/', express.static(path.join(__dirname, '../build'))); + relayServer.use('/graphql', graphQLHTTP({ schema })); + relayServer.listen(config.port, () => console.log(`App is listening on port ${config.port}`)); } - diff --git a/server/utils/requireUncached.js b/server/utils/requireUncached.js new file mode 100644 index 0000000..9e6836b --- /dev/null +++ b/server/utils/requireUncached.js @@ -0,0 +1,4 @@ +export default (module) => { + delete require.cache[require.resolve(module)]; + return require(module); +}; diff --git a/server/utils/updateSchema.js b/server/utils/updateSchema.js index de3d645..cd787bb 100644 --- a/server/utils/updateSchema.js +++ b/server/utils/updateSchema.js @@ -1,15 +1,17 @@ import path from 'path'; import fs from 'fs'; -import schema from '../data/schema'; import {graphql} from 'graphql'; import {introspectionQuery, printSchema} from 'graphql/utilities'; +import requireUncached from '../utils/requireUncached'; +const schemaFile = path.join(__dirname, '../data/schema.js'); const jsonFile = path.join(__dirname, '../data/schema.json'); const graphQLFile = path.join(__dirname, '../data/schema.graphql'); async function updateSchema() { try { - let json = await graphql(schema, introspectionQuery); + const schema = requireUncached(schemaFile).default; + const json = await graphql(schema, introspectionQuery); fs.writeFileSync(jsonFile, JSON.stringify(json, null, 2)); fs.writeFileSync(graphQLFile, printSchema(schema)); console.log('Schema has been regenerated');