Skip to content

Commit ebc5ac7

Browse files
authored
feat: Remove all onEnter preload on server side, using client side fetch (#473)
* Refactor server architecture * Separate store files * Fix move all component data reset to componentWillUnmount * Add user server provider * Refactor cluster detail, add VM based and Helm components * [wip] feat: VM based cluster support addNodes, resizeCluster, deleteNodes * Fix Helm type cluster detail * Fix cluster detail store
1 parent 7e1ff11 commit ebc5ac7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+2783
-2470
lines changed

lib/log.js

Lines changed: 0 additions & 3 deletions
This file was deleted.

lib/request.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import agent from 'superagent';
22
import _ from 'lodash';
33

4+
const debug = require('debug')('app');
5+
46
const agentOptions = {
57
header: {
68
Accept: 'application/json',
79
'Content-Type': 'application/json'
810
},
911
timeout: {
10-
response: 10000,
11-
deadline: 15000
12+
response: 20000,
13+
deadline: 30000
1214
}
1315
};
1416

@@ -60,14 +62,10 @@ class HttpAgent {
6062
.set(headers)
6163
[method === 'get' ? 'query' : 'send'](params);
6264

63-
let resp = (res && res.body) || {};
64-
65-
if (resp.success && resp.redirect) {
66-
location.href = resp.redirect;
67-
}
68-
69-
return resp;
65+
return !_.isEmpty(res) && res.body ? res.body : {};
7066
} catch (err) {
67+
debug(`res err: %O`, err.message);
68+
7169
if (err.timeout) {
7270
return {
7371
err: `Response timeout of ${agentOptions.timeout.response}ms exceeded`,

lib/utils.js

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ const yaml = require('js-yaml');
33
const appRoot = require('app-root-path');
44
const chokidar = require('chokidar');
55
const deepmerge = require('deepmerge');
6-
const log = require('./log');
6+
7+
const debug = require('debug')('app');
78

89
// when node_modules is linked, app-root-path will fail to detect root dir
910
const appRootDir = (function() {
@@ -56,26 +57,45 @@ const getServerConfig = (key = '') => {
5657
return key ? serverConfig[key] : serverConfig;
5758
};
5859

59-
const cleanServerConfig = () => {
60+
const cleanConfig = () => {
6061
serverConfig = {};
6162
};
6263

63-
const watchServerConfig = () => {
64+
const watchConfig = () => {
6465
const watcher = chokidar.watch([root('server/config.yml'), root('server/local_config.yml')], {
6566
ignored: /(^|[/\\])\../
6667
});
6768

68-
log('watching config files..');
6969
watcher.on('all', (event, path) => {
70-
log(`${event}: ${path}`);
71-
cleanServerConfig();
70+
debug(`${event}: ${path}`);
71+
cleanConfig();
7272
});
7373
};
7474

75+
const watchServer = shouldWatch => {
76+
if (shouldWatch) {
77+
// watch server w/ lib change
78+
const watcher = chokidar.watch([root('server'), root('lib')]);
79+
80+
watcher.on('ready', () => {
81+
watcher.on('all', () => {
82+
debug('Clearing */server/*, */lib/* module cache from server');
83+
84+
Object.keys(require.cache).forEach(function(id) {
85+
if (/dashboard[\/\\](server|lib)[\/\\]/.test(id)) {
86+
debug(`remove cache of %s`, id);
87+
delete require.cache[id];
88+
}
89+
});
90+
});
91+
});
92+
}
93+
};
94+
7595
module.exports = {
7696
root,
7797
loadYaml,
7898
getServerConfig,
79-
cleanServerConfig,
80-
watchServerConfig
99+
watchConfig,
100+
watchServer
81101
};

package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,12 @@
4646
},
4747
"scripts": {
4848
"dev:client": "rimraf build && NODE_ENV=development webpack --config webpack.dev.js --progress",
49-
"server": "DEBUG=op-dash BABEL_ENV=server NODE_ENV=development node server/server.js",
49+
"pack:server": "webpack --config webpack.server.js --progress",
50+
"server": "DEBUG_DEPTH=5 DEBUG=app BABEL_ENV=server NODE_ENV=development nodemon -w lib -w server server/server.js",
5051
"dev:watch": "npm run dev:client -- --watch",
5152
"dev": "rimraf build && npm run dev:client && npm run server",
5253
"prod:build": "rimraf dist && NODE_ENV=production webpack -p --config webpack.prod.js",
53-
"prod:serve": "NODE_ENV=production DEBUG=op-dash node dist/server.js",
54+
"prod:serve": "NODE_ENV=production DEBUG=app node dist/server.js",
5455
"prod": "npm run prod:build && npm run prod:serve",
5556
"lint": "eslint . --fix",
5657
"test:single": "NODE_ENV=testing jest --config jest.config.json -u",
@@ -79,7 +80,7 @@
7980
"babel-jest": "^22.0.6",
8081
"babel-loader": "7.1.1",
8182
"babel-plugin-css-modules-transform": "^1.5.0",
82-
"babel-plugin-lodash": "^3.3.2",
83+
"babel-plugin-lodash": "^3.3.4",
8384
"babel-plugin-module-resolver": "^3.0.0",
8485
"babel-plugin-transform-decorators-legacy": "^1.3.4",
8586
"babel-plugin-transform-react-remove-prop-types": "^0.4.5",
@@ -109,6 +110,7 @@
109110
"koa-webpack": "^2.0.3",
110111
"lint-staged": "^7.0.4",
111112
"node-sass": "^4.5.3",
113+
"nodemon": "^1.18.4",
112114
"object-assign": "4.1.1",
113115
"postcss-flexbugs-fixes": "3.2.0",
114116
"postcss-loader": "2.0.6",

server/middleware/auth.js

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
const debug = require('debug')('op-dash');
1+
const debug = require('debug')('app');
22

33
const authPages = ['dashboard', 'runtimes', 'purchased', 'profile', 'ssh_keys', 'store'];
44

55
module.exports = async (ctx, next) => {
6+
const { cookies } = ctx;
7+
68
// filter non-asset types
79
if (ctx.url.endsWith('.map')) {
810
return;
@@ -13,12 +15,7 @@ module.exports = async (ctx, next) => {
1315
const page = (ctx.params.page || '').split('/')[0];
1416
const needAuth = authPages.indexOf(page) > -1;
1517

16-
const brokenCookie = () => {
17-
let cookies = ctx.cookies;
18-
return !(cookies.get('user') && cookies.get('access_token'));
19-
};
20-
21-
if (needAuth && brokenCookie()) {
18+
if (needAuth && !(cookies.get('user') && cookies.get('access_token'))) {
2219
// not login
2320
ctx.redirect('/login?url=' + ctx.params.page);
2421
}

server/middleware/gzip.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const debug = require('debug')('op-dash');
1+
const debug = require('debug')('app');
22

33
module.exports = async (ctx, next) => {
44
if (ctx.url.endsWith('.js') || ctx.url.endsWith('.css')) {

server/middleware/render.js

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,21 @@
1-
// if (process.env.COMPILE_CLIENT) {
2-
// process.env.BABEL_ENV = 'server';
3-
// }
4-
5-
const React = require('react');
6-
const { renderToString } = require('react-dom/server');
7-
const { StaticRouter } = require('react-router-dom');
8-
const { matchRoutes, renderRoutes } = require('react-router-config');
9-
const { Provider } = require('mobx-react');
101
const get = require('lodash/get');
112

123
const renderPage = require('../render-page');
134

14-
const App = require('src/App').default;
15-
const routes = require('src/routes').default;
16-
17-
const isProd = process.env.NODE_ENV === 'production';
18-
19-
const i18n = require('../i18n');
20-
const { I18nextProvider } = require('react-i18next');
21-
225
module.exports = async (ctx, next) => {
23-
const branches = matchRoutes(routes, ctx.url);
24-
25-
// fix ssr notifications store not sync
26-
ctx.store.notifications = [];
27-
28-
const promises = branches.map(
29-
({ route, match }) =>
30-
route.component.onEnter
31-
? route.component.onEnter(ctx.store, match.params)
32-
: Promise.resolve(null)
33-
);
34-
35-
await Promise.all(promises);
36-
376
const context = {};
387

39-
try {
40-
// const components = isProd
41-
// ? renderToString(
42-
// <I18nextProvider i18n={i18n}>
43-
// <Provider rootStore={ctx.store} sock={null}>
44-
// <StaticRouter location={ctx.url} context={context}>
45-
// <App>{renderRoutes(routes)}</App>
46-
// </StaticRouter>
47-
// </Provider>
48-
// </I18nextProvider>
49-
// )
50-
// : null;
51-
52-
// disable ssr
53-
const components = null;
54-
55-
56-
if (context.url) {
57-
ctx.redirect(context.url);
58-
ctx.body = '<!DOCTYPE html>redirecting';
59-
return await next();
60-
}
8+
if (context.url) {
9+
ctx.redirect(context.url);
10+
ctx.body = '<!DOCTYPE html>redirecting';
11+
return await next();
12+
}
6113

14+
try {
6215
ctx.body = renderPage({
63-
isProd,
16+
isProd: process.env.NODE_ENV === 'production',
6417
title: get(ctx.store, 'config.app.title'),
65-
children: components,
18+
children: null,
6619
state: JSON.stringify(ctx.store)
6720
});
6821
} catch (err) {

server/middleware/store.js

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,40 @@
11
const url = require('url');
2-
const { useStaticRendering } = require('mobx-react');
3-
const { getServerConfig } = require('lib/utils');
4-
const RootStore = require('stores/RootStore').default;
52

6-
useStaticRendering(true);
7-
8-
const rootStore = new RootStore();
9-
rootStore.registerStores();
3+
// initial state for client app store
4+
const store = {};
105

116
/**
127
* Middleware for creating the store
138
* @param ctx
149
* @param next
1510
*/
1611
module.exports = async (ctx, next) => {
17-
try {
18-
const config = getServerConfig();
19-
20-
// Create state for SSR
21-
ctx.store = rootStore;
22-
23-
ctx.store.config = config;
24-
25-
// attach api server to ctx
26-
let serverUrl = process.env.serverUrl || config.serverUrl;
12+
// local config for server
13+
const { config } = ctx.app;
2714

28-
let apiVer = process.env.apiVersion || config.apiVersion || 'v1';
15+
let serverUrl = process.env.serverUrl || config.serverUrl;
2916

30-
// attach socket server
31-
let socketUrl = process.env.socketUrl || config.socketUrl;
17+
let apiVer = process.env.apiVersion || config.apiVersion || 'v1';
3218

33-
if (!serverUrl.startsWith('http')) {
34-
serverUrl = 'http://' + serverUrl;
35-
}
19+
let socketUrl = process.env.socketUrl || config.socketUrl;
3620

37-
if (!socketUrl.startsWith('ws://')) {
38-
socketUrl = 'ws://' + socketUrl;
39-
}
40-
41-
const clientId = process.env.clientId || config.clientId;
42-
const clientSecret = process.env.clientSecret || config.clientSecret;
43-
// url.resolve need first string starts with http
44-
ctx.store.apiServer = url.resolve(serverUrl, apiVer);
45-
ctx.store.socketUrl = socketUrl;
46-
ctx.store.clientId = clientId;
47-
ctx.store.clientSecret = clientSecret;
21+
if (!serverUrl.startsWith('http')) {
22+
serverUrl = 'http://' + serverUrl;
23+
}
24+
if (!socketUrl.startsWith('ws://')) {
25+
socketUrl = 'ws://' + socketUrl;
26+
}
4827

49-
// attach login user info to store
50-
const user = decodeURIComponent(ctx.cookies.get('user') || '{}');
51-
const role = decodeURIComponent(ctx.cookies.get('role') || '');
52-
try{
53-
ctx.store.user = JSON.parse(user);
54-
}catch(err){}
28+
// url.resolve need first string starts with http
29+
Object.assign(store, {
30+
config,
31+
socketUrl,
32+
apiServer: url.resolve(serverUrl, apiVer),
33+
clientId: process.env.clientId || config.clientId,
34+
clientSecret: process.env.clientSecret || config.clientSecret
35+
});
5536

56-
if (role === 'user') {
57-
ctx.store.user.isDev = false;
58-
ctx.store.user.isNormal = true;
59-
}
37+
ctx.store = store;
6038

61-
await next();
62-
} catch (err) {
63-
ctx.app.reportErr(err, ctx);
64-
}
39+
await next();
6540
};

server/models/roles.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

server/models/users.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)