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

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>

View File

@ -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
```

View File

@ -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'
]

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'

View File

@ -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"
},

View File

@ -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}>

View File

@ -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;

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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';

View File

@ -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 => ({

View File

@ -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';

View File

@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
ipfs_status {
json
}

View File

@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
system_status {
timestamp
json

View File

@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
wns_log @client {
timestamp
log

View File

@ -2,7 +2,7 @@
# Copyright 2020 DxOS.org
#
{
query {
wns_status @client {
timestamp
json

View File

@ -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]);

View File

@ -0,0 +1,9 @@
//
// Copyright 2020 DxOS.org
//
import Main from './containers/Main';
export {
Main
};

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'));

View File

@ -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"
}
}

View File

@ -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/'
}
}
]
}
]
},

View File

@ -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

View File

@ -1,5 +0,0 @@
//
// Copyright 2020 DxOS.org
//
export * from './hooks';

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'));

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
```
http://localhost:4000
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
```
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.

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'
]

View File

@ -0,0 +1,3 @@
#!/usr/bin/env node
module.exports = require('../dist/es/server/main.js');

View File

@ -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'

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"

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>

View File

@ -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'));

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}`);
});

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}`);
});

View File

@ -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>

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')
}
}
};

102
yarn.lock
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"