We use yarn to manage dependencies as it provides more reliable dependency list that the traditional npm.
Once you have yarn installed, you can run yarn install.
With all dependencies installed, you can run npm run build to build the project.
You can also use npm run watch for continuous build.
Currently we use npm run watch and python -m SimpleHTTPServer <port> to serve the app.
In the future, we plan to migrate to use webpack-dev-server with hot module loading support. (See #250 -- help wanted!)
-
Don't use
export default(Why?). -
We make
index.tsinsideactions/,models/, andreducers/export everything inside it so that we can just import fromactionswithout worrying about file renaming later.
-
Action names should start with the part of the model it is modifying, so it's easy to categorize. For example, all bookmark actions have the "Bookmark" prefix.
-
Synchronous actions should implement
ReduxActioninterfaces insrc/actions/redux-action, which follows pattern described in https://github.com/acdlite/redux-actions.-
Since we already have types, we do not make action creator functions.
-
For asynchronous actions, since they involve multiple sub-actions, we still have action creator functions (e.g.,
datasetLoad()inactions/dataset.ts). These action creators followredux-thunkpatterns.
-
-
In
src/action/index.ts, we haveACTION_TYPE_INDEXthat uses TS's mapped type to declare so we make sure we generateACTION_TYPESthat contain all actions.
- In
src/models/shelf.ts, we re-declare a number of Vega-Lite / CompassQL interfaces with "Shelf" prefix, allowing them to beSHORT_WILDCARDor bothSHORT_WILDCARDand fullWildcard.
-
Since our props and states are immutable, we always use
PureComponentfor all of our components and rely on its shallow prop and state comparison. -
Use lowercase-dash-separated-names for file names. (Using PascalCase as filename can be problematic for OSX in general as OSX is case-insensitive.)
-
Following Redux's Using with React guide, we distinguish between presentation and container components. However, instead of having event handlers (e.g.,
onTodoClickin the guide) for every single events, we pass inhandleActionproperty to presentation components (which implements ourActionHandlerinterface). For more information, seesrc/actions/redux-action.ts. -
You can use this plugin to generate snippets (but manually remove default exports).
-
Use
renderas a prefix for class method that returns a React component and gets called by the component'srendermethod (e.g.,renderAddFilterSpanin<Field/>). -
For CSS, we use react-css-modules and SASS, which makes it easy to modularize style in React using the
styleNametag. (See react-css-modules's README for more details.)- Since CSS-Modules use filename as a prefix, never name a scss file
index.scss. Instead use the module name. For example, the scss file fordata-pane/index.tsxisdata-pane/data-pane.scss.
- Since CSS-Modules use filename as a prefix, never name a scss file
-
We make our props and states immutable. (Using TypeScript's
Readonlytype wrapper in reducers is very helpful to enforce immutability.) -
We use
...to make sure things are immutable and we don't cause side-effects. -
For array, we have utility methods in
src/reducers/util.ts.
src/modelscontains all interfaces and helper methods for our redux state.