Skip to content

Instantly share code, notes, and snippets.

@jason-jbell
Forked from ericpkatz/fullstack_setup.md
Created September 1, 2021 23:04
Show Gist options
  • Save jason-jbell/ed0636277b692cd53d099073b6e07490 to your computer and use it in GitHub Desktop.
Save jason-jbell/ed0636277b692cd53d099073b6e07490 to your computer and use it in GitHub Desktop.
Minimal setup for full stack node app using Sequelize / pg and React

package.json

{
  "name": "full-stack-demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack",
    "build:dev": "npm run build -- --watch --mode=development",
    "start:dev": "npm run build:dev & nodemon server --ignore dist/ --ignore src/"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "pg": "^8.5.1",
    "sequelize": "^6.3.5"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/preset-react": "^7.12.7",
    "axios": "^0.21.0",
    "babel-loader": "^8.2.2",
    "nodemon": "^2.0.6",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "webpack": "^5.9.0",
    "webpack-cli": "^4.2.0"
  }
}

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        options: {
          presets: ['@babel/preset-react']
        }
      }
    ]
  }
};

server.js

const express = require('express');
const { static } = express;
const path = require('path');

const app = express();

app.use('/dist', static(path.join(__dirname, 'dist')));

app.get('/', (req, res, next)=> res.sendFile(path.join(__dirname, 'index.html')));

app.get('/api/users', async(req, res, next)=> {
  try {
    res.send(await User.findAll());
  }
  catch(ex){
    next(ex);
  }
});

const init = async()=> {
  try {
    await syncAndSeed();
    const port = process.env.PORT || 3000;
    app.listen(port, ()=> console.log(`listening on port ${port}`));
  }
  catch(ex){
    console.log(ex);
  }
};

const Sequelize = require('sequelize');
const { STRING } = Sequelize;
const conn = new Sequelize(process.env.DATABASE_URL || 'postgres://localhost/acme_db');

const User = conn.define('user', {
  name: STRING 
});
const syncAndSeed = async()=> {
  await conn.sync({ force: true });
  await Promise.all([
    User.create({ name: 'moe' }),
    User.create({ name: 'larry' }),
    User.create({ name: 'lucy' })
  ]);
};

init();

src/index.js

import React, { Component } from 'react';
import { render } from 'react-dom';
import axios from 'axios';

class App extends Component{
  constructor(){
    super();
    this.state = {
      users: [],
      loading: true
    };
  }
  async componentDidMount(){
    this.setState({
      users: (await axios.get('/api/users')).data,
      loading: false
    });

  }
  render(){
    const { users, loading } = this.state;
    if(loading){
      return '....loading';
    }
    return (
      <ul>
        {
          users.map( user => { 
            return (
              <li key={ user.id }>
                { user.name }
              </li>
            );
          })
        }
      </ul>
    );
  }
}

render(<App />, document.querySelector('#root'));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment