Koa basic usage and configuration development hot load / webpack debugging

Posted by newburcj on Mon, 24 Jan 2022 18:25:53 +0100

Koa Foundation

introduce

Core concept


principle

characteristic

Basic implementation

npm init -y

npm install --save koa

index.js

root directory

const Koa = require("koa");
const app = new Koa();

app.use(async (ctx) => {
  ctx.body = "hello,koa";
});

app.listen(3000);

kao-Router

npm install -S koa-router

use

const Koa = require("koa");
const app = new Koa();

const Router = require("koa-router");
const router = new Router();

router.get("/", (ctx) => {
  console.log(ctx);
  console.log(ctx.request);
  ctx.body = "hello,koa";
});

router.get("/api", (ctx) => {
  console.log(ctx);
  console.log(ctx.request);
  ctx.body = "hello,api";
});

app
  .use(router.routes())
  // Intercepts all requests that are not and returns 4xx 5xx error
  .use(router.allowedMethods());

app.listen(3000);

next()




Execute the following statements according to use

async await

router.get("/async", async (ctx) => {
  let result = await new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("hello world 2s later");
    }, 2000);
  });
  ctx.body = result;
});

Koa develops RESTful interfaces

npm install -S koa-router koa-body @koa/cors

.prefix

Define the prefix of the route and add the interceptor
Block access if you do not have permission to access the prefix route



After adding api

koa-body

koa data body part escape, escape POST JSON format

post

const cors = require("@koa/cors");
const koaBody = require("koa-body");

...

router.post("/post", (ctx) => {
  let { body } = ctx.request;
  console.log(body);
  console.log(ctx.request);
  // ctx.body is equivalent to CTX response
  ctx.body = {
    ...body,
  };
});

...


get params

router.get("/api", (ctx) => {
  // Get params in get request
  const params = ctx.request.query;
  console.log(params);
  // For example, the transmitted data name: "zero", age: "18"
  console.log(params.name, params.age);
  ctx.body = {
    name: params.name,
    age: params.age,
  };
});



@koa/cors

Solve cross domain problems

koa-json

npm install -S koa-json

const json = require("koa-json")

app
  .use(koaBody())
  .use(cors())
  .use(json({ pretty: false, param: "pretty" }))

If there is no tool, it will also be formatted

Mode II

Koa routing advanced configuration

Development directory structure

npm install koa koa-router koa-body @koa/cors koa-json -S

koa-combine-routers

Merge all routes

npm install koa-combine-routers

src

api

a.js
module.exports = function (ctx) {
  ctx.body = {
    message: "hello from a",
  };
};

b.js
// function a(ctx) {
//   ctx.body = {
//     message: "hello from b",
//   };
// }

// module.exports = {
//   a,
// };

module.exports = function (ctx) {
  ctx.body = {
    message: "hello from b",
  };
};

routes

aRouter.js
const Router = require("koa-router");
const a = require("../api/a");

const router = new Router();

router.get("/a", a);

module.exports = router;

bRouter.js
const Router = require("koa-router");
const b = require("../api/b");

const router = new Router();

router.get("/b", b);

module.exports = router;

routes.js
const combineRoutes = require("koa-combine-routers");

const arouters = require("./aRouter");
const brouters = require("./bRouter");

module.exports = combineRoutes(arouters, brouters);

index.js

const koa = require("koa");
const app = new koa();

const router = require("./routes/routes");

app.use(router());
app.listen(3000);


advantage

The main functions and path management in routes
The api is full of function code. The actual business processes the request and responds to the response

kao security header processing

koa-helemt

https://www.npmjs.com/package/koa-helmet
Added a safe head

npm i koa-helmet -S

index.js

const koa = require("koa");
const app = new koa();
const helmet = require("koa-helmet");

const router = require("./routes/routes");

app.use(helmet());
app.use(router());
app.listen(3000);

koa-static

Static file service

npm install koa-static -S

index.js

const koa = require("koa");
const path = require("path");
const app = new koa();
const helmet = require("koa-helmet");
const statics = require("koa-static");

const router = require("./routes/routes");

app.use(helmet());
app.use(statics(path.join(__dirname, "../public")));
app.use(router());
app.listen(3000);

node src/index.js


koa configuration development hot load

ES6 syntax support & webpack configuration

nodemon

Monitoring js changes and restarting services
https://www.npmjs.com/package/nodemon

npm install -D nodemon

npx nodemon --version

npx nodemon src/index.js



package.json

  "scripts": {
    "start": "nodemon src/index.js"
  },


webpack

npm install -D webpack webpack-cli

webpack plugin

npm install -D clean-webpack-plugin webpack-node-externals @babel/core @babel/node @babel/preset-env babel-loader cross-env
node: {
    console: true,
    global: true,
    process: true,
    Buffer: true,
    __filename: true,
    __dirname: true,
    setImmediate: true,
    path: true,
  },

webpack.config.js

root directory

const path = require("path");
const nodeExcternals = require("webpack-node-externals");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

const webpackconfig = {
  target: "node",
  mode: "development",
  entry: {
    server: path.join(__dirname, "src/index.js"),
  },
  output: {
    filename: "[name].bundle.js",
    path: path.join(__dirname, "./dist"),
  },
  devtool: "eval-source-map",
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: "babel-loader",
        },
        exclude: [path.join(__dirname, "/node_modules")],
      },
    ],
  },
  externals: [nodeExcternals()],
  plugins: [new CleanWebpackPlugin()],
};

module.exports = webpackconfig;

.babelrc

root directory

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "current"
        }
      }
    ]
  ]
}

package.json

  "scripts": {
    "start": "nodemon src/index.js"
  },

npx webpack

Use ES6 syntax

Rewrite Src / index js

// const koa = require("koa");
// const path = require("path");

import koa from "koa";
import path from "path";
import helmet from "koa-helmet";
import statics from "koa-static";
import router from "./routes/routes";

const app = new koa();
// const helmet = require("koa-helmet");
// const statics = require("koa-static");

// const router = require("./routes/routes");

app.use(helmet());
app.use(statics(path.join(__dirname, "../public")));
app.use(router());
app.listen(3000);

npx babel-node src/index.js

npx nodemon --exec babel-node src/index.js

package.json

  "scripts": {
    "start": "npx nodemon --exec babel-node src/index.js"
  },

Debug webpack

Mode 1

npx node --inspect-brk .\node_modules.bin\webpack --inline --progress

Open chrome chrome://inspect/#devices

vscode debugging

Add debug

Add configuration

  • ${workspaceFolder} represents the project engineering directory

runtimeArgs

Specify the application of babel
nodemon implements the commJs specification

{
  // Use IntelliSense to understand related properties.
  // Hover to view the description of an existing property.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "nodemon",
      "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/nodemon",
      "program": "${workspaceFolder}/src/index.js",
      "restart": true,
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "skipFiles": ["<node_internals>/**"],
      "runtimeArgs": ["--exec", "babel-node"]
    }
  ]
}

function


Optimize webpack configuration

The front can not meet the production requirements
No koabody
Just webpack during development

npm-check-updates

  • Check whether the npm dependency package has a new version

npm install -g npm-check-update

ncu

ncu --help

  • Check for version updates

nuc -u

Update instruction

rm -rf node_modules/

Delete node_modules or right-click to delete node directly_ modules

npm i

Reinstall

koa-compose

  • Middleware integrating koa

npm install koa-compose

Using koa compose

// const koa = require("koa");
// const path = require("path");

import koa from "koa";
import path from "path";
import helmet from "koa-helmet";
import statics from "koa-static";
import router from "./routes/routes";
// Optimized addition
import koaBody from "koa-body";
import jsonutil from "koa-json";
import cors from "@koa/cors";
import compose from "koa-compose";

const app = new koa();
// const helmet = require("koa-helmet");
// const statics = require("koa-static");

// const router = require("./routes/routes");

// app.use(helmet());
// app.use(statics(path.join(__dirname, "../public")));
// app.use(router());

// Integrating middleware with koa compose
const middleware = compose([
  koaBody(),
  statics(path.join(__dirname, "../public")),
  cors(),
  jsonutil({ pretty: false, param: "pretty" }),
  helmet(),
]);

app.use(middleware);
app.use(router());
app.listen(3000);

Configure webpack

Create config folder from root directory

webpack.config.base.js

const path = require("path");
const webpack = require("webpack");
const nodeExcternals = require("webpack-node-externals");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

// debugger;

const webpackconfig = {
  target: "node",
  entry: {
    server: path.join(__dirname, "src/index.js"),
  },
  output: {
    filename: "[name].bundle.js",
    path: path.join(__dirname, "./dist"),
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: "babel-loader",
        },
        exclude: [path.join(__dirname, "/node_modules")],
      },
    ],
  },
  externals: [nodeExcternals()],
  plugins: [
    new CleanWebpackPlugin(),
    new webpack.DefinePlugins({
      "process.env": {
        NODE_ENV:
          process.env.NODE_ENV === "production" ||
          process.env.NODE_ENV === "prod"
            ? "'production'"
            : "'development'",
      },
    }),
  ],
};

module.exports = webpackconfig;


webpack.config.dev.js

const webpackMerge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.config.base");

const webpackConfig = webpackMerge(baseWebpackConfig, {
  mode: "development",
  devtool: "eval-source-map",
  stats: { children: false },
});

module.exports = webpackConfig;

webpack.config.prod.js

const webpackMerge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.config.base");

const TerserWebpackPlugin = require("terser-webpack-plugin");

const webpackConfig = webpackMerge(baseWebpackConfig, {
  mode: "production",
  stats: { children: false, warnings: false },
  optimization: {
    minimizer: [
      new TerserWebpackPlugin({
        terserOptions: {
          warnings: false,
          compress: {
            warnings: false,
            // Comment out console
            drop_console: false,
            dead_code: true,
            drop_debugger: true,
          },
          output: {
            comments: false,
            beautify: false,
          },
          mangle: true,
        },
        parallel: true,
        sourceMap: false,
      }),
    ],
  },
});

module.exports = webpackConfig;

webpack-merge

Merge webpack configuration

npm i webpack-merge -D

terser-webpack-plugin

npm install terser-webpack-plugin --save-dev

TerserWebpackPlugin
Compress JS code
https://v4.webpack.docschina.org/plugins/terser-webpack-plugin/

webpack packaging configuration optimization (production requirements)

SplitChunksPlugin

webpack.config.prod.js

const webpackMerge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.config.base");

const TerserWebpackPlugin = require("terser-webpack-plugin");

const webpackConfig = webpackMerge(baseWebpackConfig, {
  mode: "production",
  stats: { children: false, warnings: false },
  optimization: {
    minimizer: [
      new TerserWebpackPlugin({
        terserOptions: {
          warnings: false,
          compress: {
            warnings: false,
            // Comment out console
            drop_console: false,
            dead_code: true,
            drop_debugger: true,
          },
          output: {
            comments: false,
            beautify: false,
          },
          mangle: true,
        },
        parallel: true,
        sourceMap: false,
      }),
    ],
    splitChunks: {
      cacheGroups: {
        commons: {
          name: "commons",
          chunks: "initial",
          minChunks: 3,
          enforce: true,
        },
      },
    },
  },
});

module.exports = webpackConfig;

package.json

Configure script

"build": "cross-env NODE_ENV=prod webpack --config config/webpack.config.prod.js"

Because the configuration of webpack is not under the root directory

Solve the path problem

Under config, create utils JS file

const path = require("path");

exports.resolve = function resolve(dir) {
  return path.join(__dirname, "..", dir);
};

exports.APP_PATH = exports.resolve("src");
exports.DIST_PATH = exports.resolve("dist");


Delete webpack config. js
Modify webpack config. base. js

const path = require("path");
// webpack packaging configuration optimization new (address error reporting)
const utils = require("./utils");
const webpack = require("webpack");
const nodeExcternals = require("webpack-node-externals");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

// debugger;

const webpackconfig = {
  target: "node",
  entry: {
    // server: path.join(__dirname, "src/index.js"),
    server: path.join(utils.APP_PATH, "index.js"),
  },
  output: {
    filename: "[name].bundle.js",
    // path: path.join(__dirname, "./dist"),
    path: utils.DIST_PATH,
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: "babel-loader",
        },
        exclude: [path.join(__dirname, "/node_modules")],
      },
    ],
  },
  externals: [nodeExcternals()],
  plugins: [
    new CleanWebpackPlugin(),
    new webpack.DefinePlugin({
      "process.env": {
        NODE_ENV:
          process.env.NODE_ENV === "production" ||
          process.env.NODE_ENV === "prod"
            ? "'production'"
            : "'development'",
      },
    }),
  ],
};

module.exports = webpackconfig;

npm run build


npm install -D rimraf

package.json

For all script configurations, note that clean needs to download the rimraf package

    "start": "nodemon --exec babel-node src/index.js",
    "webpack:debug": "node --inspect-brk ./node_modules/.bin/webpack --inline --progress",
    "build": "cross-env NODE_ENV=prod webpack --config config/webpack.config.prod.js",
    "dev": "cross-env NODE_ENV=dev nodemon --exec babel-node --inspect ./src/index.js",
    "clean": "rimraf dist"

Routing correlation

Red delete green add

demoController.js

class DemoController {
  constructor() {}
  async demo(ctx) {
    ctx.body = {
      msg: "body message",
    };
  }
}

export default new DemoController();

demoRouter.js

import Router from "koa-router";
import demoController from "../api/demoController";

const router = new Router();

router.get("/demo", demoController.demo);

module.exports = router;

routes.js

// const combineRoutes = require("koa-combine-routers");
import combineRoutes from "koa-combine-routers";
import demoRouter from "./demoRouter";

// const arouters = require("./aRouter");
// const brouters = require("./bRouter");

// module.exports = combineRoutes(arouters, brouters);
export default combineRoutes(demoRouter);

npm run dev

koa-compress

npm install koa-compress -S

index.js

// const koa = require("koa");
// const path = require("path");

import koa from "koa";
import path from "path";
import helmet from "koa-helmet";
import statics from "koa-static";
import router from "./routes/routes";
// Optimized addition
import koaBody from "koa-body";
import jsonutil from "koa-json";
import cors from "@koa/cors";
import compose from "koa-compose";
import compress from "koa-compress";

const app = new koa();

const isDevMode = process.env.NODE_ENV === "production" ? false : true;

// Integrating middleware with koa compose
const middleware = compose([
  koaBody(),
  statics(path.join(__dirname, "../public")),
  cors(),
  jsonutil({ pretty: false, param: "pretty" }),
  helmet(),
]);

if (!isDevMode) {
  app.use(compress());
}

app.use(middleware);
app.use(router());
app.listen(3000);

Topics: Webpack koa