flow: lots
This commit is contained in:
parent
2deb7fc289
commit
b32f879ccb
22
actions.js
22
actions.js
|
@ -2,7 +2,8 @@ const {invokeHookSerial} = require('@truss/truss');
|
|||
|
||||
const {Responder} = require('./response.dev');
|
||||
|
||||
const responder = new Responder();
|
||||
let responder = new Responder();
|
||||
responder.start();
|
||||
|
||||
module.exports = () => ({
|
||||
|
||||
|
@ -12,10 +13,10 @@ module.exports = () => ({
|
|||
delete headers.host;
|
||||
delete headers.connection;
|
||||
|
||||
return responder.respond(action).then((html) => {
|
||||
return responder.respond(action).then(({html, headers: resHeaders}) => {
|
||||
return invokeHookSerial('truss/web-response', {
|
||||
status: 200,
|
||||
headers: defaultHeaders(),
|
||||
headers: {...defaultResponseHeaders(), ...resHeaders},
|
||||
html,
|
||||
}, headers);
|
||||
});
|
||||
|
@ -26,10 +27,17 @@ module.exports = () => ({
|
|||
},
|
||||
});
|
||||
|
||||
function defaultHeaders() {
|
||||
function defaultResponseHeaders() {
|
||||
return {
|
||||
Date: (new Date()).toUTCString(),
|
||||
Connection: 'keep-alive',
|
||||
'Transfer-Encoding': 'chunked',
|
||||
date: (new Date()).toUTCString(),
|
||||
connection: 'keep-alive',
|
||||
};
|
||||
}
|
||||
|
||||
if (module.hot) {
|
||||
module.hot.accept('./response.dev', () => {
|
||||
responder.stop();
|
||||
responder = new require('./response.dev').Responder();
|
||||
responder.start();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import * as React from 'react';
|
||||
import React from 'react';
|
||||
|
||||
import classnames from 'classnames';
|
||||
import {Route, Switch} from 'react-router';
|
||||
|
@ -16,10 +16,10 @@ function App() {
|
|||
</div>;
|
||||
}
|
||||
|
||||
import contempo from 'contempo';
|
||||
App = contempo(App, require('./index.scss'));
|
||||
|
||||
import {hot} from 'react-hot-loader';
|
||||
App = hot(module)(App);
|
||||
|
||||
// import {styler} from '@truss/react'
|
||||
// App = styler App, require './app.scss'
|
||||
|
||||
export default App;
|
|
@ -1,10 +1,8 @@
|
|||
// import {pkgman} from '@truss/core';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
class Welcome extends React.Component {
|
||||
|
||||
render() {
|
||||
|
||||
return <div className="welcome">
|
||||
<div className="content">
|
||||
<h2>
|
||||
|
@ -18,19 +16,13 @@ class Welcome extends React.Component {
|
|||
}
|
||||
|
||||
thingsToDo() {
|
||||
|
||||
// things = for key, value of pkgman.invoke 'perseaThingsToDo'
|
||||
// <div className={key} key={key}>{value}</div>
|
||||
|
||||
// if things.length is 0
|
||||
const things = <p>You have nothing to do!</p>;
|
||||
|
||||
return <div className="things-to-do">{things}</div>;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// import {styler} from '@truss/react'
|
||||
// Welcome = styler Welcome, require './welcome.scss'
|
||||
import contempo from 'contempo';
|
||||
Welcome = contempo(Welcome, require('./welcome.scss'));
|
||||
|
||||
export default Welcome;
|
|
@ -2,7 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Truss</title>
|
||||
<title>Persea</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="root"></div>
|
||||
|
|
|
@ -4,7 +4,8 @@ import {BrowserRouter} from 'react-router-dom';
|
|||
|
||||
import DevTools from './dev-tools';
|
||||
|
||||
import App from './app';
|
||||
import App from '../app';
|
||||
|
||||
function Root ({store}) {
|
||||
|
||||
return <Provider store={store}>
|
||||
|
@ -19,7 +20,7 @@ function Root ({store}) {
|
|||
</Provider>;
|
||||
};
|
||||
|
||||
// import {styler} from '@truss/react'
|
||||
// Root = styler Root, require './index.scss'
|
||||
import contempo from 'contempo';
|
||||
Root = contempo(Root, require('./index.scss'));
|
||||
|
||||
export default Root;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
if ('production' === process.env.NODE_ENV) {
|
||||
module.exports = require('./index.prod');
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import {Provider} from 'react-redux';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
|
||||
import App from './app';
|
||||
import App from '../app';
|
||||
|
||||
function Root ({store}) {
|
||||
|
||||
return <Provider store={store}>
|
||||
|
@ -12,7 +13,7 @@ function Root ({store}) {
|
|||
</Provider>;
|
||||
};
|
||||
|
||||
// import {styler} from '@truss/react'
|
||||
// Root = styler Root, require './index.scss'
|
||||
import contempo from 'contempo';
|
||||
Root = contempo(Root, require('./index.scss'));
|
||||
|
||||
export default Root;
|
||||
|
|
|
@ -1,20 +1,9 @@
|
|||
import {combineReducers} from 'redux';
|
||||
import {reducer as formReducer} from 'redux-form/immutable';
|
||||
|
||||
// import {pkgman} from '@truss/core';
|
||||
|
||||
// import {createReducer as createResourceReducer} from '../resource'
|
||||
|
||||
export default function createRootReducer() {
|
||||
|
||||
// dynamicReducers = pkgman.invokeFlat('perseaReducers').reduce(
|
||||
// ((reducers, map) -> {reducers..., map...}), {}
|
||||
// )
|
||||
|
||||
return combineReducers({
|
||||
form: formReducer,
|
||||
// resource: createResourceReducer()
|
||||
|
||||
// dynamicReducers...
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import {all, call} from 'redux-saga/effects'
|
||||
|
||||
function createRootSaga() {
|
||||
export default function createRootSaga() {
|
||||
return function*() {
|
||||
return yield all([
|
||||
].map(call));
|
||||
};
|
||||
}
|
||||
|
||||
export default createRootSaga;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
if ('production' === process.env.NODE_ENV) {
|
||||
module.exports = require('./store.prod');
|
||||
}
|
||||
|
|
|
@ -3,16 +3,19 @@ import {compose, createStore, applyMiddleware} from 'redux';
|
|||
|
||||
import createRootReducer from './reducer';
|
||||
import createRootSaga from './saga';
|
||||
|
||||
export default function createRootStore() {
|
||||
|
||||
// sagaMiddleware = createSagaMiddleware()
|
||||
const sagaMiddleware = createSagaMiddleware()
|
||||
|
||||
// store = createStore createRootReducer(), compose(
|
||||
// applyMiddleware sagaMiddleware
|
||||
// )
|
||||
store = createStore(createRootReducer());
|
||||
const store = createStore(
|
||||
createRootReducer(),
|
||||
compose(
|
||||
applyMiddleware(sagaMiddleware)
|
||||
)
|
||||
);
|
||||
|
||||
// sagaMiddleware.run(createRootSaga());
|
||||
sagaMiddleware.run(createRootSaga());
|
||||
|
||||
return store
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
"dependencies": {
|
||||
"@truss/truss": "1.x",
|
||||
"classnames": "^2.2.6",
|
||||
"contempo": "1.x",
|
||||
"debug": "3.1.0",
|
||||
"html-webpack-plugin": "3.2.0",
|
||||
"immutable": "^3.8.2",
|
||||
|
|
|
@ -22,14 +22,19 @@ exports.Responder = class Responder {
|
|||
const address = this.address = httpServer.address();
|
||||
const config = webpackConfig();
|
||||
|
||||
config.entry.push(
|
||||
`webpack-hot-middleware/client?path=http://${
|
||||
for (const i in config.entry) {
|
||||
config.entry[i].unshift(`webpack-hot-middleware/client?path=http://${
|
||||
frontendHostname}:${address.port
|
||||
}/__webpack_hmr`
|
||||
);
|
||||
}/__webpack_hmr`);
|
||||
}
|
||||
|
||||
const compiler = webpack(config);
|
||||
this.dm = wdm(compiler, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
|
||||
},
|
||||
stats: {
|
||||
chunkModules: true,
|
||||
colors: true,
|
||||
|
@ -58,11 +63,15 @@ exports.Responder = class Responder {
|
|||
|
||||
httpServer.on('error', console.error);
|
||||
|
||||
httpServer.listen(backendPort);
|
||||
httpServer.on('close', () => httpServer.removeAllListeners());
|
||||
}
|
||||
|
||||
start() {
|
||||
this.server.listen(backendPort);
|
||||
}
|
||||
|
||||
respond({payload: {headers, url}}) {
|
||||
headers = Object.assign({}, headers);
|
||||
headers = {...headers};
|
||||
|
||||
delete headers.host;
|
||||
delete headers.connection;
|
||||
|
@ -85,10 +94,17 @@ exports.Responder = class Responder {
|
|||
data += chunk;
|
||||
});
|
||||
res.on('end', () => {
|
||||
resolve(data);
|
||||
resolve({
|
||||
html: data,
|
||||
headers: res.headers
|
||||
});
|
||||
});
|
||||
});
|
||||
client.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.server.close();
|
||||
}
|
||||
}
|
||||
|
|
94
styles/forms.scss
Normal file
94
styles/forms.scss
Normal file
|
@ -0,0 +1,94 @@
|
|||
@import './mixins.scss';
|
||||
|
||||
button, input, select {
|
||||
background-color: #333;
|
||||
color: #CCC;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 1px solid #333;
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
border: none;
|
||||
border-bottom: 1px solid #333;
|
||||
margin: 0.25em 0;
|
||||
display: block;
|
||||
font-size: 0.8em;
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
input {
|
||||
border: 1px solid #333;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.aside {
|
||||
padding: 0.2em;
|
||||
}
|
||||
|
||||
select {
|
||||
height: 1.5em;
|
||||
line-height: 0;
|
||||
text-align-last: right;
|
||||
}
|
||||
|
||||
button, select, input {
|
||||
border: 1px solid #333;
|
||||
}
|
||||
|
||||
form {
|
||||
margin-top: 2em;
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.form-row {
|
||||
@include group;
|
||||
margin-bottom: 1em;
|
||||
|
||||
> .control {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
.control {
|
||||
@include group;
|
||||
|
||||
margin-left: 0.75em;
|
||||
margin-right: 0.75em;
|
||||
text-align: right;
|
||||
|
||||
label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.truss-number {
|
||||
|
||||
button {
|
||||
background-color: #333;
|
||||
|
||||
&:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
55
styles/global.scss
Normal file
55
styles/global.scss
Normal file
|
@ -0,0 +1,55 @@
|
|||
html, body, .app, .root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.aside {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
button {
|
||||
&:hover {
|
||||
background-color: #555;
|
||||
}
|
||||
}
|
||||
|
||||
button, input, select, option {
|
||||
|
||||
&[disabled] {
|
||||
filter: grayscale(1);
|
||||
opacity: 0.5;
|
||||
|
||||
&:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
box-shadow: inset 0 0 1pt 0.5pt #CCC, 0 0 1pt 0.5pt #CCC
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid #333;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.loading {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
svg {
|
||||
height: 25%;
|
||||
width: 25%;
|
||||
}
|
||||
}
|
||||
|
||||
.editor.avocado-environment {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
8
styles/mixins.scss
Normal file
8
styles/mixins.scss
Normal file
|
@ -0,0 +1,8 @@
|
|||
@mixin group {
|
||||
&:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
60
styles/reset.css
Normal file
60
styles/reset.css
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
box-sizing: border-box;
|
||||
color: #CCCCCC;
|
||||
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
ins {
|
||||
text-decoration: none;
|
||||
}
|
||||
select {
|
||||
font-size: inherit;
|
||||
}
|
||||
button {
|
||||
line-height: 0;
|
||||
}
|
|
@ -17,20 +17,37 @@ module.exports = (config) => {
|
|||
const SOURCE_PATH = process.env.SOURCE_PATH || '/var/node/src';
|
||||
const OUTPUT_PATH = process.env.OUTPUT_PATH || '/var/node/dist';
|
||||
|
||||
const hashFormat = {
|
||||
chunk: ('production' === process.env.NODE_ENV) ? '.[chunkhash:20]' : '',
|
||||
}
|
||||
|
||||
module.exports.webpackConfig = function() {
|
||||
|
||||
const styleDirectory = path.join(SOURCE_PATH, 'styles');
|
||||
const cssPrefix = '!style-loader!css-loader!';
|
||||
const scssPrefix = `${cssPrefix}sass-loader!`;
|
||||
|
||||
const config = {
|
||||
mode: 'production' !== process.env.NODE_ENV ? 'development' : 'production',
|
||||
entry: [
|
||||
'@babel/polyfill',
|
||||
path.join(SOURCE_PATH, 'frontend', 'index.js'),
|
||||
],
|
||||
entry: {
|
||||
index: [
|
||||
'@babel/polyfill',
|
||||
path.join(SOURCE_PATH, 'frontend', 'index.js'),
|
||||
],
|
||||
style: [
|
||||
path.join(cssPrefix, styleDirectory, 'reset.css'),
|
||||
path.join(scssPrefix, styleDirectory, 'global.scss'),
|
||||
path.join(scssPrefix, styleDirectory, 'forms.scss'),
|
||||
],
|
||||
},
|
||||
optimization: {},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /(node_modules|bower_components)/,
|
||||
exclude: [
|
||||
/(node_modules\/(?!contempo))/,
|
||||
],
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
|
@ -39,6 +56,7 @@ module.exports.webpackConfig = function() {
|
|||
],
|
||||
plugins: [
|
||||
'@babel/plugin-proposal-object-rest-spread',
|
||||
'react-hot-loader/babel',
|
||||
],
|
||||
presets: [
|
||||
'@babel/preset-react',
|
||||
|
@ -47,10 +65,31 @@ module.exports.webpackConfig = function() {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [{
|
||||
loader: 'raw-loader',
|
||||
}],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [{
|
||||
loader: 'raw-loader',
|
||||
}, {
|
||||
loader: 'sass-loader',
|
||||
options: {
|
||||
sourceMap: 'production' !== process.env.NODE_ENV,
|
||||
},
|
||||
}],
|
||||
},
|
||||
],
|
||||
},
|
||||
node: {
|
||||
fs: 'empty',
|
||||
},
|
||||
output: {
|
||||
filename: 'index.js',
|
||||
filename: `[name]${hashFormat.chunk}.js`,
|
||||
chunkFilename: `[id]${hashFormat.chunk}.chunk.js`,
|
||||
path: path.join(OUTPUT_PATH, 'frontend'),
|
||||
},
|
||||
plugins: [
|
||||
|
@ -61,7 +100,10 @@ module.exports.webpackConfig = function() {
|
|||
],
|
||||
resolve: {
|
||||
modules: [path.join(OUTPUT_PATH, 'node_modules')],
|
||||
}
|
||||
},
|
||||
resolveLoader: {
|
||||
modules: [path.join(OUTPUT_PATH, 'node_modules')],
|
||||
},
|
||||
};
|
||||
|
||||
if ('production' === config.mode) {
|
||||
|
@ -70,6 +112,7 @@ module.exports.webpackConfig = function() {
|
|||
];
|
||||
}
|
||||
else {
|
||||
config.devtool = 'eval-source-map';
|
||||
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user