chore: initial no style
This commit is contained in:
commit
24f9750e5f
35
actions.js
Normal file
35
actions.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
const {invokeHookSerial} = require('@truss/truss');
|
||||||
|
|
||||||
|
const {Responder} = require('./response.dev');
|
||||||
|
|
||||||
|
const responder = new Responder();
|
||||||
|
|
||||||
|
module.exports = () => ({
|
||||||
|
|
||||||
|
'truss/http-get': (action) => {
|
||||||
|
const {payload: {headers}} = action;
|
||||||
|
|
||||||
|
delete headers.host;
|
||||||
|
delete headers.connection;
|
||||||
|
|
||||||
|
return responder.respond(action).then((html) => {
|
||||||
|
return invokeHookSerial('truss/web-response', {
|
||||||
|
status: 200,
|
||||||
|
headers: defaultHeaders(),
|
||||||
|
html,
|
||||||
|
}, headers);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
'truss/schema': () => {
|
||||||
|
return {executors: ['truss/http-get']};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function defaultHeaders() {
|
||||||
|
return {
|
||||||
|
Date: (new Date()).toUTCString(),
|
||||||
|
Connection: 'keep-alive',
|
||||||
|
'Transfer-Encoding': 'chunked',
|
||||||
|
};
|
||||||
|
}
|
4
compose.js
Normal file
4
compose.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = (config) => {
|
||||||
|
const backendPort = process.env.PERSEA_BACKPORT || 8004;
|
||||||
|
config.ports = [`${backendPort}:8004`];
|
||||||
|
};
|
10
frontend/index.html
Normal file
10
frontend/index.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Truss</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="root"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
12
frontend/index.js
Normal file
12
frontend/index.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
|
import Root from './root';
|
||||||
|
import createRootStore from './root/store';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Root store={createRootStore()} />,
|
||||||
|
document.querySelector('.root')
|
||||||
|
);
|
25
frontend/root/app.js
Normal file
25
frontend/root/app.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
import classnames from 'classnames';
|
||||||
|
import {Route, Switch} from 'react-router';
|
||||||
|
|
||||||
|
import Welcome from './welcome';
|
||||||
|
function App() {
|
||||||
|
|
||||||
|
return <div className={classnames({
|
||||||
|
app: true,
|
||||||
|
dev: 'production' !== process.env.NODE_ENV,
|
||||||
|
})}>
|
||||||
|
<Switch>
|
||||||
|
<Route path="/" component={Welcome} />
|
||||||
|
</Switch>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
import {hot} from 'react-hot-loader';
|
||||||
|
App = hot(module)(App);
|
||||||
|
|
||||||
|
// import {styler} from '@truss/react'
|
||||||
|
// App = styler App, require './app.scss'
|
||||||
|
|
||||||
|
export default App;
|
6
frontend/root/app.scss
Normal file
6
frontend/root/app.scss
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.app {
|
||||||
|
background-color: #444444;
|
||||||
|
color: #fff;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
26
frontend/root/dev-tools.js
Normal file
26
frontend/root/dev-tools.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import {createDevTools} from 'redux-devtools';
|
||||||
|
|
||||||
|
import LogMonitor from 'redux-devtools-log-monitor';
|
||||||
|
import DockMonitor from 'redux-devtools-dock-monitor';
|
||||||
|
import FilterMonitor from 'redux-devtools-filter-actions';
|
||||||
|
|
||||||
|
const DevTools = createDevTools(
|
||||||
|
|
||||||
|
<DockMonitor
|
||||||
|
toggleVisibilityKey='ctrl-h'
|
||||||
|
changePositionKey='ctrl-q'
|
||||||
|
>
|
||||||
|
|
||||||
|
<FilterMonitor>
|
||||||
|
|
||||||
|
<LogMonitor
|
||||||
|
theme='tomorrow'
|
||||||
|
/>
|
||||||
|
|
||||||
|
</FilterMonitor>
|
||||||
|
</DockMonitor>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default DevTools;
|
25
frontend/root/index.dev.js
Normal file
25
frontend/root/index.dev.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Provider} from 'react-redux';
|
||||||
|
import {BrowserRouter} from 'react-router-dom';
|
||||||
|
|
||||||
|
import DevTools from './dev-tools';
|
||||||
|
|
||||||
|
import App from './app';
|
||||||
|
function Root ({store}) {
|
||||||
|
|
||||||
|
return <Provider store={store}>
|
||||||
|
<React.Fragment>
|
||||||
|
<BrowserRouter>
|
||||||
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
|
<div className="dev-tools">
|
||||||
|
<DevTools />
|
||||||
|
</div>
|
||||||
|
</React.Fragment>
|
||||||
|
</Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// import {styler} from '@truss/react'
|
||||||
|
// Root = styler Root, require './index.scss'
|
||||||
|
|
||||||
|
export default Root;
|
7
frontend/root/index.js
Normal file
7
frontend/root/index.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
if ('production' === process.env.NODE_ENV) {
|
||||||
|
module.exports = require('./index.prod');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
module.exports = require('./index.dev');
|
||||||
|
}
|
18
frontend/root/index.prod.js
Normal file
18
frontend/root/index.prod.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import React from 'react';
|
||||||
|
import {Provider} from 'react-redux';
|
||||||
|
import {BrowserRouter} from 'react-router-dom';
|
||||||
|
|
||||||
|
import App from './app';
|
||||||
|
function Root ({store}) {
|
||||||
|
|
||||||
|
return <Provider store={store}>
|
||||||
|
<BrowserRouter>
|
||||||
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
|
</Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// import {styler} from '@truss/react'
|
||||||
|
// Root = styler Root, require './index.scss'
|
||||||
|
|
||||||
|
export default Root;
|
9
frontend/root/index.scss
Normal file
9
frontend/root/index.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
@media (max-width: 1023px) {
|
||||||
|
.testing {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dev-tools {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
20
frontend/root/reducer.js
Normal file
20
frontend/root/reducer.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
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...
|
||||||
|
});
|
||||||
|
}
|
10
frontend/root/saga.js
Normal file
10
frontend/root/saga.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import {all, call} from 'redux-saga/effects'
|
||||||
|
|
||||||
|
function createRootSaga() {
|
||||||
|
return function*() {
|
||||||
|
return yield all([
|
||||||
|
].map(call));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createRootSaga;
|
28
frontend/root/store.dev.js
Normal file
28
frontend/root/store.dev.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import createSagaMiddleware from 'redux-saga';
|
||||||
|
import {compose, createStore, applyMiddleware} from 'redux';
|
||||||
|
|
||||||
|
import DevTools from './dev-tools';
|
||||||
|
|
||||||
|
import createRootReducer from './reducer';
|
||||||
|
import createRootSaga from './saga';
|
||||||
|
|
||||||
|
export default function createRootStore() {
|
||||||
|
|
||||||
|
const sagaMiddleware = createSagaMiddleware();
|
||||||
|
|
||||||
|
const store = createStore(
|
||||||
|
createRootReducer(),
|
||||||
|
compose(
|
||||||
|
applyMiddleware(sagaMiddleware),
|
||||||
|
DevTools.instrument()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
module.hot.accept('./reducer', () => {
|
||||||
|
store.replaceReducer(require('./reducer').default());
|
||||||
|
});
|
||||||
|
|
||||||
|
sagaMiddleware.run(createRootSaga());
|
||||||
|
|
||||||
|
return store;
|
||||||
|
}
|
7
frontend/root/store.js
Normal file
7
frontend/root/store.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
if ('production' === process.env.NODE_ENV) {
|
||||||
|
module.exports = require('./store.prod');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
module.exports = require('./store.dev');
|
||||||
|
}
|
18
frontend/root/store.prod.js
Normal file
18
frontend/root/store.prod.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import createSagaMiddleware from 'redux-saga';
|
||||||
|
import {compose, createStore, applyMiddleware} from 'redux';
|
||||||
|
|
||||||
|
import createRootReducer from './reducer';
|
||||||
|
import createRootSaga from './saga';
|
||||||
|
export default function createRootStore() {
|
||||||
|
|
||||||
|
// sagaMiddleware = createSagaMiddleware()
|
||||||
|
|
||||||
|
// store = createStore createRootReducer(), compose(
|
||||||
|
// applyMiddleware sagaMiddleware
|
||||||
|
// )
|
||||||
|
store = createStore(createRootReducer());
|
||||||
|
|
||||||
|
// sagaMiddleware.run(createRootSaga());
|
||||||
|
|
||||||
|
return store
|
||||||
|
}
|
36
frontend/root/welcome.js
Normal file
36
frontend/root/welcome.js
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// import {pkgman} from '@truss/core';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
class Welcome extends React.Component {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
return <div className="welcome">
|
||||||
|
<div className="content">
|
||||||
|
<h2>
|
||||||
|
<span>💕 </span>
|
||||||
|
Welcome back to <strong>Persea</strong>
|
||||||
|
<span> 💕</span>
|
||||||
|
</h2>
|
||||||
|
{this.thingsToDo()}
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
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'
|
||||||
|
|
||||||
|
export default Welcome;
|
27
frontend/root/welcome.scss
Normal file
27
frontend/root/welcome.scss
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
.welcome {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
display: block;
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
background-color: #333;
|
||||||
|
padding: 6em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.things-to-do div {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
15
index.js
Normal file
15
index.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import {createDispatcher} from '@truss/truss';
|
||||||
|
|
||||||
|
const dispatcher = createDispatcher();
|
||||||
|
dispatcher.lookupActions(require('./actions'));
|
||||||
|
dispatcher.lookupHooks(require('./hooks'));
|
||||||
|
dispatcher.connect();
|
||||||
|
|
||||||
|
if (module.hot) {
|
||||||
|
module.hot.accept('./actions', () => {
|
||||||
|
dispatcher.lookupActions(require('./actions'));
|
||||||
|
});
|
||||||
|
module.hot.accept('./hooks', () => {
|
||||||
|
dispatcher.lookupHooks(require('./hooks'));
|
||||||
|
});
|
||||||
|
}
|
35
package.json
Normal file
35
package.json
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"name": "persea",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "node -e '' -r '@truss/truss/task/build'",
|
||||||
|
"default": "yarn run dev",
|
||||||
|
"dev": "node -e '' -r '@truss/truss/task/scaffold'"
|
||||||
|
},
|
||||||
|
"author": "cha0s",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@truss/truss": "1.x",
|
||||||
|
"classnames": "^2.2.6",
|
||||||
|
"debug": "3.1.0",
|
||||||
|
"html-webpack-plugin": "3.2.0",
|
||||||
|
"immutable": "^3.8.2",
|
||||||
|
"react": "^16.4.2",
|
||||||
|
"react-dom": "^16.4.2",
|
||||||
|
"react-hot-loader": "^4.3.5",
|
||||||
|
"react-redux": "^5.0.7",
|
||||||
|
"react-router": "^4.3.1",
|
||||||
|
"react-router-dom": "^4.3.1",
|
||||||
|
"redux": "^4.0.0",
|
||||||
|
"redux-devtools": "^3.4.1",
|
||||||
|
"redux-devtools-dock-monitor": "^1.1.3",
|
||||||
|
"redux-devtools-filter-actions": "^1.2.2",
|
||||||
|
"redux-devtools-log-monitor": "^1.4.0",
|
||||||
|
"redux-form": "^7.4.2",
|
||||||
|
"redux-saga": "^0.16.0",
|
||||||
|
"webpack-dev-middleware": "3.1.3",
|
||||||
|
"webpack-hot-middleware": "2.22.3"
|
||||||
|
}
|
||||||
|
}
|
94
response.dev.js
Normal file
94
response.dev.js
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
const http = require('http');
|
||||||
|
|
||||||
|
const webpack = require('webpack');
|
||||||
|
const wdm = require('webpack-dev-middleware');
|
||||||
|
const whm = require('webpack-hot-middleware');
|
||||||
|
|
||||||
|
const debug = require('debug')('truss:persea');
|
||||||
|
|
||||||
|
const {webpackConfig} = require('./webpack.config');
|
||||||
|
|
||||||
|
const backendHostname = process.env.PERSEA_BACKHOST || 'persea';
|
||||||
|
const backendPort = process.env.PERSEA_BACKPORT || 8004;
|
||||||
|
const frontendHostname = process.env.PERSEA_FRONTHOST || 'localhost';
|
||||||
|
|
||||||
|
exports.Responder = class Responder {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
const httpServer = this.server = http.createServer();
|
||||||
|
|
||||||
|
httpServer.on('listening', () => {
|
||||||
|
const address = this.address = httpServer.address();
|
||||||
|
const config = webpackConfig();
|
||||||
|
|
||||||
|
config.entry.push(
|
||||||
|
`webpack-hot-middleware/client?path=http://${
|
||||||
|
frontendHostname}:${address.port
|
||||||
|
}/__webpack_hmr`
|
||||||
|
);
|
||||||
|
|
||||||
|
const compiler = webpack(config);
|
||||||
|
this.dm = wdm(compiler, {
|
||||||
|
stats: {
|
||||||
|
chunkModules: true,
|
||||||
|
colors: true,
|
||||||
|
context: process.cwd(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.hm = whm(compiler, {
|
||||||
|
path: '/__webpack_hmr',
|
||||||
|
});
|
||||||
|
|
||||||
|
debug(`HTTP listening on ${JSON.stringify(address)}...`);
|
||||||
|
});
|
||||||
|
|
||||||
|
httpServer.on('request', (req, res) => {
|
||||||
|
this.dm(req, res, (error) => {
|
||||||
|
if (error) {
|
||||||
|
return console.error(error);
|
||||||
|
}
|
||||||
|
this.hm(req, res, (error) => {
|
||||||
|
if (error) {
|
||||||
|
return console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
httpServer.on('error', console.error);
|
||||||
|
|
||||||
|
httpServer.listen(backendPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
respond({payload: {headers, url}}) {
|
||||||
|
headers = Object.assign({}, headers);
|
||||||
|
|
||||||
|
delete headers.host;
|
||||||
|
delete headers.connection;
|
||||||
|
|
||||||
|
// forward to internal HTTP
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
headers,
|
||||||
|
backendHostname,
|
||||||
|
path: url,
|
||||||
|
port: this.address.port,
|
||||||
|
};
|
||||||
|
|
||||||
|
const client = http.get(options);
|
||||||
|
client.on('response', (res) => {
|
||||||
|
let data = '';
|
||||||
|
res.setEncoding('utf8');
|
||||||
|
res.on('data', (chunk) => {
|
||||||
|
data += chunk;
|
||||||
|
});
|
||||||
|
res.on('end', () => {
|
||||||
|
resolve(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
client.on('error', reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
0
response.production.js
Normal file
0
response.production.js
Normal file
77
webpack.config.js
Normal file
77
webpack.config.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
|
||||||
|
module.exports = (config) => {
|
||||||
|
|
||||||
|
if ('production' === config.mode) {
|
||||||
|
return [config, module.exports.webpackConfig()];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const SOURCE_PATH = process.env.SOURCE_PATH || '/var/node/src';
|
||||||
|
const OUTPUT_PATH = process.env.OUTPUT_PATH || '/var/node/dist';
|
||||||
|
|
||||||
|
module.exports.webpackConfig = function() {
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
mode: 'production' !== process.env.NODE_ENV ? 'development' : 'production',
|
||||||
|
entry: [
|
||||||
|
'@babel/polyfill',
|
||||||
|
path.join(SOURCE_PATH, 'frontend', 'index.js'),
|
||||||
|
],
|
||||||
|
optimization: {},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
exclude: /(node_modules|bower_components)/,
|
||||||
|
use: {
|
||||||
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
babelrcRoots: [
|
||||||
|
OUTPUT_PATH,
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
'@babel/plugin-proposal-object-rest-spread',
|
||||||
|
],
|
||||||
|
presets: [
|
||||||
|
'@babel/preset-react',
|
||||||
|
'@babel/preset-env',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: 'index.js',
|
||||||
|
path: path.join(OUTPUT_PATH, 'frontend'),
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
title: 'Truss',
|
||||||
|
template: path.join(SOURCE_PATH, 'frontend', 'index.html'),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
modules: [path.join(OUTPUT_PATH, 'node_modules')],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ('production' === config.mode) {
|
||||||
|
config.optimization.minimizer = [
|
||||||
|
new UglifyJsPlugin({cache: false})
|
||||||
|
];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
config.plugins.push(new webpack.HotModuleReplacementPlugin());
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user