summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbdus <abdus@abdus.net>2021-01-16 11:44:46 +0530
committerAbdus <abdus@abdus.net>2021-01-16 11:44:46 +0530
commite5bc4769750ae05eba2973ecbc637d1dad15ed8e (patch)
treec18227454f5d86bb72d05cdfa7b6812d09ca6e2d
parent3fca59639a8a2fdf23fc494f933dd74eabf65a32 (diff)
downloadabdus.net-e5bc4769750ae05eba2973ecbc637d1dad15ed8e.tar.bz2
abdus.net-e5bc4769750ae05eba2973ecbc637d1dad15ed8e.zip
new: recommendations
-rw-r--r--content/posts/server-side-react.md131
-rw-r--r--data/personal.yaml11
2 files changed, 139 insertions, 3 deletions
diff --git a/content/posts/server-side-react.md b/content/posts/server-side-react.md
index 4246cb1..56cd1fe 100644
--- a/content/posts/server-side-react.md
+++ b/content/posts/server-side-react.md
@@ -120,7 +120,19 @@ configs:
```json
{
- "presets": ["@babel/preset-react", "@babel/preset-env"]
+ "presets": [
+ "@babel/preset-react",
+ [
+ "@babel/preset-env",
+ {
+ "useBuiltIns": "usage",
+ "corejs": 2,
+ "targets": {
+ "firefox": "64"
+ }
+ }
+ ]
+ ]
}
```
@@ -197,7 +209,7 @@ module.exports = {
rules: [
{
test: /\.css$/,
- use: ["style-loader", "css-loader"], // load css files
+ use: ["style-loader", "css-loader"],
},
{
test: /\.jsx?$/,
@@ -257,3 +269,118 @@ Here, you can read more about [`hydrate`](https://reactjs.org/docs/react-dom.htm
Now that we have a `src/client/` directory, we could create as many components
we want and import them inside `src/client/index.js`
+
+### Server Set-up
+
+Nothing much here, really. A simple Node.js server which will import React and
+process `App.js` from `client/` to make an HTML string.
+
+So, let's create a directory called `src/server/index.js`, and fill it with some
+valid code.
+
+```js
+// src/server/index.js
+import React from "react";
+import { renderToString } from "react-dom/server";
+import App from "../client/App.js";
+import express from "express";
+
+const server = express();
+const port = process.env.PORT || 3000;
+
+app.listen(port, () => console.log(`Listening on ${port}`));
+
+server.get("/", async (req, res) => {
+ res.send(renderToString(<App />));
+});
+```
+
+In case you have missed it, this Node server have a JSX tag in it (i.e. `<App />`).
+Do you know what that means? Yeah, we need the Babel CLI to transpile it
+back to regular JavaScript. So, I now have to install `@babel/cli` using yarn.
+
+Once the `@babel/cli` has been installed, we will have access to `babel`
+command. Using `Babel`, we will compile `src` directory and store it inside
+`dist`. `dist/server` is the directory we will be running using Node, and not
+the `src/server` directory.
+
+Now, install `react`, `react-dom` and `express` as dependencies using Yarn.
+
+```sh
+yarn add react react-dom express
+```
+
+Let's compile everything with Babel. Following is the command to compile
+everything from `src/` directory to `dist/`.
+
+```sh
+yarn babel src -d dist
+```
+
+Now, start the damn server using Node (or `nodemon` if you are in development
+mode).
+
+```sh
+nodemon dist/server/index.js
+```
+
+At this point, the project set-up is done. Time to move on to actually building
+what I planned to build.
+
+## Quote Machine
+
+I already [described](#what-are-we-building-again) what I am building as a
+demonsration for Server Side Fendering of React.
+
+First, we need a Quote API. I had to find something which is simple, and does
+not require any authentication. One such API is the [Game of Thrones QUotes API](https://gameofthronesquotes.xyz/). It's hosted on Heroku. And the codebase can be found
+at [Github](https://github.com/shevabam/game-of-thrones-quotes-api).
+
+Let me open `src/server/index.js` and write some code to call this API.
+
+Start by writing a helper function to fetch an API endpoint. I implemented it in
+the most minimal way. Have a look:
+
+```js
+function fetch(url, options = {}) {
+ return new Promise((resolve, reject) => {
+ https.get(url, options, (res) => {
+ let data = "";
+ res.on("data", (chunks) => (data += chunks));
+ res.on("error", (e) => reject(e));
+ res.on("end", () => resolve(data));
+ });
+ });
+}
+```
+
+In case you have not noticed, we need a HTML template to render JavaScript
+bundle generated by React. I will create it inside `src/shared/index.js`. This
+will also help me pass an initial state to the Server Side Rendered app. Keep
+reading.
+
+```js
+// src/shared/index.js
+export default function renderComponen(meta, html, script) {
+ return `
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <title>Quote Machine</title>
+ ${meta}
+ </head>
+ <body>
+ <div id="react-root">${html}</div>
+ ${script}
+ </body>
+ </html>`;
+}
+```
+
+This script takes in three parameters, `html`(generated by `renderToString`),
+`meta`(Meta Tags) and `script` (JavaScript bundle generated by Webpack).
+
+All good so far!
+
+
diff --git a/data/personal.yaml b/data/personal.yaml
index 5133152..f713fb2 100644
--- a/data/personal.yaml
+++ b/data/personal.yaml
@@ -16,6 +16,16 @@ testimonials:
have an opportunity to work with Abdus, you are among the lucky ones.
One of the most reliable people I know.
+ - name: Matt Smith
+ designation: Software Engineer, Zero to Mastery
+ content: |
+ Having been fortunate enough to have worked with Abdus in multiple
+ projects in various capacities over the last 3 years, I can be sure to
+ count on Abdus, whether I am leading a project or if I am working on a
+ project he is leading. Abdus is highly motivated, knowledgeable and really
+ takes the time to understand the requirements in order to suggest or
+ implement the best solution. Its always a pleasure to work with Abuds!
+
- name: Aquibur Rahman
designation: CEO, MailModo
content: |
@@ -24,7 +34,6 @@ testimonials:
looking for the solution himself. I am sure with his hard work and grit,
he is going to succeed always in his life.
-
social:
#- url: https://t.co/cloud_dev
#name: Telegram