- install node.js and yarn
- load dependencies:
yarn install
- run dev server:
yarn run dev
- run eslint:
yarn run lint
- run tests:
yarn run test
- update autocompletion for custom components:
yarn run generate
- add npm package as dev-dependency:
yarn add -D <package name>
- upgrade dependencies:
yarn upgrade
- run build for production:
yarn run build
Add the following to your etc/hosts
172.17.0.1 inowas.local
Build typescript container in docker-inowas-api repository
docker build -t inowas/typescript typescript
Configure config.js
export default {
baseURL: 'http://inowas.local:8002'
};
Start development server:
$ docker run --rm -it -p 8080:8080 -p 3000:3000 --volume $(pwd):/app inowas/typescript yarn run dev
Init database
$ docker-compose exec php bash
$ ./build/build.on.docker.sh
$ ./build/test.on.docker.sh
$ cs inowas:es:migrate 2
$ cs inowas:es:migrate 3
Open your browser with http://inowas.local:8080.
We use a feature like module structure.
The module and feature t03
has a complete structure which looks like
t03
├── actions
│ ├── actions.js
│ ├── commands.js
│ ├── events.js
│ ├── index.js
│ ├── queries.js
│ └── routing.js
├── components
│ ├── index.js
│ ├── stressPeriodDataTable.jsx
│ ├── stressPeriodProperties.jsx
│ └── ...
├── containers
│ ├── index.js
│ ├── main.jsx
│ ├── modelEditorGeneral.jsx
│ └── ...
├── index.js
├── reducers
│ ├── BoundariesOverview.js
│ ├── index.js
│ └── model.js
├── sagas
│ ├── getModflowModelDetails.js
│ ├── index.js
│ ├── loadBoundary.js
│ └── ...
└── selectors
├── index.js
├── mapState.js
├── model.js
└── ...
Each folder contains an index.js
file which exposes the components/functions for external use. The available folders
should be actions
, components
, containers
, reducers
, sagas
and selectors
. The core
module is similar but has
components in it's root which follows the structure above.
We have a special separation here to be more like the event sourced backend. Actions (action.js) triggers only a store change. Commands
commands.js sends a request to server and triggers an event. Events (
event.js) triggers only a store change from a successful command. Queries (
queries.js) send a get/load request to server and triggers an action to set data in store, if needed. Usually it uses a saga for complex flows like
getModflowDetailsFlow. Changes or updates for the Browser location are located in
routing.js. A special case is the
callbacks.js` file which manipulates the state of the given component.
In an ideal world, the components folder contains only dump/pure/stateless components. These components are not connected to the store. To improve performance and avoid useless rendering we use recompose.
Containers are connected to the store and dispatches actions. In an ideal world, containers contains no layout and provides only props for the components. To improve performance we use reselect. Please consider also React is Slow, React is Fast.
Redux is a predictable state container for JavaScript apps. Each module like t03
has a main
reducer which is commonly used with combineReducers()
. The reducers applies state changes from actions to the Redux store.
Selectors
are functions to retrieve state from the store. They are composeable and you can compute derived data. A special file is
mapState.js
which contains the mapStateToProps
functions (which uses reselect) for containers.
Redux Saga is a library that aims to make application side effects (i.e. asynchronous things like data fetching and impure things like accessing the browser cache) easier to manage, more efficient to execute, simple to test, and better at handling failures.