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);