The second day of entry: what kind of experience is it to use koa to build a node server

Today is the second day of my employment. The leader told me that the files rendered by the server were configured yesterday. Today, I will study how to use koa to build a node server!

As usual, I went to the koa official website to check what koa is, and the result is a very simple one-sentence introduction on the official website: koa--a next-generation web development framework based on the node.js platform.

Personally, I feel that the official documentation of koa is not very friendly to front-end Xiaobai. It is recommended to read Ruan Yifeng's koa framework tutorial and Liao Xuefeng's article on koa introductory before getting started.

Then introduce the first step of the project, install koa:

npm i also -S

After installation, first create a new server folder in the project root directory, then create a new server.js file in this folder, and then introduce koa in it:

const Koa = require('koa')
const app = new Koa()
const isDev = process.env.NODE_ENV === 'development'

Why declare isDev here? Because server-side rendering is divided into two different situations: development environment and production environment.

Then we continue to write a middleware in server.js to record all requests and fetch errors, so that we can get a good understanding of whether there are some errors in the process of server-side rendering, and troubleshoot the errors in time.

Respect first:

app.use(async (ctx, next) => {
 try {
   console.log(`request with path ${ctx.path}`)
   await next()
 } catch (err) {
   console.log(err)
   ctx.status = 500
   if (isDev) {
     ctx.body = err.message
   } else {
     ctx.body = 'please try again later'
   }
 }
})

Briefly explain: adding an async in front of the function represents the asynchronous processing function, and the parameter next represents the function that executes the next asynchronous processing. Inside the try loop body, the console prints out the requested path. If isDev is true, you can directly write the error message into the body, so that you can see the error message directly on the page. If it is not a development environment, you can write a friendly reminder text, for example: "please try again later".

This is the simplest koa middleware that records all requests and errors, and returns an error message.

Next, let's talk about how to handle server-side rendering.

Before processing server-side rendering, first install koa-router in the terminal:

npm i koa-router -S

This is a routing tool provided by koa. Then create a routers folder under the server folder, and then create two files in it, one is dev-ssr.js and the other is ssr.js. The former deals with server-side rendering during development, and the latter deals with formal environments.

In the dev-ssr.js file, first introduce koa-router:

const Router = require('koa-router')

Here, you also need to use two tools, which need to be installed:

npm and axios - S
npm and memory -fs -D

Axios that sends requests on the node side, of course, can also send requests on the browser side. Remember to follow -S when installing, because it can be used in business code.

And memory-fs is only used during development, so it is followed by -D. There may be children's shoes to ask, what is this memory-fs used for? Don't worry, Run Tu will take a picture of the official website for everyone to see at a glance:

The main idea is: a simple memory file system. Save the data in a JavaScript object.

Then, without further ado, let's introduce these two tools:

const axios = require('axios')
const MemoryFS = require('memory-fs')

Next, two more tools are introduced:

const webpack = require('webpack')
const VueServerRenderer = require('vue-server-renderer')

Because the code needs to be packaged in the node development environment and server-side rendering is required.

Next, to introduce serverConfig, it is the configuration file webpack.config.server.js written on the first day of employment:

const serverConfig = require('../../build/webpack.config.server')

Then, how to make webpack run in the node development environment?

The answer is through serverCompiler:

const serverCompiler = webpack(serverConfig)

Then go to a new mfs instance:

const mfs = new MemoryFS()
serverCompiler.outputFileSystem = mfs

This specifies that the output directory of webpack is in MemoryFS.

With these configurations, declare a bundle:

let bundle

Used to record new files generated by webpack each time it is packaged.

serverCompiler.watch({}, (err, stats) => {
 if (err) throw err
 stats = stats.toJson()
 stats.erros.forEach(err => console.log(err))
 stats.hasWarnings.forEach(warn => console.warn(err))

 const bundlePath = path.join(
   serverConfig.output.path,
   'vue-ssr-server-bundle.json'
 )
 bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8'))
})

The advantage of using watch() here is that, like using webpack-dev-server, every time a file is modified in the client directory, it will re-pack it, and then you can get the new file.

The first parameter of serverCompiler.watch() is an empty object, and the second parameter is a callback. If there is err, throw it directly.

Then I felt a bit obscure about stats, and the leader told me to do it first, and then read the webpack documentation when I had time.

Next, you can read the generated bundle file, splice the path to read the file, set the file name, and specify the encoding as utf-8, and finally convert the string to JSON through JSON.parse().

After performing the above steps, it is time to return the content to HTML.

During server-side rendering, HTML is generated using the ejs template engine. Use the createBundleRenderer() method of VueServerRenderer to help generate a function that can directly call the renderer. It accepts several parameters in it. The first one is inject, which is set to false, so that it will not perform other injection operations. The second is clientManifest, which automatically generates a string referenced by a js file with a script tag, so that it can be directly added to the content of ejs.

Finally, the complete code of dev-ssr.js is as follows:

const Router = require('koa-router')
const axios = require('axios')
const path = require('path')
const fs = require('fs')
const MemoryFS = require('memory-fs')
const webpack = require('webpack')
const VueServerRenderer = require('vue-server-renderer')

const serverConfig = require('../../build/webpack.config.server')

const serverCompiler = webpack(serverConfig)
const mfs = new MemoryFS()
serverCompiler.outputFileSystem = mfs

let bundle
serverCompiler.watch({}, (err, stats) => {
 if (err) throw err
 stats = stats.toJson()
 stats.erros.forEach(err => console.log(err))
 stats.hasWarnings.forEach(warn => console.warn(err))

 const bundlePath = path.join(
   serverConfig.output.path,
   'vue-ssr-server-bundle.json'
 )
 bundle = JSON.parse(mfs.readFileSync(bundlePath, 'utf-8'))
})

const handleSSR = async (ctx) => {
 if (bundle) {
   ctx.body = 'wait a moment...'
   return
 }

 const clientManifestResp = await axios.get(
   'http://127.0.0.1:8080/vue-ssr-client-manifest.json'
 )

 const clientManifest = clientManifestResp.data

 const template = fs.readFileSync(
   path.join(__dirname, '../server.template.ejs')
 )

 const renderer = VueServerRenderer
   .createBundleRenderer(bundle, {
     inject: false,
     clientManifest
   })
}

 

write at the end

The experience of using koa to build a node server this time is only about the renderer step. Later, I will continue to talk about how to render the bundle into actual HTML content and add it to the template. The latest articles will be updated in my public account < Uncle Runtu > as soon as possible. Welcome to pay attention.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325303098&siteId=291194637