You already know a little about Node.js from 14Nodejs (7 days)

Finally, I tried to contact the wechat public subscription account development which I always wanted to do but failed to achieve

Of course, with their current level, still rely on the help of the tutorial, here to learn the course is 7 days to get node.js wechat public number development

This is my second 7-day course since I got to know Node.js, but before that I have to learn about the Koa framework covered in the tutorial


Koa is introduced

Koa is a Web development framework based on the Node.js platform built by the original Express team

Express is an ES5-based syntax, and with the new version of Node.js supporting ES6, the team rewrote it to produce KOA 1.0, while KOA 2.0 is an even more advanced ES7-based syntax

Install koa2

npm i koa
Copy the code

Create the KOA2 project

// Import koA, unlike koa 1.x. In KOA2, we import a class, so we use uppercase koa:
const Koa = require('koa');

// Create a Koa object representing the Web app itself:
const app = new Koa();

app.use( ... )

// Listen on port 3000:
app.listen(3000);
Copy the code

App. Use (/ path, function /, the function… )

Installing middleware on path causes the middleware function to be executed whenever the base path of the requested path matches that path. If path is not set, the default is /

app.use('/admin'.function(req, res) {
   console.log(req.originalUrl); // '/admin/new'
	console.log(req.baseUrl); // '/admin'
	console.log(req.path); // '/new'
});
Copy the code
app.use(async (ctx, next) => {
    await next(); // Process the next asynchronous function
    ctx.response.type = 'text/html' // Set the content-type of response
    ctx.response.body = '

Hello, koa2!

'
// Set the content of response }) Copy the code

Functions marked with async are called asynchronous functions. In asynchronous functions, another asynchronous function can be called with await. These two keywords will be introduced in ES7 (usage looks like Promise)

In the above code, the argument CTX is the variable that koA passes in to encapsulate request and Response, and we can access request and Response, and next is the next asynchronous function koA passes in to process

For each HTTP request, KOA calls the async function registered with app.use() and passes in CTX and next parameters

Example:

const Koa=require('koa');
const app=new Koa();
app.use(async (ctx, next) => {
    console.log('the first 1');
    await next(); // Call the next middleware
    console.log('the first 2');
});
app.use(async (ctx, next) => {
    console.log('the second 1');
    await next(); // Call the next middleware
    console.log('the second 2');
});
app.use(async (ctx, next) => {
    console.log('the third one');
    await next();
    console.log('the third 2');
});
app.listen(3000);

// Print the following result:
/ / the first 1
/ / the second one
/ / the third one
/ / 2. 3
The second 2 / /
/ / the first two
Copy the code

Koa – the router and koa – bodyparser

Koa-router handles URL mapping and facilitates OPERATIONS on urls

Koa – the router to use

const router = require('koa-router') ();Koa / / in the router...// add router middleware:
app.use(router.routes());
Copy the code

Note that the importkoa-routerLast of the statement(a)It’s a function call

By using koA-Router, we can handle more complex URL operations, such as GET requests

// log request URL:
app.use(async (ctx, next) => {
    console.log(`<h1>Hello, ${name}! </h1>`);
    await next();
});

// add url-route:
router.get('/hello/:name'.async (ctx, next) => {
    var name = ctx.params.name; // Ctx.params. name can be used to obtain the URL variable
    ctx.response.body = `<h1>Hello, ${name}! </h1>`;
});
Copy the code

Processing get requests

Router.get (‘/path’, async fn) is used to process get requests

Handling POST requests

Process post requests with router.post(‘/path’, async fn)

Note that the data in the POST request cannot be correctly parsed into the body of the request by the client. In this case, koA-BodyParser should be used to parse the data

Koa – bodyparser use

const router = require('koa-router') ();Koa / / in the router
const bodyParser = require('koa-bodyparser');
app.use(bodyParser()); // Inject bodyParser before router.routes... router.post('/path'.asyncFn)...// add router middleware:
app.use(router.routes());
app.listen(3000);
Copy the code

Note that koA-BodyParser must be registered with the app object before the Router

Routing instance

Extract the routing

To make the directory structure more aesthetically pleasing, all URL handling functions can be extracted

// index.js
var fn_index = async(CTX, next) => {...... };var fn_signin = async(CTX, next) => {...... };module.exports = {
    'GET /': fn_index,
    'POST /signin': fn_signin
};
Copy the code

In terms of obtaining the app.js page, the example code of Liao Xuefeng is slightly complicated as follows

var fs = require('fs') // Introduce the node.js core module fs

Fs.readdirsync synchronously reads the files in the /controllers directory
// The source instance index.js is stored in the /controllers directory
var files = fs.readdirSync(__dirname + '/controllers');
// Source instance note: Sync can be used here because it is only run once at startup and there are no performance issues

// Filter all files with the.js suffix in this directory
var js_files = files.filter((f) = >{
    return f.endsWith('.js');
});

// Loop through all.js files
for (var f of js_files) {
	// Dynamically get the last.js export set in the /controllers directory
    let mapping = require(__dirname + '/controllers/' + f);
    for (var url in mapping) { // Now the mapping is the exports object of each.js file and loops through that object
        if (url.startsWith('GET ')) { // If the object key url already begins with 'GET '
            var path = url.substring(4); // Extract the path part of the key name, where '/'
            router.get(path, mapping[url]);
        } else if (url.startsWith('POST ')) { // If the object key url starts with 'POST '
            var path = url.substring(5); // Extract the path part of the key name, here '/signin'
            router.post(path, mapping[url]);
        } else {
            // Invalid URL:
            console.log(`invalid URL: ${url}`); }}}Copy the code

Fs.readdirsync (path[, options]) Synchronizes the version of fs.readdir()

  • path String | Buffer | URL
  • options String | Object
    • encoding String The default value'utf8'
    • withFileTypes Boolean The default valuefalse
  • Returns < string [] > | < Buffer [] > | < fs. Dirent [] >

The optional options argument can be either a string with a specified encoding or an object with an Encoding attribute, which specifies the character encoding for the filename to be passed to the callback. If encoding is set to ‘buffer’, the file name returned is a buffer object.

__dirname

In addition to modules such as require and exports, each Node.js module contains two special members

  • __dirnameDynamically gets the absolute path to the directory to which the current file module belongs
  • __filenameDynamically gets the absolute path to the current file

str.startsWith(searchString [, position])

The startsWith() method is used to determine whether the current string begins with another given substring, returning true or false depending on the result

  • searchStringThe substring to search for
  • positionSearch for the beginning of the searchString in STR, which defaults to 0, the beginning of the actual string

endsWith()

The () method tests whether a string ends with the specified suffix. Returns true if the character sequence represented by the argument is the suffix of the character sequence represented by this object, false otherwise

stringObject.substring(start,stop)

The substring() method is used to extract the character of a string intermediate between two specified subscripts

  • Start a necessity. A non-negative integer specifying the position in stringObject of the first character of the substring to be extracted

  • The stop is optional. A non-negative integer that is 1 more than the position in stringObject of the last character of the substring to be extracted.

    If omitted, the substring is returned up to the end of the string

Compact entry file (app.js)

Make a copy of the above code, name it Controller.js, and optimize the code as follows

var fs = require('fs') // Introduce the node.js core module fs
const router = require('koa-router') ();Koa / / in the router
The addMapping function takes two arguments
// router koa-router instance
// Mapping all route urls
function addMapping(router, mapping) {
    for (var url in mapping) { // Now the mapping is the exports object of each.js file and loops through that object
        if (url.startsWith('GET ')) { // If the object key url already begins with 'GET '
            var path = url.substring(4); // Extract the path part of the key name, where '/'
            router.get(path, mapping[url]);
        } else if (url.startsWith('POST ')) { // If the object key url starts with 'POST '
            var path = url.substring(5); // Extract the path part of the key name, here '/signin'
            router.post(path, mapping[url]);
        } else {
            console.log(`invalid URL: ${url}`); }}}function addControllers(router, dir) {
    Fs.readdirsync synchronously reads the files in the /controllers directory
	// The source instance index.js is stored in the /controllers directory
    var files = fs.readdirSync(__dirname + '/' + dir);
    // Filter all files with the.js suffix in this directory
    var js_files = files.filter((f) = > {
        return f.endsWith('.js');
    });
    // Loop through all.js files
    for (var f of js_files) {
    	// Dynamically get the last.js export set in the /controllers directory
        let mapping = require(__dirname + '/' + dir + '/' + f);
        // Call the addMapping function and set theaddMapping(router, mapping); }}module.exports = function (dir) {
    let controllers_dir = dir || 'controllers'.// If no arguments are passed, the scan directory defaults to 'controllers'
        router = require('koa-router') ();// Dynamically introduce the KOA-Router component
    addControllers(router, controllers_dir);
    // The router argument is the instantiated router
    // The controllers_dir argument is a path
    return router.routes(); // add router middleware
};
Copy the code

As a result, our code in app.js is simplified again

// Import Controller Middleware:
const controller = require('./controller');

/ / using middleware:
app.use(controller());
Copy the code

The article has been synchronized with my personal blog: “Node Learning Notes first Introduction to Koa”.


Reference:

  • [KOA – Official website of Liao Xuefeng]
  • [Documentation for Node.js V12.13.1]
  • [express中app.use的使用]

This article is published by OpenWrite!