Serves react app from server.

This commit is contained in:
richburdon 2020-05-23 14:36:15 -04:00
parent 94559bdf47
commit f54cd5b46a
16 changed files with 3266 additions and 178 deletions

View File

@ -5,6 +5,8 @@ Apollo GraphQL client and server using express.
## Tasks
- [ ] Server React app from server.
- https://www.freecodecamp.org/news/how-to-set-up-deploy-your-react-app-from-scratch-using-webpack-and-babel-a669891033d4/
- [ ] Trigger server-side commands (separate express path?)
- [ ] Material UI.

View File

@ -0,0 +1,39 @@
# Console
Apollo GraphQL client.
## Usage
```bash
yarn
yarn start
```
http://localhost:8080
## Deploy
```bash
yarn build
```
This creates the following folders:
```
/dist
/es # Module imports.
/production # Production build.
```
NOTE: GQL and Production files and exported and may be used by the server.
```javascript
import QUERY_STATUS from '@dxos/console-client/gql/status.graphql';
import config from '@dxos/console-client/config.json';
...
const file = path.join(__dirname + '../../../../node_modules/@dxos/console-client/dist/production', 'index.html');
res.sendFile(file);
```

View File

@ -1,4 +1,5 @@
{
"public_url": "/app",
"port": 4000,
"path": "/graphql"
}

View File

@ -3,9 +3,16 @@
"version": "1.0.0-beta.0",
"description": "DxOS Console Client",
"main": "dist/es/index.js",
"files": [
"config.json",
"dist/production",
"gql"
],
"scripts": {
"analyzer": "webpack --config webpack-analyzer.config.js",
"build": "npm run clean && babel ./src --out-dir ./dist/es --ignore \"**/*.test.js\" --source-maps inline",
"build": "npm run clean && npm run build:module && npm run build:production",
"build:module": "babel ./src --out-dir ./dist/es --ignore \"**/*.test.js\" --source-maps inline",
"build:production": "PUBLIC_URL=/app webpack --mode production",
"clean": "rm -rf dist",
"lint": "semistandard 'src/**/*.js'",
"start": "VERBOSE=true webpack-dev-server --mode development",
@ -34,7 +41,7 @@
"@babel/core": "^7.4.5",
"@babel/node": "^7.8.7",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-export-default-from": "^7.5.2",
"@babel/plugin-proposal-export-default-from": "^7.8.3",
"@babel/preset-env": "^7.4.5",
"@babel/preset-react": "^7.0.0",
"babel-eslint": "^10.0.2",
@ -48,11 +55,12 @@
"eslint-plugin-react": "^7.17.0",
"html-webpack-plugin": "^4.3.0",
"jest": "^24.8.0",
"react-scripts": "^3.4.1",
"semistandard": "^14.2.0",
"webpack": "^4.41.2",
"webpack-bundle-analyzer": "^3.6.0",
"webpack-dev-server": "^3.11.0",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2",
"webpack-version-file-plugin": "^0.4.0"
},

View File

@ -2,12 +2,15 @@
// Copyright 2020 DxOS
//
import { useQuery } from '@apollo/react-hooks';
import debug from 'debug';
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import QUERY_STATUS from '../gql/status.graphql';
import QUERY_STATUS from '../../gql/status.graphql';
const App = () => {
const log = debug('dxos:console:client:app');
const Status = () => {
const { loading, error, data } = useQuery(QUERY_STATUS);
if (loading) {
return <div>Loading...</div>;
@ -16,6 +19,8 @@ const App = () => {
return <div>Error: ${error}</div>;
}
log(JSON.stringify(data));
return (
<pre>
{JSON.stringify(data, undefined, 2)}
@ -23,4 +28,4 @@ const App = () => {
);
};
export default App;
export default Status;

View File

@ -0,0 +1,31 @@
//
// Copyright 2020 DxOS
//
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient from 'apollo-boost';
import React from 'react';
import Status from '../components/Status';
import config from '../../config.json';
const { port, path } = config;
// TODO(burdon): Error handling for server errors.
// TODO(burdon): Authentication:
// https://www.apollographql.com/docs/react/networking/authentication/
const client = new ApolloClient({
uri: `http://localhost:${port}${path}`
});
const Main = () => {
return (
<ApolloProvider client={client}>
<Status />
</ApolloProvider>
);
};
export default Main;

View File

@ -0,0 +1,5 @@
//
// Copyright 2020 DxOS
//
export Main from './main';

View File

@ -2,30 +2,12 @@
// Copyright 2020 DxOS
//
import { ApolloProvider } from '@apollo/react-hooks';
import ApolloClient from 'apollo-boost';
import debug from 'debug';
import React from 'react';
import { render } from 'react-dom';
import App from './components/App';
import Main from './containers/Main';
const PORT = 4000;
const client = new ApolloClient({
uri: `http://localhost:${PORT}/graphql`
});
// TODO(burdon): Error handling for server errors.
// TODO(burdon): Auth
// https://www.apollographql.com/docs/react/networking/authentication/
const Main = () => {
return (
<ApolloProvider client={client}>
<App />
</ApolloProvider>
);
};
debug.enable('dxos:console:client:*');
render(<Main />, document.getElementById('root'));

View File

@ -1,7 +1,7 @@
{
"build": {
"name": "@dxos/console-client",
"buildDate": "2020-05-23T17:02:38.800Z",
"buildDate": "2020-05-23T18:35:48.873Z",
"version": "1.0.0-beta.0"
}
}

View File

@ -30,8 +30,9 @@ module.exports = {
fs: 'empty'
},
// TODO(burdon): Config production path for apollo (diff webpack config).
output: {
path: `${__dirname}/dist`,
path: `${__dirname}/dist/production`,
filename: '[name].bundle.js',
publicPath: PUBLIC_URL
},

View File

@ -0,0 +1,12 @@
# Console
Apollo GraphQL client.
## Usage
```bash
yarn
yarn start
```
http://localhost:4000

View File

@ -26,6 +26,7 @@
"express-graphql": "^0.9.0",
"graphql": "^15.0.0",
"graphql-tag": "^2.10.3",
"react-dom": "^16.13.1",
"source-map-support": "^0.5.12"
},
"devDependencies": {

View File

@ -8,28 +8,30 @@ import path from 'path';
import { ApolloServer, gql } from 'apollo-server-express';
import { print } from 'graphql/language';
import SCHEMA from './gql/api.graphql';
import QUERY_STATUS from './gql/status.graphql';
import QUERY_STATUS from '@dxos/console-client/gql/status.graphql';
import clientConfig from '@dxos/console-client/config.json';
import { resolvers } from './resolvers';
import config from '../config.json';
import { version } from '../package.json';
const log = debug('c2:src');
debug.enable('c2:*');
import SCHEMA from './gql/api.graphql';
// Resolver
const resolvers = {
Query: {
status: () => ({
version
})
}
};
const log = debug('dxos:console:server');
// TODO(burdon): Config.
debug.enable('dxos:console:*');
//
// Express server.
//
// Server
const app = express();
//
// CORS
//
// import cors from 'cors'
// https://expressjs.com/en/resources/middleware/cors.html
// https://www.prisma.io/blog/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d
@ -38,14 +40,23 @@ const app = express();
// credentials: true
// }));
//
// React app
// TODO(burdon): Create HTML file.
// TODO(burdon): Load JS.
app.get('/app', (req,res) =>{
res.sendFile(path.join(__dirname + '/../../../node_modules/@dxos/console-client/dist/es/main.js'));
//
const { public_url } = clientConfig;
app.get(`${public_url}(/:filePath)?`, (req, res) => {
const { filePath = 'index.html' } = req.params;
const file = path.join(__dirname + '../../../../node_modules/@dxos/console-client/dist/production', filePath);
res.sendFile(file);
});
//
// Apollo Server
// https://www.apollographql.com/docs/apollo-server/api/apollo-server
//
const server = new ApolloServer({
typeDefs: SCHEMA,
resolvers,
@ -66,12 +77,20 @@ const server = new ApolloServer({
}
});
//
// Apollo middleware
// https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserverapplymiddleware
//
server.applyMiddleware({
app,
path: config.path
});
//
// Start server
//
app.listen({ port: config.port }, () => {
log(`Running: http://localhost:${config.port}`);
});

View File

@ -0,0 +1,21 @@
//
// Copyright 2020 DxOS
//
import debug from 'debug';
import { version } from '../package.json';
const log = debug('dxos:console:resolver');
//
// Resolver
//
export const resolvers = {
Query: {
status: () => ({
version
})
}
};

3221
yarn.lock

File diff suppressed because it is too large Load Diff