b59298ec0e
* accept hot module changes, move routes into root component * Fix "You cannot change <Router routes>; it will be ignored" error message by implementing solution in Github: https://github.com/ReactTraining/react-router/issues/2704#issuecomment-211352123 Router is only instantiated once in a production setting (e.g. not webpack-dev-server), so there is minimal overhead on producing a random key value for `Router`. |
||
---|---|---|
common | ||
flow-typed | ||
jest_config | ||
spec | ||
static | ||
webpack_config | ||
.babelrc | ||
.editorconfig | ||
.eslintrc.json | ||
.flowconfig | ||
.gitignore | ||
.nvmrc | ||
.travis.yml | ||
Dockerfile | ||
LICENSE | ||
README.md | ||
docker-compose.yml | ||
package-lock.json | ||
package.json |
README.md
MyEtherWallet V4+ (ALPHA - VISIT V3 for the production site)
Run:
npm run dev # run app in dev mode
Build:
npm run build # build app
It generates app in dist
folder.
Test:
npm run test # run tests with Jest
Derivation Check:
The derivation checker utility assumes that you have:
- Docker installed/available
- dternyak/eth-priv-to-addr pulled from DockerHub
Docker setup instructions:
- Install docker (on macOS, I suggest Docker for Mac)
docker pull dternyak/eth-priv-to-addr
Run Derivation Checker
npm run derivation-checker
Folder structure:
│
├── common - Your App
│ ├── actions - application actions
│ ├── api - Services and XHR utils(also custom form validation, see InputComponent from components/common)
│ ├── components - components according to "Redux philosophy"
│ ├── config - frontend config depending on REACT_WEBPACK_ENV
│ ├── containers - containers according to "Redux philosophy"
│ ├── reducers - application reducers
│ ├── routing - application routing
│ ├── index.jsx - entry
│ ├── index.html
├── static
├── webpack_config - Webpack configuration
├── jest_config - Jest configuration
Docker setup
You should already have docker and docker-compose setup for your platform as a pre-req.
docker-compose up
Style Guides and Philosophies
The following are guides for developers to follow for writing compliant code.
Redux and Actions
Each reducer has one file in reducers/[namespace].js
that contains the reducer
and initial state, one file in actions/[namespace].js
that contains the action
creators and their return types, and optionally one file in
sagas/[namespace].js
that handles action side effects using
redux-saga
.
The files should be laid out as follows:
Reducer
- State should be explicitly defined and exported
- Initial state should match state flow typing, define every key
- Reducer function should handle all cases for actions. If state does not change as a result of an action (Because it merely kicks off side-effects in saga) then define the case above default, and have it fall through.
// @flow
import type { NamespaceAction } from "actions/namespace";
export type State = { /* Flowtype definition for state object */ };
export const INITIAL_STATE: State = { /* Initial state shape */ };
export function namespace(
state: State = INITIAL_STATE,
action: NamespaceAction
): State {
switch (action.type) {
case 'NAMESPACE_NAME_OF_ACTION':
return {
...state,
// Alterations to state
};
case 'NAMESPACE_NAME_OF_SAGA_ACTION':
default:
// Ensures every action was handled in reducer
// Unhandled actions should just fall into default
(action: empty);
return state;
}
}
Actions
- Define each action object type beside the action creator
- Export a union of all of the action types for use by the reducer
/*** Name of action ***/
export type NameOfActionAction = {
type: 'NAMESPACE_NAME_OF_ACTION',
/* Rest of the action object shape */
};
export function nameOfAction(): NameOfActionAction {
return {
type: 'NAMESPACE_NAME_OF_ACTION',
/* Rest of the action object */
};
};
/*** Action Union ***/
export type NamespaceAction =
| ActionOneAction
| ActionTwoAction
| ActionThreeAction;
Action Constants
Action constants are not used thanks to flow type checking. To avoid typos, we
use (action: empty)
in the default case which assures every case is accounted
for. If you need to use another reducer's action, import that action type into
your reducer, and create a new action union of your actions, and the other
action types used.
Styling
Legacy styles are housed under common/assets/styles
and written with LESS.
However, going forward, each styled component should create a a .scss
file of
the same name in the same folder, and import it like so:
import React from "react";
import "./MyComponent.scss";
export default class MyComponent extends React.component {
render() {
return (
<div className="MyComponent">
<div className="MyComponent-child">Hello!</div>
</div>
);
}
}
These style modules adhere to SuitCSS naming convention:
.MyComponent {
/* Styles */
&-child {
/* Styles */
&.is-hidden {
display: none;
}
}
}
All elements inside of a component should extend its parent class namespace, or create a new namespace (Potentially breaking that out into its own component.)
Variables and mixins can be imported from the files in common/styles
:
@import "sass/colors";
code {
color: $code-color;
}
Converting Styles
When working on a module that has styling in Less, try to do the following:
- Screenshot the component in question
- Create a new SCSS file in the same directory
- Remove styling from LESS file, convert it to the SCSS file (Mostly s/@/$)
- Convert class names to SuitCSS naming convention
- Convert any utility classes from
etherewallet-utilities.less
into mixins - Convert as many element selectors to class name selectors as possible
- Convert as many
<br/>
tags or
s to margins - Ensure that there has been little to no deviation from screenshot