Server Console App directly from the server.

Use Moustache to create template and set config in page.
Use babel plugins to process GQL (and fix GQL queries).
Added service type.
This commit is contained in:
richburdon
2020-05-27 19:09:20 -04:00
parent 0b0234761f
commit eb6bcd9c95
77 changed files with 586 additions and 210 deletions
+5
View File
@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
@@ -7,14 +7,14 @@ Apollo GraphQL client.
First start the server:
```bash
cd packages/consoe-server
cd packages/console-server
yarn start
```
Then start the Webpack devserver.
```bash
cd packages/consoe-client
cd packages/consoe-app
yarn start
```
@@ -8,6 +8,10 @@ module.exports = {
'@babel/preset-react'
],
plugins: [
// Allows export of components importing GQL files (without webpack).
'import-graphql',
'inline-json-import',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-export-default-from'
]
+41
View File
@@ -0,0 +1,41 @@
#
# NODE_ENV === production
# NOTE: Set CONFIG_FILE to swap out this config file.
#
app:
title: 'Console'
org': 'DxOS'
theme: 'dark'
website: 'https://dxos.org'
publicUrl: '/console'
api:
path: '/api'
port: 4000
intervalLog: 5000
pollInterval: 10000
system:
debug: 'dxos:console:*'
services:
app:
prefix: '/app'
server: 'http://127.0.0.1:5999'
wns:
server: 'http://127.0.0.1:9473/api'
webui: 'http://127.0.0.1:9473/webui'
signal:
server: 'http://127.0.0.1:4000'
api: 'http://127.0.0.1:4000'
ipfs:
server: '/ip4/127.0.0.1/tcp/5001'
gateway: '/ip4//127.0.0.1:8888/ipfs/'
webui: 'http://127.0.0.1:5001/webui'
wellknown:
endpoint: 'http://127.0.0.1:9000/.well-known/dxos'
@@ -1,18 +1,14 @@
{
"name": "@dxos/console-client",
"name": "@dxos/console-app",
"version": "1.0.0-beta.0",
"description": "DxOS Console Client",
"main": "dist/es/index.js",
"files": [
"config.yml",
"dist/production",
"gql"
"src/gql"
],
"scripts": {
"analyzer": "webpack --config webpack-analyzer.config.js",
"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=/console webpack --mode production",
"build": "babel ./src --out-dir ./dist/es --ignore \"**/*.test.js\" --source-maps inline",
"clean": "rm -rf dist",
"lint": "semistandard 'src/**/*.js'",
"start": "VERBOSE=true webpack-dev-server --mode development",
@@ -69,7 +65,9 @@
"babel-jest": "^24.8.0",
"babel-loader": "^8.0.0",
"babel-plugin-add-module-exports": "^1.0.2",
"babel-plugin-import-graphql": "^2.7.0",
"babel-plugin-inline-import": "^3.0.0",
"babel-plugin-inline-json-import": "^0.3.2",
"dotenv-webpack": "^1.8.0",
"eslint": "^6.7.2",
"eslint-config-semistandard": "^15.0.0",
@@ -94,6 +92,10 @@
"webpack-version-file-plugin": "^0.4.0",
"yaml-loader": "^0.6.0"
},
"peerDependencies": {
"react": "16.12.0",
"react-dom": "^16.12.0"
},
"publishConfig": {
"access": "public"
},
@@ -2,7 +2,6 @@
// Copyright 2020 DxOS.org
//
import debug from 'debug';
import React from 'react';
import { HashRouter, Redirect, Route, Switch } from 'react-router-dom';
import { ApolloProvider } from '@apollo/react-hooks';
@@ -11,11 +10,10 @@ import CssBaseline from '@material-ui/core/CssBaseline';
import { ErrorHandler } from '@dxos/debug';
import config from '../../config.yml';
import { build } from '../../version.json';
import { build } from '../version.json';
import { createTheme } from '../theme';
import { clientFactory } from '../client';
import { createTheme } from '../theme';
import modules from '../modules';
import Layout from './Layout';
@@ -30,18 +28,15 @@ import Signaling from './panels/Signaling';
import Status from './panels/Status';
import WNS from './panels/wns/WNS';
// TODO(burdon): Config object.
Object.assign(config, { build });
debug.enable(config.system.debug);
// Global error handler.
const errorHandler = new ErrorHandler();
/**
* Root application.
*/
const Main = () => {
const Main = ({ config }) => {
Object.assign(config, { build });
return (
<ApolloProvider client={clientFactory(config)}>
<ConsoleContextProvider config={config} modules={modules} errorHandler={errorHandler}>
@@ -7,8 +7,8 @@ import React, { useEffect, useState } from 'react';
import { useQuery } from '@apollo/react-hooks';
import { makeStyles } from '@material-ui/core';
import SYSTEM_STATUS from '../../gql/system_status.graphql';
import WNS_RECORDS from '../../gql/wns_records.graphql';
import SYSTEM_STATUS from '../gql/system_status.graphql';
import WNS_RECORDS from '../gql/wns_records.graphql';
import { useQueryStatusReducer } from '../hooks';
@@ -38,6 +38,7 @@ const VersionCheck = () => {
const { dxos: { image: current } } = JSON.parse(status.system_status.json);
let latest = current;
data.wns_records.json.forEach(({ attributes: { name, version } }) => {
// TODO(burdon): Filter by type (WRN?)
if (name.startsWith('dxos/xbox:')) {
if (compareVersions(version, latest) > 0) {
latest = version;
@@ -7,7 +7,7 @@ import { useQuery } from '@apollo/react-hooks';
import Json from '../../components/Json';
import SYSTEM_STATUS from '../../../gql/system_status.graphql';
import SYSTEM_STATUS from '../../gql/system_status.graphql';
import { ConsoleContext, useQueryStatusReducer } from '../../hooks';
@@ -5,7 +5,7 @@
import React, { useContext } from 'react';
import { useQuery } from '@apollo/react-hooks';
import WNS_RECORDS from '../../../../gql/wns_records.graphql';
import WNS_RECORDS from '../../../gql/wns_records.graphql';
import { ConsoleContext, useQueryStatusReducer, useSorter } from '../../../hooks';
@@ -5,7 +5,7 @@
import React, { useContext } from 'react';
import { useQuery } from '@apollo/react-hooks';
import WNS_RECORDS from '../../../../gql/wns_records.graphql';
import WNS_RECORDS from '../../../gql/wns_records.graphql';
import { ConsoleContext, useQueryStatusReducer, useSorter } from '../../../hooks';
@@ -5,7 +5,7 @@
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import IPFS_STATUS from '../../../../gql/ipfs_status.graphql';
import IPFS_STATUS from '../../../gql/ipfs_status.graphql';
import { useQueryStatusReducer } from '../../../hooks';
@@ -5,7 +5,7 @@
import React, { useContext } from 'react';
import { useQuery } from '@apollo/react-hooks';
import WNS_LOG from '../../../../gql/wns_log.graphql';
import WNS_LOG from '../../../gql/wns_log.graphql';
import { ConsoleContext, useQueryStatusReducer } from '../../../hooks';
@@ -13,7 +13,7 @@ import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import TableBody from '@material-ui/core/TableBody';
import WNS_RECORDS from '../../../../gql/wns_records.graphql';
import WNS_RECORDS from '../../../gql/wns_records.graphql';
import { ConsoleContext, useQueryStatusReducer, useSorter } from '../../../hooks';
@@ -26,9 +26,10 @@ const types = [
{ key: null, label: 'ALL' },
{ key: 'wrn:xbox', label: 'XBox' },
{ key: 'wrn:resource', label: 'Resource' },
{ key: 'wrn:service', label: 'Service' },
{ key: 'wrn:app', label: 'App' },
{ key: 'wrn:bot', label: 'Bot' },
{ key: 'wrn:type', label: 'Type' },
{ key: 'wrn:type', label: 'Type' }
];
const useStyles = makeStyles(theme => ({
@@ -5,7 +5,7 @@
import React, { useContext } from 'react';
import { useQuery } from '@apollo/react-hooks';
import WNS_STATUS from '../../../../gql/wns_status.graphql';
import WNS_STATUS from '../../../gql/wns_status.graphql';
import { ConsoleContext, useQueryStatusReducer } from '../../../hooks';
@@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
ipfs_status {
json
}
@@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
system_status {
timestamp
json
@@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
wns_log @client {
timestamp
log
@@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
wns_status @client {
timestamp
json
@@ -29,11 +29,11 @@ export const useQueryStatusReducer = ({ loading, error, data }) => {
useEffect(() => {
if (loading) {
setTimeout(() => setStatus({ loading }));
setStatus({ loading });
}
if (error) {
setTimeout(() => setStatus({ error }));
setStatus({ error });
}
}, [loading, error]);
+9
View File
@@ -0,0 +1,9 @@
//
// Copyright 2020 DxOS.org
//
import Main from './containers/Main';
export {
Main
};
+15
View File
@@ -0,0 +1,15 @@
//
// Copyright 2020 DxOS.org
//
import debug from 'debug';
import React from 'react';
import { render } from 'react-dom';
import config from '../config.yml';
import Main from './containers/Main';
debug.enable(config.system.debug);
render(<Main config={config} />, document.getElementById('root'));
@@ -1,7 +1,7 @@
{
"build": {
"name": "@dxos/console-client",
"buildDate": "2020-05-27T01:16:27.565Z",
"buildDate": "2020-05-27T22:04:52.661Z",
"version": "1.0.0-beta.0"
}
}
@@ -9,10 +9,10 @@ const webpack = require('webpack');
const PUBLIC_URL = process.env.PUBLIC_URL || '';
// TODO(burdon): Remove.
const STACK_CONFIG = process.env.CONFIG || 'default';
module.exports = {
devtool: 'eval-source-map',
devServer: {
@@ -30,7 +30,6 @@ module.exports = {
fs: 'empty'
},
// TODO(burdon): Config production path for apollo (diff webpack config).
output: {
path: `${__dirname}/dist/production`,
filename: '[name].bundle.js',
@@ -74,9 +73,6 @@ module.exports = {
// NOTE: Must be defined below Dotenv (otherwise will override).
// https://webpack.js.org/plugins/environment-plugin
new webpack.EnvironmentPlugin({
PUBLIC_URL: String(PUBLIC_URL),
STACK_CONFIG: String(STACK_CONFIG),
DEBUG: ''
}),
// Define the build config file based on the target.
@@ -87,14 +83,14 @@ module.exports = {
// https://www.npmjs.com/package/webpack-version-file-plugin
new VersionFile({
template: path.join(__dirname, 'version.ejs'),
packageFile: path.join(__dirname, 'package.json'),
outputFile: path.join(__dirname, 'version.json')
}),
outputFile: path.join(__dirname, 'src', 'version.json')
})
],
module: {
rules: [
// js
{
test: /\.js$/,
exclude: /(node_modules)/,
@@ -108,27 +104,6 @@ module.exports = {
test: /\.ya?ml$/,
type: 'json',
use: 'yaml-loader'
},
// https://www.apollographql.com/docs/react/integrations/webpack
{
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader'
},
// fonts
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
]
},
@@ -8,8 +8,7 @@ const HtmlWebPackPlugin = require('html-webpack-plugin');
const commonConfig = require('./webpack-common.config');
module.exports = merge(commonConfig, {
entry: './src/main',
entry: './src/main.js',
plugins: [
// https://github.com/jantimon/html-webpack-plugin#options
-5
View File
@@ -1,5 +0,0 @@
//
// Copyright 2020 DxOS.org
//
export * from './hooks';
-10
View File
@@ -1,10 +0,0 @@
//
// Copyright 2020 DxOS.org
//
import React from 'react';
import { render } from 'react-dom';
import Main from './containers/Main';
render(<Main />, document.getElementById('root'));
+34 -2
View File
@@ -4,9 +4,41 @@ Apollo GraphQL client.
## Usage
Use the following command to run the server at: http://localhost:4000
```bash
yarn
yarn start
```
To test the Console app, the `@dxos/console-app` must be built first:
```bash
cd ../console-app
yarn build
```
Use the following command to run the client in development mode (via the `webpack-dev-server`) at http://localhost:8080
```bash
yarn dev
```
To build the client and serve it directly from the server:
```bash
yarn build
yarn start
```
http://localhost:4000
Then open the app at: http://localhost:4000/console
## Production
When running the Console server, either set the `CONFIG_FILE` environment variable or set the `--config` option.
```bash
./bin/console.js --config ./config.yml
```
NOTE: The server passes its configuration directly to the Console app when it is loaded.
+9 -6
View File
@@ -4,20 +4,23 @@
module.exports = {
presets: [
[
'@babel/preset-env'
]
'@babel/preset-env',
'@babel/preset-react'
],
plugins: [
[
'babel-plugin-inline-import', {
extensions: [
'.graphql',
'.proto',
'.txt'
'.mustache',
'.graphql'
]
}
],
// Allows export of components importing GQL files (without webpack).
'import-graphql',
'inline-json-import',
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-export-default-from'
]
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env node
module.exports = require('../dist/es/server/main.js');
@@ -3,6 +3,8 @@
# NOTE: Set CONFIG_FILE to swap out this config file.
#
# TODO(burdon): Set defaults.
app:
title: 'Console'
org': 'DxOS'
@@ -18,23 +20,19 @@ api:
system:
debug: 'dxos:console:*'
xbox:
image: '/opt/xbox/IMAGE'
services:
app:
prefix: '/app'
server: 'http://127.0.0.1:5999' # TODO(burdon): ???
server: 'http://127.0.0.1:5999'
wns:
server: 'https://node1.dxos.network/wns/api'
webui: 'https://node1.dxos.network/wns/webui'
# server: 'http://127.0.0.1:9473/api'
# webui: 'http://127.0.0.1:9473/webui'
signal:
server: 'http://127.0.0.1:4000'
api: 'http://127.0.0.1:4000' # TODO(burdon): ???
api: 'http://127.0.0.1:4000'
ipfs:
server: '/ip4/127.0.0.1/tcp/5001'
+33 -6
View File
@@ -1,12 +1,24 @@
{
"name": "@dxos/console-server",
"name": "@dxos/console",
"version": "1.0.0-beta.0",
"description": "DxOS Console Server",
"main": "index.js",
"main": "dist/es/index.js",
"bin": {
"console": "bin/console.js"
},
"files": [
"bin/",
"dist/es"
],
"scripts": {
"build": "npm run clean && npm run build:client && npm run build:server",
"build:client": "PUBLIC_URL=/console webpack --mode development",
"build:server": "babel ./src --out-dir ./dist/es --ignore \"**/*.test.js\" --copy-files",
"clean": "rm -rf ./dist",
"dev": "VERBOSE=true webpack-dev-server --mode development --watch",
"lint": "semistandard 'src/**/*.js'",
"test": "jest --rootDir ./src --passWithNoTests --no-cache",
"start": "BABEL_DISABLE_CACHE=1 nodemon --exec babel-node ./src/main.js"
"start": "CONFIG_FILE=./config.yml BABEL_DISABLE_CACHE=1 nodemon --exec babel-node src/server/main.js -- --verbose"
},
"author": "DxOS.org",
"license": "GPL-3.0",
@@ -17,8 +29,9 @@
"testEnvironment": "node"
},
"dependencies": {
"@babel/polyfill": "^7.8.7",
"@babel/runtime": "^7.8.7",
"@dxos/console-client": "^1.0.0-beta.0",
"@dxos/console-app": "^1.0.0-beta.0",
"apollo-boost": "^0.4.9",
"apollo-server-express": "^2.13.1",
"debug": "^4.1.1",
@@ -28,8 +41,11 @@
"graphql-tag": "^2.10.3",
"ipfs-http-client": "^44.1.0",
"js-yaml": "^3.14.0",
"mustache-express": "^1.3.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"source-map-support": "^0.5.12"
"source-map-support": "^0.5.12",
"yargs": "^15.3.1"
},
"devDependencies": {
"@babel/cli": "7.4.4",
@@ -40,8 +56,13 @@
"@babel/preset-env": "^7.4.5",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.8.0",
"babel-loader": "^8.1.0",
"babel-plugin-add-module-exports": "^1.0.2",
"babel-plugin-import-graphql": "^2.7.0",
"babel-plugin-inline-import": "^3.0.0",
"babel-plugin-inline-json-import": "^0.3.2",
"body-parser": "^1.19.0",
"dotenv-webpack": "^1.8.0",
"eslint": "^6.7.2",
"eslint-config-semistandard": "^15.0.0",
"eslint-config-standard": "^14.1.1",
@@ -54,7 +75,13 @@
"eslint-plugin-standard": "^4.0.1",
"jest": "^24.8.0",
"nodemon": "^2.0.4",
"semistandard": "^14.2.0"
"react": "^16.13.1",
"react-dom": "^16.13.1",
"semistandard": "^14.2.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2"
},
"publishConfig": {
"access": "public"
+10
View File
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= title %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
@@ -0,0 +1,16 @@
//
// Copyright 2020 DxOS.org
//
import debug from 'debug';
import React from 'react';
import { render } from 'react-dom';
import { Main } from '@dxos/console-client';
// Load from global printed into HTML page via template.
const { config } = window.__DXOS__;
debug.enable(config.system.debug);
render(<Main config={config} />, document.getElementById('root'));
-101
View File
@@ -1,101 +0,0 @@
//
// Copyright 2020 DxOS.org
//
import debug from 'debug';
import express from 'express';
import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';
import { ApolloServer, gql } from 'apollo-server-express';
import { print } from 'graphql/language';
import SYSTEM_STATUS from '@dxos/console-client/gql/system_status.graphql';
import { createResolvers } from './resolvers';
import SCHEMA from './gql/api.graphql';
const config = yaml.safeLoad(
fs.readFileSync(path.join(__dirname, '../../../node_modules/@dxos/console-client/config.yml')));
const log = debug('dxos:console:server');
debug.enable(config.system.debug);
//
// Express 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
// app.use(cors({
// origin: true,
// credentials: true
// }));
//
// React app
//
const { app: { publicUrl } } = config;
// TODO(burdon): Load via WNS.
app.get(`${publicUrl}(/: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: createResolvers(config),
// https://www.apollographql.com/docs/apollo-server/testing/graphql-playground
// https://github.com/prisma-labs/graphql-playground#usage
// introspection: true,
playground: {
settings: {
'editor.theme': 'light'
},
tabs: [
{
name: 'Status',
endpoint: config.api.path,
query: print(gql(SYSTEM_STATUS))
}
]
}
});
//
// Apollo middleware
// https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserverapplymiddleware
//
server.applyMiddleware({
app,
path: config.api.path
});
//
// Start server
//
const { api: { port } } = config;
app.listen({ port }, () => {
log(`Running: http://localhost:${port}`);
});
+138
View File
@@ -0,0 +1,138 @@
//
// Copyright 2020 DxOS.org
//
import bodyParser from 'body-parser';
import debug from 'debug';
import express from 'express';
import mustache from 'mustache-express';
import fs from 'fs';
import yaml from 'js-yaml';
import { ApolloServer, gql } from 'apollo-server-express';
import { print } from 'graphql/language';
import yargs from 'yargs';
import SYSTEM_STATUS from '@dxos/console-client/src/gql/system_status.graphql';
import { createResolvers } from './resolvers';
import SCHEMA from '../gql/api.graphql';
const argv = yargs
.option('config', {
alias: 'c',
description: 'Config file',
type: 'string'
})
.option('verbose', {
alias: 'v',
description: 'Verbse info',
type: 'boolean'
})
.help()
.alias('help', 'h')
.argv;
const configFile = argv.config || process.env.CONFIG_FILE;
if (!configFile) {
yargs.showHelp();
process.exit(1);
}
const config = yaml.safeLoad(fs.readFileSync(configFile));
const log = debug('dxos:console:server');
debug.enable(config.system.debug);
if (argv.verbose) {
log(JSON.stringify(config, undefined, 2));
}
//
// Express server.
//
const app = express();
app.set('views', `${__dirname}/views`);
app.set('view engine', 'mustache');
app.engine('mustache', mustache());
app.use(bodyParser.urlencoded({ extended: true }));
// TODO(burdon): Add react, webpack deps
// TODO(burdon): app.use(compression());
//
// 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
// app.use(cors({
// origin: true,
// credentials: true
// }));
//
// React app
// TODO(burdon): Can we load this via WNS?
//
const { app: { publicUrl } } = config;
const bundles = [
'runtime', 'vendor', 'material-ui', 'dxos', 'main'
];
app.use(`${publicUrl}/lib`, express.static('./dist/client'));
app.get(publicUrl, (req, res) => {
res.render('console', {
title: 'Console',
container: 'root',
config: JSON.stringify(config),
scripts: bundles.map(bundle => ({ src: `${publicUrl}/lib/${bundle}.bundle.js` }))
});
});
//
// Apollo Server and middleware
// https://www.apollographql.com/docs/apollo-server/api/apollo-server
// https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserverapplymiddleware
//
const server = new ApolloServer({
typeDefs: SCHEMA,
resolvers: createResolvers(config),
// https://www.apollographql.com/docs/apollo-server/testing/graphql-playground
// https://github.com/prisma-labs/graphql-playground#usage
// introspection: true,
playground: {
settings: {
'editor.theme': config.app.theme
},
tabs: [
{
name: 'Status',
endpoint: config.api.path,
query: print(gql(SYSTEM_STATUS))
}
]
}
});
server.applyMiddleware({ app, path: config.api.path });
//
// Start server
//
const { api: { port } } = config;
app.listen({ port }, () => {
log(`Running: http://localhost:${port}`);
});
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<div id="{{ container }}"></div>
<!-- Config loaded by client. -->
<script charset="utf-8" type="application/javascript">
window.__DXOS__ = { config: {{{ config }}} };
</script>
<!-- React bundles. -->
{{#scripts}}
<script charset="utf-8" type="application/javascript" src="{{src}}"></script>
{{/scripts}}
</body>
</html>
+110
View File
@@ -0,0 +1,110 @@
//
// Copyright 2019 DxOS
//
const path = require('path');
const Dotenv = require('dotenv-webpack');
const webpack = require('webpack');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const PUBLIC_URL = process.env.PUBLIC_URL || '';
module.exports = {
devtool: 'eval-source-map',
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
disableHostCheck: true,
port: 8080,
watchOptions: {
ignored: /node_modules/,
aggregateTimeout: 600
}
},
node: {
fs: 'empty'
},
entry: './src/client/main.js',
output: {
path: `${__dirname}/dist/client`,
filename: '[name].bundle.js',
publicPath: PUBLIC_URL
},
optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name (module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
if (packageName.startsWith('@dxos')) {
return 'dxos';
}
if (packageName.startsWith('@material-ui')) {
return 'material-ui';
}
return 'vendor';
}
}
}
}
},
plugins: [
// https://github.com/jantimon/html-webpack-plugin#options
new HtmlWebPackPlugin({
template: './public/index.html',
templateParameters: {
title: 'DxOS Console'
}
}),
// https://www.npmjs.com/package/dotenv-webpack#properties
new Dotenv({
path: process.env.DOT_ENV || '.env'
}),
// NOTE: Must be defined below Dotenv (otherwise will override).
// https://webpack.js.org/plugins/environment-plugin
new webpack.EnvironmentPlugin({})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader'
}
},
// https://github.com/eemeli/yaml-loader
{
test: /\.ya?ml$/,
type: 'json',
use: 'yaml-loader'
}
]
},
resolve: {
alias: {
'@material-ui/styles': path.resolve(__dirname, '..', '..', 'node_modules/@material-ui/styles'),
'react': path.resolve(__dirname, '..', '..', 'node_modules/react'),
'react-dom': path.resolve(__dirname, '..', '..', 'node_modules/react-dom')
}
}
};
+95 -7
View File
@@ -904,6 +904,14 @@
"@babel/helper-create-regexp-features-plugin" "^7.8.3"
"@babel/helper-plugin-utils" "^7.8.3"
"@babel/polyfill@^7.8.7":
version "7.8.7"
resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.8.7.tgz#151ec24c7135481336168c3bd8b8bf0cf91c032f"
integrity sha512-LeSfP9bNZH2UOZgcGcZ0PIHUt1ZuHub1L3CVmEyqLxCeDLm4C5Gi8jRH8ZX2PNpDhQCo0z6y/+DIs2JlliXW8w==
dependencies:
core-js "^2.6.5"
regenerator-runtime "^0.13.4"
"@babel/preset-env@7.9.0":
version "7.9.0"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.0.tgz#a5fc42480e950ae8f5d9f8f2bbc03f52722df3a8"
@@ -3539,7 +3547,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
ansi-styles@^4.1.0:
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
@@ -4036,6 +4044,11 @@ async@^2.6.2:
dependencies:
lodash "^4.17.14"
async@~3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/async/-/async-3.1.1.tgz#dd3542db03de837979c9ebbca64ca01b06dc98df"
integrity sha512-X5Dj8hK1pJNC2Wzo2Rcp9FBVdJMGRR/S7V+lH46s8GVFhtbo5O4Le5GECCF/8PISVdkUA6mMPvgz7qTTD1rf1g==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -4125,7 +4138,7 @@ babel-jest@^24.8.0, babel-jest@^24.9.0:
chalk "^2.4.2"
slash "^2.0.0"
babel-loader@8.1.0, babel-loader@^8.0.0:
babel-loader@8.1.0, babel-loader@^8.0.0, babel-loader@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3"
integrity sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==
@@ -4150,6 +4163,13 @@ babel-plugin-dynamic-import-node@^2.3.3:
dependencies:
object.assign "^4.1.0"
babel-plugin-import-graphql@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/babel-plugin-import-graphql/-/babel-plugin-import-graphql-2.7.0.tgz#984b2330afa05cce5ff81e577f7d82cdb86aea6d"
integrity sha512-PCNT6hLXaFxb7bsXJ+ALFnEnZUK2Hj1HhM0nWv4XDpuYf8arulm7ZAu/Z0MBItLkcik/TAokGX9IUzwyTYMXvQ==
dependencies:
graphql-tag "^2.9.2"
babel-plugin-inline-import@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/babel-plugin-inline-import/-/babel-plugin-inline-import-3.0.0.tgz#220eb2a52f8e779d8fb89447f950275e1e3f5981"
@@ -4157,6 +4177,13 @@ babel-plugin-inline-import@^3.0.0:
dependencies:
require-resolve "0.0.2"
babel-plugin-inline-json-import@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/babel-plugin-inline-json-import/-/babel-plugin-inline-json-import-0.3.2.tgz#fdec1a59364d632895d421aec4c9435ccbbcadd3"
integrity sha512-QNNJx08KjmMT25Cw7rAPQ6dlREDPiZGDyApHL8KQ9vrQHbrr4PTi7W8g1tMMZPz0jEMd39nx/eH7xjnDNxq5sA==
dependencies:
decache "^4.5.1"
babel-plugin-istanbul@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854"
@@ -4417,7 +4444,7 @@ bn.js@^5.1.1:
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.2.tgz#c9686902d3c9a27729f43ab10f9d79c2004da7b0"
integrity sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==
body-parser@1.19.0, body-parser@^1.18.3:
body-parser@1.19.0, body-parser@^1.18.3, body-parser@^1.19.0:
version "1.19.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==
@@ -4818,6 +4845,11 @@ caller-path@^2.0.0:
dependencies:
caller-callsite "^2.0.0"
callsite@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
callsites@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
@@ -5120,6 +5152,15 @@ cliui@^5.0.0:
strip-ansi "^5.2.0"
wrap-ansi "^5.1.0"
cliui@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
clone-deep@^0.2.4:
version "0.2.4"
resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6"
@@ -5531,7 +5572,7 @@ core-js-pure@^3.0.0:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813"
integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==
core-js@^2.4.0:
core-js@^2.4.0, core-js@^2.6.5:
version "2.6.11"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
@@ -6244,6 +6285,13 @@ debuglog@^1.0.1:
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
decache@^4.5.1:
version "4.6.0"
resolved "https://registry.yarnpkg.com/decache/-/decache-4.6.0.tgz#87026bc6e696759e82d57a3841c4e251a30356e8"
integrity sha512-PppOuLiz+DFeaUvFXEYZjLxAkKiMYH/do/b/MxpDe/8AgKBi5GhZxridoVIbBq72GDbL36e4p0Ce2jTGUwwU+w==
dependencies:
callsite "^1.0.0"
decamelize-keys@^1.0.0, decamelize-keys@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9"
@@ -10931,7 +10979,7 @@ lru-cache@^4.0.1:
pseudomap "^1.0.2"
yallist "^2.1.2"
lru-cache@^5.0.0, lru-cache@^5.1.1:
lru-cache@^5.0.0, lru-cache@^5.1.1, lru-cache@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
@@ -11525,6 +11573,20 @@ murmurhash3js-revisited@^3.0.0:
resolved "https://registry.yarnpkg.com/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz#6bd36e25de8f73394222adc6e41fa3fac08a5869"
integrity sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==
mustache-express@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/mustache-express/-/mustache-express-1.3.0.tgz#91d67121e3553d42d6c995f4c32793db89492493"
integrity sha512-JWG8Rzxh9tpoLEH0NZ2u/caDiwhIkW+50IOBrcO+lHya3tCYj41bYPDEHCxPbKXvPrSyMNpI6ly4xdU2zpNQtg==
dependencies:
async "~3.1.0"
lru-cache "~5.1.1"
mustache "^3.1.0"
mustache@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/mustache/-/mustache-3.2.1.tgz#89e78a9d207d78f2799b1e95764a25bf71a28322"
integrity sha512-RERvMFdLpaFfSRIEe632yDm5nsd0SDKn8hGmcUwswnyiE5mtdZLDybtHAz6hjJhawokF0hXvGLtx9mrQfm6FkA==
mute-stream@0.0.7:
version "0.0.7"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab"
@@ -15238,7 +15300,7 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
string-width@^4.0.0, string-width@^4.1.0:
string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
@@ -16834,6 +16896,15 @@ wrap-ansi@^5.1.0:
string-width "^3.0.0"
strip-ansi "^5.0.0"
wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -17016,7 +17087,7 @@ yargs-parser@^15.0.1:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^18.1.3:
yargs-parser@^18.1.1, yargs-parser@^18.1.3:
version "18.1.3"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
@@ -17092,6 +17163,23 @@ yargs@^14.2.2:
y18n "^4.0.0"
yargs-parser "^15.0.1"
yargs@^15.3.1:
version "15.3.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b"
integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==
dependencies:
cliui "^6.0.0"
decamelize "^1.2.0"
find-up "^4.1.0"
get-caller-file "^2.0.1"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^4.2.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^18.1.1"
zen-observable-ts@^0.8.21:
version "0.8.21"
resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d"