Giter Club home page Giter Club logo

looseleaf-node's Introduction

LooseLeaf - Node.js App

Getting Started

We are going to use the following stack:

  • Platform: node
  • Framework: express
  • CSS Framework: materialize
  • CSS Preprocessor: SASS
  • JavaScript Framework: React with react-router v4 and react-router-config
  • Build Tool: webpack
  • Unit Testing: mocha, chai
  • Integration Testing: SuperTest and cheerio.
  • Database: mongodb
  • Authentication: facebook, email, google, github, twitter
  • Deployment: digitalOcean

Tools

Authentication and Database Middleware

  • mongoose - object modeling for our MongoDB database
  • passport - help us authenticating with different methods

Automated Testing

  • mocha sets up the unit test, while chai helps you accomplish a unit test using asserts.
  • SuperTest spools up your Express server and sends requests to it.Once the requests come back, you can make assertions about the response.
  • cheerio is jQuery for Node. It'll help your server code parse HTML.

Baseline App

Take the following steps to create a baseline app:

  1. Follow this tutorial to set up a create-react-app with react-hot-loader

    React Hot Loader allows you to tweak React components in real time.

  2. Follow this tutorial to set up the rest of the create-react-app project to use react-router. We are going to use Version 4.x of the React Router, which is a complete rewrite of Versions 3.x and prior.

    Warning: Implementing the Build, Run & Develop section in the second tutorial could cause react-hot-loader to not work so this section wasn't implemented in the baseline app, which is available for download on Github.

  3. FullStackReact's Tutorial and Sample Project - A create-react-app with server example

    • Pro: Builds a client app to run concurrently with a server app.
    • Con: This helps you build a single page application. If you want to build a isomorphic webapp, proceed with the next step.
  4. Isomorphic Webapp Book Chapter 2 Sample Code Learning

Docs

File Structure

$ tree -l 3 --ignore 'node_modules'
looseleaf-node
├───package.json
├───.babelrc
├───.env <== #C
├───server
│   ├───server.js <== #B
│   ├───start-client.js	 
│   ├───run.js <== #A
│   ├───build
│   ├───data <== #A
│   ├───assets <== #A
│   └───api
|   	 └───api1.js <== #A and #B
├───test
├───client
│   ├───package.json
│   ├───config
│   ├───public
|   |   └───favicon.ico
|   |   └───index.html  <== #B
│   ├───src
│   |   └───shared
|   |   |   ├───Profile
|   |   |   |   ├── App.js <== #A
|   |   |   |   ├── HTML.js <== #A
|   |   |   |   ├── Header.js
|   |   |   |   ├── Home.js
|   |   |   |   ├── Main.js
|   |   |   |   ├── NotFound.js
|   |   |   |   └── routes.js <== #A
|   |   |   └───Recipe
|   |   |       ├── App.js
|   |   |       ├── HTML.js
|   |   |       └── ...
│   |   ├───AppUser.js <== #B
│   |   └───index.js <== #B
│   |   └───main.js <== #A
|   ├───iso-middleware
|   |   ├── renderRoute.jsx <== #D
|   |   └── renderView.jsx <== #D

Notes

  • Lots of extraneous folders and files were omitted from the file structure map above because they are auto-generated when you first set up your project or after when you build the project
  • #A: These files are the entry points for the isomorphic webapp.
  • #B: These files are associated with the create-react-app, which includes HMR and react-hot-loader for better development work flow. index.js and index.html are the entry points. index.js renders component that attaches to the root componnent identified in the index.html file.
  • #C: These files are omitted from the github repo because they contain authentication ids, secrets, etc that are application-specific
  • #D: These files are used by the server to render html pages using React code shared with the client.

Tutorial

  • React Express

    Facebook provides a command-line utility called create-react-app which automatically sets up a new React project with a sensible default project structure and feature set. This is the best way to get started as a beginner.

    You'll likely outgrow this option pretty quickly as you get a better grasp of React and want to customize your stack. Fortunately, create-react-app offers an eject option to export your app, so you're not locked in.

  • create-react-app

Create React App is agnostic of the backend, and just produces static HTML/JS/CSS bundles.

Running the App

Before running the app, you have to set up a few things:

  1. From the project directory, run the command:

    $ npm install && cd client && npm install && cd ..
    $ mkdir server/build
    

    This installs all the dependencies in your package.json from for both the server and the client. Everytime you make changes to package.json, npm install needs to be run so that the dependencies defined in the file would get downloaded by npm. The dependencies gets downloaded into a folder called node_modules.

  2. Set up your database for the app:

    MongoDB

    • Install MongoDB: $ brew install mongodb

    • Create the data directory: $ sudo mkdir -p /data/db

    • Set permissions for the data directory:

       $ sudo chown -R `whoami` /data/db
      
    • Run MongoDB server: $ mongod

    • Run MongoDB shell in a separate terminal: $ mongo

    • Some useful commands to run in the mongo shell

       > use test $ switch to db test
       > show collections $ list all collections inside current db
       users
       > db.users.find() $ in the users collection, return all documents
       > db.users.remove( { } ) $ remove all documents in the users collection
       > db.users.remove( { index } )
       > db.users.dropIndexes()
      

Check out Azat Marda's Cheatsheet, Quick Reference, and Little Mongo Handbook for more useful commands.

  1. If you are developing on the client side only, $ cd client then $ npm run build or $ yarn build - Build the project. For production builds, you'll want to use npm run build to build an optimized bundle and transpiled down to ES5, which will be saved to the filesystem. If you don't have hot reloading enabled, you have to run this after making changes to your source code to allow the changes to take effect next time you start the client server. This is undesirable and there are a few workarounds, in particular, nodemon and react-hot-reloader, which will be discussed in more detail below.

  2. For developing an integrated client and server app, we want to run the isomorphic webapp with the following command line:

    $ npm start
    

    This will give us access to:

    $ npm build-client
    
  3. For developing an server and client separately

    • To run both the server and client in separately, do the following, which starts the server to automomatically listen on port 3001 (http://localhost:3001/) and the client to automomatically listen on port 3000 (http://localhost:3000/).

       $ npm start-dev
      

      If the single page application doesn't render correctly on the server, you need to do this:

       # npm build-client
      

      The npm start-dev script is equivalent to running npm run start-server and npm run start-client concurrently. We learn how to do that from FullStackReact's Tutorial and Sample Project.

    • To run just the server app, do

       $ npm run start-server
      
    • To run both the client and server app, do

       $ npm start-dev
      
    • To run the client app, do

       $ npm run start-client
      

      Alternatively,

       $ cd client && npm start
      

      In this mode, you can use react-hot-loader to make changes to react components in runtime.

      Just go to http://localhost:3001/api/hello to see change being made.

      If you want to run on other ports, like 9000, 8000, 8080, just specify the port you want:

       $ PORT=9000 npm start
      
    • To run the server to serve static content:

       $ yarn global add serve
       $ serve -s build
      

      In this mode, you can't use react-hot-loader because the client app is rendered on the server side.

  4. Stop the database server when you are done:

    • Stop the postgres database
    $ pg_ctl -D /usr/local/var/postgres stop
    
    • Or if you use mongo: control+C

Redux

redux is a manager of global variables for React components.

Middleware

  • redux-thunk - allows you to write action creators that return a function instead of an action. redux-thunk allows you to delay the dispatch of an action or to dispatch only if a certain condition is met. A thunk is a function that wraps an expression to delay its evaluation.
  • redux-promise - receives a promise, dispatch the resolved value of the promise, but will not dismatch anything if the promise rejects.
  • redux-logger - logging tool that lets you replay problems as if they happened in your own browser.
  • react-redux - We need to use connect from react-redux to connect a React component to a Redux store.

Express

  • morgan - log every request to the console
  • body-parser - get information from html forms

Authentication

See the tutorial for how to set up passport and postgresql with your react-node app.

We also need to create a controller for creating the User object after the user enters all the required information:

$ mkdir controllers
$ touch controllers/user.js

The user controller will include logic for creating a new user and authenticating a returning user. The user controller relies on the User model for creating a new User. The user controller requires the following dependencies:

  • async - We will be using async.waterfall a lot, which:

    Runs the tasks array of functions in series, each passing their results to the next in the array. However, if any of the tasks pass an error to their own callback, the next function is not executed, and the main callback is immediately called with the error.

  • nodemailer - a module for Node.js applications to allow easy as cake email sending.

  • jsonwebtoken

  • moment - is a lightweight Javascript date library for parsing, validating, manipulating, and formatting dates.

  • request - Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.

  • querystring - Node's utilities for parsing and formatting URL query strings.

Oauth

  1. Install dependencies
    • moment, which is a lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.
    • react-cookie, which lets you load and save cookies with React.

CSS

We are using materialize-css, which depends on jquery. Add the following to the client project:

$ cd client
$ npm install --save materialize-css
$ npm install --save jquery
$ touch src/assets/index.css

The index.css is where the custom styles for you app go. This will override the materialize-css style if you add the following imports to your index.js (or whatever the main entry point of your client app is):

// src/index.js

import 'materialize-css'
import 'materialize-css/dist/css/materialize.min.css';
import './assets/index.css';

To use materialize components in your react components, import jquery and add the script in componentDidMount:

// src/components/Header.js
import React from 'react'
import { Link } from 'react-router-dom'
import $ from 'jquery'

class Header extends React.Component {
  componentDidMount() {
    $(".dropdown-button").dropdown()
  }
  render() {
    // TODO: nav and dropdown menu
  }

What about CSS javascripts? Read the full stack react tutorial for more on that.

DevTools

  • morgan - quest logger middleware for node.js
  • webpack
  • babel
  • immer - a tiny package that allows you to work with immutable state in a more convenient way. It is based on the copy-on-write mechanism.
  • mobx - Simple, scalable state management

Resources

looseleaf-node's People

Contributors

xiaoyunyang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

looseleaf-node's Issues

MVP Checklist

Beta version 1

User Creation and Update

  • Create User Account via Facebook
  • Create User Account via Github
  • Create User Account via Email and Local Strategy
  • Settings Page - If username update ... need to make sure it’s not already taken

User Profile Page

  • Make a user public profile page.
  • User can follow other users.
  • Add a link on user profile page to join a community if the user is not currently associated with any community.
  • Under the "Projects" Tab, display all the projects which the User has created.
  • Under the "Projects" Tab, display all the projects for which the User is a contributor for.
  • Show badges for each project that the user has created and/or contribute to: badges that could be shown: (1) Creator of the project, (2) contributor of the project, (3) watcher of the project.

User Home Page

  • Display latest posts from someone the user follows
  • Display latest posts from some who follows the user
  • Display latest posts related to the projects the user is a contributor and/or creator for
  • Display latest posts created under the community of which the user is a member.

Project Creation

  • Redirect to project page if a project is successfully created.

Project Page

  • HTML for each project page needs to have correct meta.
  • Ability for a logged in user to "contribute" to a project. Also, there should be a way to undo it.
  • Ability for a logged in user to "watch" a project page. Also, there should be a way to undo it.
  • Display view-only ProjectPage for guests of the website who are not logged in and interactive ProjectPage for users who are logged in.
  • Ability for any logged in user to post an update to project (Draft.js).
  • Display Contributors for a ProjectPage (async fetch via redux).
  • Display post associated with the project (need Api and a way for view to distinguish between posts by project creator, project contributor, and any other user).
  • Allow project creator to edit the Project Info.

Notif

  • Create standalone Notif page under User App.
  • Whenever userA invites userB to join a project via the project page, the invite message and link to the project should be added to the userB's notifications stack.
  • Whenever any user excluding the project creator clicks "contribute" button, a message that a user joined the project, along with a link to the project should be added to the project creator's notification stack.
  • Whenever userA follows userB, a message that userA started following them should get added to userB's notifications stack.

Post

  • Ability for the post creator to delete a post.
  • Create standalone post page that displays a single post.
  • Ability for the post creator to edit a post.
  • Ability for any loggedinUser to respond to a post.
  • Ability for any loggedinUser who is not the post creator to react to post. Some ideas: (1) like 👍 (2) hooray 🎉, (3) great job 👏,(4) mindblowing 🤯, (5) interesting 🤔, (6) love ❤️

Community Page

  • List some dummy data for the projects, which is hosted from JSON files stored on server
  • Every created project should have its own page.
  • Use settings page to see and modify user information
  • Ability for user to make an announcement on Community page (anyone or just community members?)
  • Ability for user to join a community.
  • Ability for user to leave a community.
  • Display users who are members of the community based on date last logged in. Most recent at the top.
  • Display posts created under the community based on date created. Most recent at the top.
  • Display projects associated with the community based on date created. Most recent at the top. One project can be associated with multiple communities.

Freemium

  • Remove user email from user profile. Emails can be accessed by recruiters who pay LooseLeaf a fee to access the talent pool on LooseLeaf (Same business model as LinkedIn and Stackshare)

Misc

  • Include a page for browsing all communities.
  • Include a page for browsing all projects.

Security

  • Enable csrf for the form used to submit user email and password
  • List all users from community page if they have joined the community.
  • Server sends GuestApp if not logged in, and sends UserApp if logged in.
  • Complete HowItWorks page. Serve content for the page from a markdown file.

Beta Version 2

User Creation and And Update

  • If someone joins via Github, default username for this username should be plucked form the github username.
  • User should be able to add multiple links for their website, including (1) Linkedin, (2) Github, (3) Personal, (4) Dribble, (6) YouTube channel. See Simbi for inspiration.
  • When user first signs up, redirect the user to the ProfileBuilder app that asks a series of questions to help the user set up his/her profile.
  • Settings Page - Ability to delete an account.
  • Settings Page - Ability to disable account.
  • Settings Page - Ability to change password from user setting page

User Profile Page - Projects

  • Highlight all the projects for which the User is a contributor to show if user has acquired the following "badges" for the project: (1) contributed to the project (i.e., added self as a contributor), (2) watching the project (if is a contributor, automatically is a watcher of the project), (3) submitted something for the project, (4) voted best submission by community, (5) voted best submission by project creator, (6) has posted under the project's discussion board (?)
  • Upon hover over the "contributor" badge, a tooltip should show indicating how many posts this user made under this project.

Project Creation

  • Create ProjectBuilder app that asks a series of questions on multiple pages to help the user create a project.
  • The description field for the project should be Draft.js, not regular text.
  • The project creator has the option to becomes the first project contributor.
  • Project creator has the ability to end the project anytime?

Freemium

  • Premium users can make projects private (Github's business model).

Company Pages (?)

  • organizations can create company pages.
  • Individual users can associate themselves with a company page (similar to AngelList and Crunchbase)

FAQ

  • Freemium - Limit free users to join only one community at a time? Premium users can join many communities?
  • Freemium - No limit to how many projects a free user can be a contributor for.
  • Clarify why we ask user for their location. The reason is we need to connect them to the non-profits that are close to them because non-profits organizers are well connected and can introduce them to opportunities.
  • Look into repl.it, codepen, codesandbox and Glitch for hosting developer projects.
  • Aspiring creators can create projects postings and work on the projects that they've created
  • Project creator specifies the deliverable and the due date. Once a project is created, anyone can work on it.
  • Deliverables may include Medium (for writing and comics), Codepen, Glitch, repl.it, and Github (repo or gist).
  • Completing a project means submitting a link to the project from the project page.
  • When the clock runs out on a project, the creator of the project will be prompted to select the best submittal and give review or feedback to any of the submittals thus far.

Deployment Prep

AWS

  • See tutorial part 1 and part 2 for deploying to AWS EC2 Micro instance.
  • Another tutorial for setting up MERN webapp on EC2
  • Set up mongodb by ssh into AWS EC2 instance and install mongo locally. Run mongod and mongo. Step 1: Follow this tutorial)
    Step 2: Make sure AWS Inbound Rule under Security Settings are as such:

screenshot 2018-08-03 23 17 10

Step 3: ``` // server.js import mongoose from 'mongoose'; mongoose.connect('mongodb://localhost:27017/test’); ``` [This tutorial](https://ianlondon.github.io/blog/mongodb-auth/) is also helpful.

User settings Update Bugs

Bug

  • Update redux store after user info changes (See TODO in this file). Current behavior is after successfully updating user info in the database via the user settings page, when we navigate back to user profile page using the SPA, outdated info is still shown.
  • If user successfully changes username, have server redirect to the updated url with the new username. This would inevitably cause a page refresh.

TODO

  • When user wants to change username, have the server check if the desired username is already taken. There's opportunity to have some code reuse with the local registration handler.
  • When user wants to change email, have the server check if the new email is not already taken.
  • When user makes any request to the server to change User data, make sure this user is actually logged in.
  • If user successfully updates username, have the server redirect back to the settings page with the new username (different URL)

App Setup

Technology selection and experimentation

  • Select Web Tech Stack HowTo doc
  • Add React Router V4. Hack react-router-config to handle routing in Guest Mode and User Mode - See Solution
  • Connect Mongo database to server using mongoose

Dev Workflow and environment Set up

  • Set up create-react-app for development of client application:
    • Integrate create-react-app with Server API. Got create-react-app and server to run on separate localhost ports concurrently for improving separation of concerns between server code and client code. I used FullStackReact's Tutorial and Sample Project, which is a create-react-app with server example.
    • Set up create-react-app with webpack 4, code splitting, webpack hot module reload, webpack-dev-middleware, and react-hot-loader. Created open source starter project isomorphic-router-demo
  • Add eslint to both client and server.
  • Set up automated Testing for server: mocha, chai, SuperTest and cheerio.

Isomorphic App Features

Set up Universal App (Isomorphic Webapp)

  • Set up a single page isomorphic Webapp using Iso Book Chapter 2 Sample Code as a starting point.
  • Set up an isomorphic router app using Iso Book Chapter 4 Sample Code and a few other tutorials and universal/isomorphic app repos to get everything set up with React Router 4, react-router-config, Webpack 4 and code splitting. Created a repo isomorphic-router-demo to help others who need to get started with an isomorphic router app with this stack.

UserProfileApp server and client integration

Content Creation

  • Create React component that imports text from markdown to be rendered on different pages. Gotcha: Enable cors before serving static content from localhost:3001 (server) for localhost:3000 (create-react-app) consumption. This is for development only. Alternatively, you can implement a workaround to add an extension to Chrome that disables CORS protection.

Security Stuff

  • [Server] Authentication and User Login - See SetupAuth

    • Scotch.io's local auth Tutorial
    • For Facebook and Github registrations, make local password the token.
    • Scotch.io's oAuth Tutorial and DJAM's programming blog to sign up / login via Facebook and Github.
    • Sign up / Login with LinkedIn
    • Add nodemailer and mailgun to allow app to send emails to users. See this article
    • Refactor passport auth code and new user creation code to eliminate duplicate code. Fix the callback hell with mongoose database access.
    • Remove capability to for user to delete their profile. They can only deactivate it. Deleting user from database messes up the logic for creating a unique user name.
  • [Security]

    • Sanitize input on the server side (ejs form) using validator
    • Add helmet to server to mitigate cross site scripting (XSS).
    • Add https to localhost server.
    • Add csurf to server side forms (ejs) to protect against cross site request forgery (CSRF).
    • Sanitize client side using DOMPurify
    • In the login via email strategy, rather than displaying the message indicating email has a problem or password has a problem ,simply display "Incorrect email or password". This is better from a security standpoint.
    • Move all secret auth stuff to .env, which is excluded from github as defined in gitignore. See this tutorial
    • Add XSS protection to client side forms. Use validator?
    • Add csurf to client side forms to protect against CSRF.
    • Incorporate client-side detection and mitigation of invalid input for user login/signup forms
    • Set up auto-redirect to the HTTPS app

Unhandled Promise Rejection

Error occurs every time passport is used to log in user. The error dump are below:

Facebook

Logging in from CommunityGuest page through facebook and getting redirected back to CommunityUser page.

::1 - GET /auth/facebook?redirPath=/community/designers/projects HTTP/1.1 302 0 - 0.918 ms
::1 - GET /auth/facebook/callback?code={some code}
::1 - GET /community/designers/projects HTTP/1.1 200 3719 - 5.345 ms
::1 - GET /index.css HTTP/1.1 304 - - 0.306 ms
::1 - GET /communityuser.bundle.js HTTP/1.1 304 - - 0.381 ms
::1 - GET /api/project HTTP/1.1 304 - - 2.272 ms
(node:26522) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot 
set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:469:11)
    at ServerResponse.header (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:170:12)
    at /Users/xiaoyun/LooseLeaf/Website/looseleaf-node/client/iso-middleware/renderLandingApp.jsx:34:16
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:26522) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 
This error originated either by throwing inside of an async function without a catch block, 
or by rejecting a promise which was not handled with .catch(). (rejection id: 9)

Github

Logging in from Landing home page through github and getting redirected back to User home page.

::1 - GET /auth/github?redirPath=/ HTTP/1.1 302 0 - 0.805 ms
::1 - GET /auth/github/callback?code={some code} HTTP/1.1 302 46 - 1002.604 ms
(node:26522) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot 
set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:469:11)
    at ServerResponse.header (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:170:12)
    at /Users/xiaoyun/LooseLeaf/Website/looseleaf-node/client/iso-middleware/renderLandingApp.jsx:34:16
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:26522) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error 
originated either by throwing inside of an async function without a catch block, or by rejecting 
a promise which was not handled with .catch(). (rejection id: 10)
::1 - GET / HTTP/1.1 200 8183 - 12.327 ms
::1 - GET /index.css HTTP/1.1 304 - - 0.943 ms
::1 - GET /logo.png HTTP/1.1 304 - - 0.571 ms
::1 - GET /user.bundle.js HTTP/1.1 304 - - 0.435 ms
::1 - GET /api/hello HTTP/1.1 304 - - 0.780 ms
(node:26522) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot 
set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:469:11)
    at ServerResponse.header (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:170:12)
    at /Users/xiaoyun/LooseLeaf/Website/looseleaf-node/client/iso-middleware/renderLandingApp.jsx:34:16
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:26522) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error 
originated either by throwing inside of an async function without a catch block, or by rejecting 
a promise which was not handled with .catch(). (rejection id: 11)

Local

Logging in from Project page to through email+password getting redirected back to the same Project page.

::1 - POST /auth/login HTTP/1.1 200 2 - 227.223 ms
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:469:11)
    at ServerResponse.header (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:170:12)
    at done (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:1004:10)
    at tryHandleCache (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/ejs/lib/ejs.js:228:10)
    at View.exports.renderFile [as engine] (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/ejs/lib/ejs.js:437:10)
    at View.render (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/view.js:135:8)
    at tryRender (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/application.js:640:10)
    at Function.render (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/application.js:592:3)
    at ServerResponse.render (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:1008:7)
    at /Users/xiaoyun/LooseLeaf/Website/looseleaf-node/server/server.js:220:19
    at Layer.handle [as handle_request] (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/router/index.js:317:13)
    at /Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/router/index.js:275:10)
location undefined
::1 - GET /project/this-is-a-test-jb2t2cr HTTP/1.1 200 4030 - 6.196 ms
::1 - GET /index.css HTTP/1.1 304 - - 0.641 ms
::1 - GET /logo.png HTTP/1.1 304 - - 0.565 ms
::1 - GET /projectpage.bundle.js HTTP/1.1 304 - - 0.406 ms
(node:26522) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot 
set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:469:11)
    at ServerResponse.header (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:767:10)
    at ServerResponse.send (/Users/xiaoyun/LooseLeaf/Website/looseleaf-node/node_modules/express/lib/response.js:170:12)
    at /Users/xiaoyun/LooseLeaf/Website/looseleaf-node/client/iso-middleware/renderLandingApp.jsx:34:16
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:26522) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error 
originated either by throwing inside of an async function without a catch block, or by rejecting 
a promise which was not handled with .catch(). (rejection id: 13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.