We built the house, so you can party on the terrace.
A create-react-app based frontend starter project, using react-scripts 3.0+.
You can get started right-away with testing, files generation, http calls, state-management (with store immutability checks via a plugin), internationalization, etc. handled for you right from the start.
Dev Note: Don't attempt to
react-scripts startinside terrace itself. See development instructions for more.
yarn global add terrace.js
terrace create project-name -gei
# ^ this takes care of project generation, packages installation, and directory change.
yarn startYarn is an important pre-requisite.
- Webpack 4 (for build)
- Watchman (for testing)
- Yarn (no, you can't use npm commands as an alternative, not yet)
# from anywhere inside your project directory
terrace --help
terrace [command] --helpBuilt on Environment:
MacOS 10.13.3 (17D47)
Node 8.11.2 (LTS)
NPM 5.6.0
Yarn 1.7.0
Git 2.18.0
# Required utilities:
brew install watchman # https://github.com/facebook/create-react-app/issues/3006
yarn install
yarn start
# in another terminal but same directory
yarn link
# ensure you don't have terrace installed already before this
# now you have the terrace binary available to use globally
# you can go ahead and use terrace commands to run and test that the changes work as intendedyarn preupdate
yarn publish [--major|--minor|--patch]
Note:
NODE_PATH=srcis in effect. Use that to specify import paths in any JS files.
Note:
SASS=src:node_modulesis in effect. Use that to specify import paths in any SCSS files.
Note: In
WebStorm, mark./srcas Resources Root. (Rt. click > Mark directory as > Resources root)
Note: A
pre-commithook (unless--without-githooksis specified) runs before every commit to ensure that any specified linters work as intended. Any hooks are defined in .githooks.
If githooks don't work, you can initialize them manually using the following commands (provided the project wasn't created with--without-githooks)
chmod +x .githooks/*
git config core.hooksPath .githooksLibrary imports
Util imports
Icon imports
Component imports
import './styles.css';
constant declarations
Component declaration and named export
Default component export
Component related functions
If you know how redux-saga is used, skim over this section.
- Actions are defined in respective
src/viewsfiles. - Tasks (the actual functions) are defined in respective
src/viewsfiles. - Sagas (the things that trigger tasks) are defined in
src/sagas.js.
Now, how it works:
Actionsaredispatched from other places.Sagaslisten foractions, and firetasks.Tasksfire the API calls, anddispatchsomeactionsthroughredux-saga.- Those
actionslet us pass data into thereduxstore. - Components
connected to thereduxstore listen on updated to the store. - Any relevant UI changes are made.
- HTTP actions are defined in
src/utils/http.js. - We use
axios. - All API calls are defined in
src/apis.js. - Parametrized URLs/routes can be processed with
parametrizePathinsrc/utils/transition.js. - All outgoing payloads are sent through the
normalizerdefined insrc/adapters/application.js. - Add incoming payloads are received through the
serializerdefined insrc/adapters/application.js. - If custom handling for a resource is required, add a resource type to the
schemadefined insrc/adapters/application.js. - Read http://jsonapi.org/ for an idea about how to construct and establish resources and relationships.
- Authentication is cookie based.
Note: Use status code constants from package
http-status-codesto handle request errors.
Note: Add logic to
handleFailedResponsesfromutils/error-handlersto handle weird API error cases. You would however, need to plug it into the HTTP call methods yourself. It's not being used yet.
- All routes (with parameters, or otherwise) are defined in
src/routes.js. - We use
react-routerv4. The usage is as indicated by the documentation. - Any usages of link tags to parametrized routes must be processed through the
parametrizeRoutefunction insrc/utils/transition.js(docs at source).
To locally store and fetch request payloads, use { cache, load } from utils/request-cache.
There is a very thin wrapper on top of sessionStorage to make this happen.
This needs improvements.
import { cache, load } from 'utils/request-cache';;
You can do stuff like:
import { cache, load } from 'utils/request-cache';
import { get } from 'utils/http';
import API from 'apis';
async function getResource() {
let response = load(API.DUMMY) || await get(API.DUMMY);
cache(API.DUMMY, response);
}Ideally, there should be a schema defined for each different type of request.
New schemas should be added to const SCHEMA in adapters/application.js.
Normalizers and Serializers for those should be added to switch-case entry in the same file, and functions for them defined somewhere in the format described in serialize_GENERIC and normalize_GENERIC in the same file.
They are automatically handled in the http util by axios.
Note: Use
getRawfromutils/httponly for requests where you need low-level request API access. Not for general purpose HTTP resource request.
However, for them to be automatically handled in the first place, you need to specify the SCHEMA a request will follow, in the get, post, ... calls in this manner:
import { SCHEMA } from 'adapters/application';
import { get } from 'utils/http';
import API from 'apis';
async function getResource() {
let resource = await get(API.DUMMY, { /* options */ }, SCHEMA.GENERIC);
// ...
}- Project runs on Typescript strict mode.
- Project Directory Structure is opinionated.
- Internationalization is enabled, and optional.
- Initial testing setup has been prepared, and some unit and integration tests added.
- File generators for components and views have been added.
- Make this an installable project from npm.
- Make this project configurable during installation. (partly done)
- Move generators to terrace cli.
- Make terrace projects upgradable using the terrace cli.
- Compatible with Windows.
- Test that it works on Linux Distros.
- When a view is created in
--without-reducermode, ensure that reducer and actions imports in the view file are removed. - Add some template parsing logic to the generator system.
- Implement checking of whether the bin has been built or not by storing the last built hash in the
.terrace-clifile. - Support React Hooks based views and components.
- Implement functionality to support working with SSR. It currently does not work with SSR.
