forked from cerc-io/laconic-console
Serves react app from server.
This commit is contained in:
parent
94559bdf47
commit
f54cd5b46a
@ -5,6 +5,8 @@ Apollo GraphQL client and server using express.
|
|||||||
## Tasks
|
## Tasks
|
||||||
|
|
||||||
- [ ] Server React app from server.
|
- [ ] 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?)
|
- [ ] Trigger server-side commands (separate express path?)
|
||||||
|
|
||||||
- [ ] Material UI.
|
- [ ] Material UI.
|
||||||
|
39
packages/console-client/README.md
Normal file
39
packages/console-client/README.md
Normal 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);
|
||||||
|
```
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"public_url": "/app",
|
||||||
"port": 4000,
|
"port": 4000,
|
||||||
"path": "/graphql"
|
"path": "/graphql"
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,16 @@
|
|||||||
"version": "1.0.0-beta.0",
|
"version": "1.0.0-beta.0",
|
||||||
"description": "DxOS Console Client",
|
"description": "DxOS Console Client",
|
||||||
"main": "dist/es/index.js",
|
"main": "dist/es/index.js",
|
||||||
|
"files": [
|
||||||
|
"config.json",
|
||||||
|
"dist/production",
|
||||||
|
"gql"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"analyzer": "webpack --config webpack-analyzer.config.js",
|
"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",
|
"clean": "rm -rf dist",
|
||||||
"lint": "semistandard 'src/**/*.js'",
|
"lint": "semistandard 'src/**/*.js'",
|
||||||
"start": "VERBOSE=true webpack-dev-server --mode development",
|
"start": "VERBOSE=true webpack-dev-server --mode development",
|
||||||
@ -34,7 +41,7 @@
|
|||||||
"@babel/core": "^7.4.5",
|
"@babel/core": "^7.4.5",
|
||||||
"@babel/node": "^7.8.7",
|
"@babel/node": "^7.8.7",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.5.5",
|
"@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-env": "^7.4.5",
|
||||||
"@babel/preset-react": "^7.0.0",
|
"@babel/preset-react": "^7.0.0",
|
||||||
"babel-eslint": "^10.0.2",
|
"babel-eslint": "^10.0.2",
|
||||||
@ -48,11 +55,12 @@
|
|||||||
"eslint-plugin-react": "^7.17.0",
|
"eslint-plugin-react": "^7.17.0",
|
||||||
"html-webpack-plugin": "^4.3.0",
|
"html-webpack-plugin": "^4.3.0",
|
||||||
"jest": "^24.8.0",
|
"jest": "^24.8.0",
|
||||||
|
"react-scripts": "^3.4.1",
|
||||||
"semistandard": "^14.2.0",
|
"semistandard": "^14.2.0",
|
||||||
"webpack": "^4.41.2",
|
"webpack": "^4.41.2",
|
||||||
"webpack-bundle-analyzer": "^3.6.0",
|
"webpack-bundle-analyzer": "^3.6.0",
|
||||||
"webpack-dev-server": "^3.11.0",
|
|
||||||
"webpack-cli": "^3.3.10",
|
"webpack-cli": "^3.3.10",
|
||||||
|
"webpack-dev-server": "^3.11.0",
|
||||||
"webpack-merge": "^4.2.2",
|
"webpack-merge": "^4.2.2",
|
||||||
"webpack-version-file-plugin": "^0.4.0"
|
"webpack-version-file-plugin": "^0.4.0"
|
||||||
},
|
},
|
||||||
|
@ -2,12 +2,15 @@
|
|||||||
// Copyright 2020 DxOS
|
// Copyright 2020 DxOS
|
||||||
//
|
//
|
||||||
|
|
||||||
import { useQuery } from '@apollo/react-hooks';
|
import debug from 'debug';
|
||||||
import React from 'react';
|
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);
|
const { loading, error, data } = useQuery(QUERY_STATUS);
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return <div>Loading...</div>;
|
return <div>Loading...</div>;
|
||||||
@ -16,6 +19,8 @@ const App = () => {
|
|||||||
return <div>Error: ${error}</div>;
|
return <div>Error: ${error}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log(JSON.stringify(data));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<pre>
|
<pre>
|
||||||
{JSON.stringify(data, undefined, 2)}
|
{JSON.stringify(data, undefined, 2)}
|
||||||
@ -23,4 +28,4 @@ const App = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default App;
|
export default Status;
|
31
packages/console-client/src/containers/Main.js
Normal file
31
packages/console-client/src/containers/Main.js
Normal 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;
|
5
packages/console-client/src/index.js
Normal file
5
packages/console-client/src/index.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2020 DxOS
|
||||||
|
//
|
||||||
|
|
||||||
|
export Main from './main';
|
@ -2,30 +2,12 @@
|
|||||||
// Copyright 2020 DxOS
|
// Copyright 2020 DxOS
|
||||||
//
|
//
|
||||||
|
|
||||||
import { ApolloProvider } from '@apollo/react-hooks';
|
import debug from 'debug';
|
||||||
import ApolloClient from 'apollo-boost';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { render } from 'react-dom';
|
import { render } from 'react-dom';
|
||||||
|
|
||||||
import App from './components/App';
|
import Main from './containers/Main';
|
||||||
|
|
||||||
const PORT = 4000;
|
debug.enable('dxos:console:client:*');
|
||||||
|
|
||||||
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>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
render(<Main />, document.getElementById('root'));
|
render(<Main />, document.getElementById('root'));
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"build": {
|
"build": {
|
||||||
"name": "@dxos/console-client",
|
"name": "@dxos/console-client",
|
||||||
"buildDate": "2020-05-23T17:02:38.800Z",
|
"buildDate": "2020-05-23T18:35:48.873Z",
|
||||||
"version": "1.0.0-beta.0"
|
"version": "1.0.0-beta.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,9 @@ module.exports = {
|
|||||||
fs: 'empty'
|
fs: 'empty'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// TODO(burdon): Config production path for apollo (diff webpack config).
|
||||||
output: {
|
output: {
|
||||||
path: `${__dirname}/dist`,
|
path: `${__dirname}/dist/production`,
|
||||||
filename: '[name].bundle.js',
|
filename: '[name].bundle.js',
|
||||||
publicPath: PUBLIC_URL
|
publicPath: PUBLIC_URL
|
||||||
},
|
},
|
||||||
|
12
packages/console-server/README.md
Normal file
12
packages/console-server/README.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Console
|
||||||
|
|
||||||
|
Apollo GraphQL client.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn
|
||||||
|
yarn start
|
||||||
|
```
|
||||||
|
|
||||||
|
http://localhost:4000
|
@ -26,6 +26,7 @@
|
|||||||
"express-graphql": "^0.9.0",
|
"express-graphql": "^0.9.0",
|
||||||
"graphql": "^15.0.0",
|
"graphql": "^15.0.0",
|
||||||
"graphql-tag": "^2.10.3",
|
"graphql-tag": "^2.10.3",
|
||||||
|
"react-dom": "^16.13.1",
|
||||||
"source-map-support": "^0.5.12"
|
"source-map-support": "^0.5.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -8,28 +8,30 @@ import path from 'path';
|
|||||||
import { ApolloServer, gql } from 'apollo-server-express';
|
import { ApolloServer, gql } from 'apollo-server-express';
|
||||||
import { print } from 'graphql/language';
|
import { print } from 'graphql/language';
|
||||||
|
|
||||||
import SCHEMA from './gql/api.graphql';
|
import QUERY_STATUS from '@dxos/console-client/gql/status.graphql';
|
||||||
import QUERY_STATUS from './gql/status.graphql';
|
import clientConfig from '@dxos/console-client/config.json';
|
||||||
|
|
||||||
|
import { resolvers } from './resolvers';
|
||||||
|
|
||||||
import config from '../config.json';
|
import config from '../config.json';
|
||||||
import { version } from '../package.json';
|
|
||||||
|
|
||||||
const log = debug('c2:src');
|
import SCHEMA from './gql/api.graphql';
|
||||||
debug.enable('c2:*');
|
|
||||||
|
|
||||||
// Resolver
|
const log = debug('dxos:console:server');
|
||||||
const resolvers = {
|
|
||||||
Query: {
|
// TODO(burdon): Config.
|
||||||
status: () => ({
|
debug.enable('dxos:console:*');
|
||||||
version
|
|
||||||
})
|
//
|
||||||
}
|
// Express server.
|
||||||
};
|
//
|
||||||
|
|
||||||
// Server
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
|
//
|
||||||
// CORS
|
// CORS
|
||||||
|
//
|
||||||
|
|
||||||
// import cors from 'cors'
|
// import cors from 'cors'
|
||||||
// https://expressjs.com/en/resources/middleware/cors.html
|
// https://expressjs.com/en/resources/middleware/cors.html
|
||||||
// https://www.prisma.io/blog/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d
|
// https://www.prisma.io/blog/enabling-cors-for-express-graphql-apollo-server-1ef999bfb38d
|
||||||
@ -38,14 +40,23 @@ const app = express();
|
|||||||
// credentials: true
|
// credentials: true
|
||||||
// }));
|
// }));
|
||||||
|
|
||||||
|
//
|
||||||
// React app
|
// React app
|
||||||
// TODO(burdon): Create HTML file.
|
//
|
||||||
// TODO(burdon): Load JS.
|
|
||||||
app.get('/app', (req,res) =>{
|
const { public_url } = clientConfig;
|
||||||
res.sendFile(path.join(__dirname + '/../../../node_modules/@dxos/console-client/dist/es/main.js'));
|
|
||||||
|
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
|
// https://www.apollographql.com/docs/apollo-server/api/apollo-server
|
||||||
|
//
|
||||||
|
|
||||||
const server = new ApolloServer({
|
const server = new ApolloServer({
|
||||||
typeDefs: SCHEMA,
|
typeDefs: SCHEMA,
|
||||||
resolvers,
|
resolvers,
|
||||||
@ -66,12 +77,20 @@ const server = new ApolloServer({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Apollo middleware
|
||||||
// https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserverapplymiddleware
|
// https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserverapplymiddleware
|
||||||
|
//
|
||||||
|
|
||||||
server.applyMiddleware({
|
server.applyMiddleware({
|
||||||
app,
|
app,
|
||||||
path: config.path
|
path: config.path
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start server
|
||||||
|
//
|
||||||
|
|
||||||
app.listen({ port: config.port }, () => {
|
app.listen({ port: config.port }, () => {
|
||||||
log(`Running: http://localhost:${config.port}`);
|
log(`Running: http://localhost:${config.port}`);
|
||||||
});
|
});
|
||||||
|
21
packages/console-server/src/resolvers.js
Normal file
21
packages/console-server/src/resolvers.js
Normal 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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user