A base application for revenge web applications.
- Run
npm install
- create a
config.json
in the project root (refer to the example files)
npm start
It will start a webpack-dev-server, running at hostname/port specified in the config.json
.
A basic revenge application, with some common functionalities already in place.
revenge
provides a @queries
decorator for declaring data dependencies on components. An example of @queries
usage is shown in app/containers/AuthContainer.js
, that uses the user
query.
Queries definitions are in app/queries.js
. This webseed comes with an example query, which is the aforementioned user
query.
In app/routes.js
you'll find two main route trees under App
:
LoginRoute
AuthenticatedRoute
LoginRoute
displays a login interface, with username and password fields. When the form is submit, it invokes the doLogin
action defined in App.js
. The HTTP request is stubbed and it returns a fake token, which is stored in a cookie.
LoginRoute
automatically automatically redirects to /
whenever immediately after a successful login and/or when navigating to it with a token already present. The redirection destination can be configured using the authenticatedPath
prop.
AuthenticatedRoute
is the dual of LoginRoute
. When navigating to it without a token, it automatically redirects to /login
(again, this can be configured, using the loginRoute
prop). Also, it listens to changes of the app state and if the token is invalidated (i.e. removed), it performs the same redirection.
Several i18n facilities are provided (built on top of react-intl
).
app/Hello/Hello.js
shows an example of using the intlMethods
decorator to access the i18n facilities.
The greeting displayed to the user is translated using this.formatMessage
(injected by the decorator).
const greeting = this.formatMessage('Hello.hello');
This looks for the Hello.hello
translation key for the current locale, whose definition file is placed in app/locales/{localeName}.json
. For instance, en.json
contains:
{
"locales": ["en"],
"messages": {
"Hello": {
"hello": "hello"
}
}
}
so greeting
will evaluate to "Hello"
.
In order to keep the bundle size as small as possible, locale files are dynamically requested according to the user's preferred language (this uses the webpack bundle splitting feature).
Same goes for the Intl.js
polyfill required by some browsers (e.g. Safari): it is provided as a separate bundle and requested only if needed.
Basic components are building blocks for all the application's components. They are highly reusable components, and they are often customization over third parties components.
This webseed comes with a dependency on buildo/react-components
and some of them are cherry-picked in app/components/Basic/index.js
.
An example of customization over a third-party component is app/components/Basic/LoadingSpinner/LoadingSpinner.js
.
A domain model is a system of abstractions that describes selected aspects of a sphere of knowledge, influence, or activity (a domain).
-- https://en.wikipedia.org/wiki/Domain_model
A domain model represents the abstractions we want to work with. In a revenge app, they're modeled using tcomb
.
tcomb
allows for both definition and runtime validation of the domain objects. Whenever an object does not conform to its definition, tcomb
will raise a warning (only in development).
This is especially useful when interacting with a REST API that may change over time. Any change or error in the API spec will be caught early on by the tcomb
validation, allowing for a fast debugging experience.
Each domain object is defined in /app/domain
. This webseed ships with an example definition for the User
domain object (app/domain/User.js
).