This project is an assignment of a full stack subject.
It is a website for readers to purchase, review and manage the books in it.
Our inspiration comes from the Amazon and Douban (the equivalent of Goodreads in China).
The demo is running on: http://knight-frank-web.s3-website-ap-southeast-2.amazonaws.com/
For more details:
Client: README
Server: README
# Enter server folder
cd server
# Install server's dependence
npm install
# Install client's dependence (or you can cd to ../client folder and do `npm install`)
npm run install-client
# Run server and client concurrently
npm run dev
The server runs on port 3000.
The client runs on port 5000.
However, there are some variables need to be set before running this app.
They are in /server/config/key.js
.
module.exports = {
mongoURI: process.env.MONGO_URI,
port: process.env.PORT || 5000,
email: process.env.EMAIL,
emailPwd: process.env.EMAIL_PWD,
redisURI: process.env.REDIS_URI,
redisPort: process.env.REDIS_PORT,
redisPwd: process.env.REDIS_PWD,
};
If you are using mail service rather than QQ, like Gmail or Hotmail, you should change the service name in server/utils/mailer.js Line 15. For more supported well-known services can be found in Nodemailer.
For both React.js and Express.js We decided to follow Airbnb's JavaScript Code Style.
Here are some basic rules:
-
Use space between
=
andvariables
.// bad const steps=1; // good const steps = 1;
-
Use
const
for all of your references; avoid usingvar
. -
If you must reassign references, use
let
instead ofvar
. -
Use the literal syntax for object creation.
// bad const item = new Object(); // good const item = {};
-
Use property value shorthand.
Why? It is shorter to write and descriptive.
const lukeSkywalker = 'Luke Skywalker'; // bad const obj = { lukeSkywalker: lukeSkywalker, }; // good const obj = { lukeSkywalker, };
-
Do not call
Object.prototype
methods directly, such ashasOwnProperty
,propertyIsEnumerable
, andisPrototypeOf
.Why? These methods may be shadowed by properties on the object in question - consider
{ hasOwnProperty: false }
- or, the object may be a null object (Object.create(null)
).// bad console.log(object.hasOwnProperty(key)); // good console.log(Object.prototype.hasOwnProperty.call(object, key)); // best const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope. /* or */ import has from 'has'; // https://www.npmjs.com/package/has // ... console.log(has.call(object, key));
-
Use the literal syntax for array creation.
// bad const items = new Array(); // good const items = [];
-
Use
Array#push
instead of direct assignment to add items to an array.const someStack = []; // bad someStack[someStack.length] = 'abracadabra'; // good someStack.push('abracadabra');
-
Since currently there's no JavaScript engine natively supports ES6 modules, server side uses
require()
to import modules.const mongoose = require('mongoose');
React has its own sytax. Following are some basic rules in Airbnb's React Code Style.
- Only include one React component per file.
- Always use JSX syntax.
- Always use
class extends React.Component
to create class. - Extensions use
.jsx
extension for React components. - Filename uses PascalCase for filenames. E.g.,
ReservationCard.jsx
. - Reference uses PascalCase for React components and camelCase for their instances.
// bad
import reservationCard from './ReservationCard';
// good
import ReservationCard from './ReservationCard';
// bad
const ReservationItem = <ReservationCard />;
// good
const reservationItem = <ReservationCard />;
- Component uses the filename as the component name. For example,
ReservationCard.jsx
should have a reference name ofReservationCard
. However, for root components of a directory, useindex.jsx
as the filename and use the directory name as the component name:
// bad
import Footer from './Footer/Footer';
// bad
import Footer from './Footer/index';
// good
import Footer from './Footer';
- Props naming should avoid using DOM component prop names for different purposes.
Why? People expect props like
style
andclassName
to mean one specific thing. Varying this API for a subset of your app makes the code less readable and less maintainable, and may cause bugs.
// bad
<MyComponent style="fancy" />
// bad
<MyComponent className="fancy" />
// good
<MyComponent variant="fancy" />