Fou Frontend is an isomorphic app built with modern technologies and a focus on design and performance. It uses:
- React for UI rendering
- Fluxible for a Flux architecture with unidirectional data flow
- Immutable and React "pure" components for bleeding edge performance
- Koa as the backend server for file serving and React pre-rendering
- webpack to compile and bundle everything together, hot reload included 🔥
- SCSS and Susy for sassy stylesheets
- Babel for classy ES6+ code
I used kriasoft/react-starter-kit as a starting point (hence the many commits).
- elegant landing page with good copy and a clear value proposition for the target users
- mobile-first responsive design that looks great on smartphones, tablets and desktops
- page transitions, loaders, smooth animations and UX enhancements
- form validation
- client-side checks for length and valid characters
- server-side for uniqueness
- resource bundles contain a hash in their name for cache busting => efficient, long-term caching
- each component has a local stylesheet => concise and shallow stylesheets, reduced conflicts
- webpack-dev-server reloads modules instantly => faster development, increased productivity
- server side pre-rendering => speedy SPA app with unaffected SEO
- auth
- login, logout and registration pages
- cookies are signed with KeyGrip (rotated credentials)
- sessions are stored in a Redis database, only a session ID is stored client-side
- pages: profile, conversations, settings
- functionality: write posts/comments, like posts/comments, messaging
- integrate with "inspiration sources" such as 500px, Artsy, Instagram, Pinterest
- automated E2E tests with Nightwatch.js
- refactoring
- components, decorators, server
- try to move form logic into Fluxible stores
- get rid of material-ui; use own or dedicated components
You need the following:
node.js
with generators support orio.js
- a Redis server running on localhost
- the
FOUfashion/api
server
If you're using the FOUfashion/development
repo set-up, run these commands to start the database and the reverse proxy:
$ docker-compose up -d redis
$ docker-compose up -d nginx
$ source ../.env
# install node dependencies
$ npm install
# build in production mode and start
$ npm run bundle && npm run start
# source config env vars
$ source ../.env
# build the server bundle with auto-restart
$ npm run watch-server
# build the client bundle with hot reload
$ npm run watch-client
# run BrowserSync as a proxy
$ npm run browser-sync
Note that you need a valid $FRONTEND_API_TOKEN
for it to connect to the API:
# Start the API server
$ npm start
# Connect to the admin interface
$ vantage 4000
# Generate first-party credentials
api~$ fp -u frontend -e [email protected] -f Front -l End -n fronty
# Now you can re-start the frontend server
$ export FRONTEND_API_TOKEN=<token>
I use debug to log detailed messages for app debugging. To enable logging:
- Client side: run
Debug.enabled('fou:*')
in the console and refresh the page - Server side: run
export DEBUG="fou:*"
and restart the server
If logging is not enabled, log calls are just no-ops.
Facebook's Jest is used to run unit tests.
# run the tests (coverage included)
$ npm test
# automatically re-run the tests on code changes
$ npm run test-watch
# also lint the code if you're feeling fancy
$ npm run lint
# and if you can't help from typing...
$ npm run lint-watch
While in dev mode, the servers will run on 0.0.0.0
. If you want access from another device, set the HOSTNAME
env var to the appropriate IP (LAN or public).
I use Atom with atom-beautify
, autocomplete
, language-babel
, linter
, linter-eslint
, linter-scss-lint
and css-comb
. These plugins provide code formatting, auto completion, ES6+ support and linting.
-
Components
- composition > inheritance
- use decorators and higher order components
-
Component styling
- each component has a local stylesheet
styles.scss
, preferred over JS - all the class names in a component must come from the local stylesheet
- to reuse styles, use
scss
mixins and define new classes in the local stylesheet - if a certain element and style is used frequently, consider making it a component
- if the root element has a class, try to name it the same as the component
- each component has a local stylesheet