douglasnaphas / anagrampoems

Make anagram poems.
Apache License 2.0
0 stars 0 forks source link

Show a menu of words available in the name #10

Open douglasnaphas opened 5 months ago

douglasnaphas commented 5 months ago

TODO

douglasnaphas commented 5 months ago

Framework selection

This is the first feature I'm working on, so I'll write out the analysis for picking frameworks.

Wishlist

Maybe wishlist is better than requirements, because every putatively required property is negotiable. Wishlist emphasizes that you might not get what you're wishing for.

  1. API Gateway-level authorizing. When a request that might need to be authenticated gets to what's serving it, it's guaranteed auth'd if it's supposed to be. This is less something I want out of a framework, and more a design decision that may influence how I view features offered by different frameworks. For example, how a framework handles cookies might matter less if I'm processing the cookies in an API Gateway authorizer and feeding the origin server info about the authenticated user.
  2. At least the option to do server-side rendering. Not saying I will, just saying I might.
  3. Not being pushed towards some SaaS solution owned by the framework maintainers. Examples of what I don't want would be Next.js, which pushes you towards Vercel, and Gatsby, which I've heard pushes you towards Gatsby Cloud. I'm hosting everything on AWS with CDK.
  4. Framework support for Lambda.
  5. Both front-end bundling and SSR.
  6. This schema validation thing is nice. Would cut out a lot of code that's boring to write.
  7. Catching errors in async middleware is nice. I'd like to know that if a middleware gets to return next() it isn't in an erroneous state.

    Architectural decisions

    Serve the front-end from S3 or Lambda?

    Lambda

    Pros

    Could do server-side rendering.

    Early winner: Fastify, no S3

    I think I can do SSR with Fastify. Maybe bundling, too. I'm just going to try it, I think.

    Another contender: Express, no S3

    I listened to this talk on Fastify and this one on downsides of Express, and I'm left unpersuaded that I should avoid Express. The downside of Express seems to be throughput, which I'm less worried about, and Fastify is introducing some concepts, like the use of plugins to achieve a modular monolith, that I don't think my app would benefit from. Express is much more widely used, Fastify is not growing quickly, and I already have working example code with Express.

    New lead contender: Express (Lambda) + Vite (S3)

    I'm probably going to need a framework skilled in bundling, et cetera, if I'm going to work successfully with Tailwind.

S3 vs. no-S3 is looking like a tradeoff between getting bundling right (S3) and avoiding front-end hydration (no S3, i.e., I don't like loading the page and then fetching the user).

S3 might win because I can mitigate the jank caused by load-then-fetch with better use of loading states or suspense.

Newer lead contender: Express + Vite, all in Lambda

Just because I'm using Vite to build a static site doesn't mean I can't SSR parts of it (I think),

douglasnaphas commented 4 months ago

ChatGPT on SSR + Vite

If I use React’s renderToString, could I combine server-side rendering with Vite.js?

Yes, you can combine server-side rendering (SSR) using React's renderToString with Vite.js. Vite is a modern build tool that significantly speeds up development with its hot module replacement (HMR) capabilities and uses Rollup for production builds, making it highly efficient. It also has out-of-the-box support for features like ES modules, which can make working with React more streamlined.

Here’s how you can set up a React SSR project using Vite.js:

Step 1: Set Up Your Project

Create a new project and initialize it:

mkdir vite-react-ssr
cd vite-react-ssr
npm init vite@latest .

When prompted, choose the React template. This sets up a basic React project managed by Vite.

Step 2: Configure Vite for SSR

Vite requires a bit of configuration to handle SSR. Modify the Vite config file to specify entry points for client and server:

  1. vite.config.js - Configure Vite to recognize separate entry points for server and client. You might also need to adjust the build settings:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      input: {
        main: './index.html',
        client: './src/entry-client.js',
        server: './src/entry-server.js'
      }
    }
  }
});
  1. src/entry-client.js - This is the entry point for the client-side application. It should hydrate the React app on the client:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.hydrate(<App />, document.getElementById('root'));
  1. src/entry-server.js - This file will handle server-side rendering:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import App from './App';

export function render() {
  return ReactDOMServer.renderToString(<App />);
}

Step 3: Implement the Server

You'll need an Express server (or any other Node.js server framework) to handle requests and serve the SSR content:

  1. Install Express:
npm install express
  1. server.js - Create an Express server that uses the server build:
import express from 'express';
import { render } from './dist/server/entry-server.js';

const app = express();

app.use(express.static('dist/client'));

app.get('*', (req, res) => {
  const appHtml = render();
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Vite + React SSR</title>
      </head>
      <body>
        <div id="root">${appHtml}</div>
        <script type="module" src="/assets/client.js"></script>
      </body>
    </html>
  `);
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Step 4: Run Your Project

Additional Considerations

Combining Vite with SSR can lead to a very fast development experience and an optimized production build, making it a compelling choice for modern React applications.

douglasnaphas commented 4 months ago

ChatGPT on adding Lambda to Express + Vite

You provided some code samples earlier in response to my question, "If I use React’s renderToString, could I combine server-side rendering with Vite.js?"

What code do I need to add or modify to run the Express server from an AWS Lambda function?

Running an Express app from an AWS Lambda function involves several adjustments to ensure that the Express application can handle Lambda's event and context objects, as well as to properly respond through Lambda's callback mechanism. You'll use libraries like aws-serverless-express or serverless-http to bridge Express and AWS Lambda. Below, I'll show you how to adapt your server-side code using the serverless-http package, which is simpler and more flexible for many use cases.

Step-by-Step Guide

Step 1: Install serverless-http First, add the serverless-http library to your project. This library is designed to handle the translation between your Node.js server (e.g., Express) and the AWS Lambda handler.

npm install serverless-http

Step 2: Modify Your Express Application for AWS Lambda Assuming you have an existing Express application setup, you'll need to modify it slightly so it can be invoked by AWS Lambda. Here’s how you can do it:

  1. Create the Express App (if not already created):

    const express = require('express');
    const app = express();
    
    app.get('/', (req, res) => {
     res.send('Hello from Express on AWS Lambda!');
    });
    
    module.exports = app;
  2. Wrap the Express app with serverless-http: Create a new file, perhaps called lambda.js, to be the entry point for Lambda:

    const serverless = require('serverless-http');
    const app = require('./app');  // Importing your Express app
    
    module.exports.handler = serverless(app);

Step 3: Configure the AWS Lambda Function Now, you'll need to set up your Lambda function on AWS. Here’s a brief overview:

Step 4: Set Up API Gateway To expose your Lambda function via HTTP:

Step 5: Deploy and Test After setting up the Lambda function and API Gateway:

Additional Notes

This setup leverages serverless-http to run an Express application on AWS Lambda, allowing you to utilize existing Express-based server-side rendering setups in a serverless environment effectively.