JianghuJS-Project Structure

12002

1. JianghuJS Directory Structure

In JianghuJS, the directory structure follows the eggjs structural specifications, as shown below:

├── app  
│   ├── common  
│   ├── constant  
│   │   ├── constant.js  
│   │   └── error.js  
│   ├── controller  
│   ├── public  
│   ├── schedule  
│   ├── service  
│   └── view  
├── config  
│   ├── config.default.js  
│   ├── config.local.js  
│   ├── config.prod.js  
│   ├── config.unittest.js  
│   └── plugin.js  
├── app.js  
├── jsconfig.json  
├── package.json  
├── sql  
│   └── init.sql  
└── upload  

2. Description of Each Directory

  • app: The main code directory of the application
    • common: Stores common tools, static methods, etc. for the project
    • constant: Stores constant definitions
      • constant.js: Constant definition file
      • error.js: Error message definition file
    • controller: Stores controllers for exposed interfaces
    • public: Static resources directory
    • schedule: Stores scheduled tasks
    • service: Stores the service directory for application protocols
    • view: Stores the directory for pages
  • config: Stores configuration files
    • config.default.js: Default configuration file
    • config.local.js: Configuration file used during npm run dev
    • config.prod.js: Configuration file used during npm run start
    • config.unittest.js: Configuration file used during npm run test
    • plugin.js: Plugin configuration file
  • app.js: The entry file for custom initialization work at startup
  • jsconfig.json: File for configuring syntax checking, intelligent sensing, and other related settings for JavaScript projects
  • package.json: Project dependency and configuration file
  • sql: Stores SQL files
  • init.sql: Initialization SQL file
  • upload: Directory for uploaded files

3. [JianghuJS Core] Middleware - Chained Calls

Middleware is essentially a function that can intercept, process requests, and pass them to the next middleware or route handler function. The use of middleware allows us to break down the request handling process, modularizing the handling logic, which facilitates code reuse and maintenance.

In Egg.js, middleware is passed through the app and ctx objects. For each request, Egg.js passes the ctx object to each middleware function in the order defined and executes their logic. During the execution of middleware, the middleware function can modify the ctx object as needed and decide whether to pass the request to the next middleware or route handler function. This creates a chained request handling process, ultimately yielding the desired result.

In addition to the core idea of chained calls, Egg.js middleware also has the following characteristics:

  • Multiple middleware can be defined, forming an array of middleware.
  • Middleware can be registered through the app object.
  • The execution order of middleware can be controlled by defining the order of middleware.
  • Middleware can share state through the ctx object, facilitating data transfer and processing.
  • Middleware can intercept, modify, and terminate requests as needed.

Let's start by writing a simple gzip middleware to see how middleware is implemented.

// app/middleware/gzip.js  
const isJSON = require('koa-is-json');  
const zlib = require('zlib');  

async function gzip(ctx, next) {  
  await next();  

  // Convert the response body to gzip after subsequent middleware execution  
  let body = ctx.body;  
  if (!body) return;  
  if (isJSON(body)) body = JSON.stringify(body);  

  // Set gzip body and correct the response header  
  const stream = zlib.createGzip();  
  stream.end(body);  
  ctx.body = stream;  
  ctx.set('Content-Encoding', 'gzip');  
}