# 项目生成

koa-generator (opens new window):一个 koa 的项目脚手架工具,初始项目我们就使用它来进行搭建

# 安装脚手架

npm install -g koa-generator
1

# 生成项目 & 安装依赖

koa2  /tmp/foo && cd /tmp/foo
1

Install dependencies:

npm install
1

Rock and Roll

npm start
1

# 目录结构

这里生成的目录全部放在了外面,我们需要把它整理一下

整理成如下格式

同时将bin -> www下面的启动命令目录修改一下

var app = require("../src/app");
1

# 前端模板引擎ejs (opens new window)

ejs 非常简单,感兴趣的自行查看。

# 我们先安装 ejs

npm install ejs
1

在 app.js 中修改使用

app.use(
  views(__dirname + "/views", {
    extension: "ejs",
  }),
);
1
2
3
4
5

# 在 views 中我们写两个页面

index.ejs

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel="stylesheet" href="/stylesheets/style.css" />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>EJS Welcome to <%= title %></p>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11

error.ejs

<h1><%= message %></h1>
<h2><%= error.status %></h2>
<pre><%= error.stack %></pre>
1
2
3

我们在执行启动命令

npm run start
1

页面就显示出来了,

因为这个项目主要是后台的,关于前端的样式,js 我们都不说了,可以直接 copy 即可

# 使用 mysql + sequlize

安装依赖

yarn add mysql2 sequelize
1

# 添加 conf 目录,主要是写配置

添加 db.js

const { isProd } = require("../utils/env");

let REDIS_CONF = {
  port: 6379,
  host: "127.0.0.1",
};

let MYSQL_CONF = {
  host: "localhost",
  user: "root",
  password: "root",
  port: "3306",
  database: "koa2_weibo_db",
};

if (isProd) {
  REDIS_CONF = {
    // 线上的 redis 配置
    port: 6379,
    host: "127.0.0.1",
  };

  MYSQL_CONF = {
    // 线上的 mysql 配置
    host: "localhost",
    user: "root",
    password: "Mysql_2018",
    port: "3306",
    database: "koa2_weibo_db",
  };
}

module.exports = {
  REDIS_CONF,
  MYSQL_CONF,
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

主要是 redis 和 mysql 的配置

# 添加 db 目录主要是 db

这里面主要是数据模型

其中 model 目录下都是 sequelize 的数据模型

seq.js 是 sequelize 的配置

const Sequelize = require("sequelize");
const { MYSQL_CONF } = require("../conf/db");
const { isProd, isTest } = require("../utils/env");

const { host, user, password, database } = MYSQL_CONF;
const conf = {
  host,
  dialect: "mysql",
};

if (isTest) {
  conf.logging = () => {};
}

// 线上环境,使用连接池
if (isProd) {
  conf.pool = {
    max: 5, // 连接池中最大的连接数量
    min: 0, // 最小
    idle: 10000, // 如果一个连接池 10 s 之内没有被使用,则释放
  };
}

const seq = new Sequelize(database, user, password, conf);

module.exports = seq;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 使用 redis 、 koa-redis 、koa-generic-session 做缓存身份信息处理

# 改造 app.js

const Koa = require("koa");
const app = new Koa();
const views = require("koa-views");
const json = require("koa-json");
const onerror = require("koa-onerror");
const bodyparser = require("koa-bodyparser");
const logger = require("koa-logger");
const koaStatic = require("koa-static");
const session = require("koa-generic-session");
const redisStore = require("koa-redis");

//配置常量
const { SESSION_SECRET_KEY } = require("./conf/secretKeys");
const { REDIS_CONF } = require("./conf/db");
const { isProd } = require("./utils/env");
//配置常量end

const index = require("./routes/index");
const users = require("./routes/users");

//路由
const errorViewRouter = require("./routes/view/error");
// error handler
let onerrorConf = {};
if (isProd) {
  onerrorConf = {
    redirect: "/error",
  };
}
onerror(app);

// middlewares
app.use(
  bodyparser({
    enableTypes: ["json", "form", "text"],
  }),
);
app.use(json());
app.use(logger());
app.use(koaStatic(__dirname + "/public"));

app.use(
  views(__dirname + "/views", {
    extension: "ejs",
  }),
);
//middlewares -end

// session 配置
app.keys = [SESSION_SECRET_KEY];
app.use(
  session({
    key: "weibo.sid", // cookie name 默认是 `koa.sid`
    prefix: "weibo:sess:", // redis key 的前缀,默认是 `koa:sess:`
    cookie: {
      path: "/",
      httpOnly: true,
      maxAge: 24 * 60 * 60 * 1000, // 单位 ms
    },
    store: redisStore({
      all: `${REDIS_CONF.host}:${REDIS_CONF.port}`,
    }),
  }),
);
// session 配置end

// routes
app.use(index.routes(), index.allowedMethods());
app.use(users.routes(), users.allowedMethods());

app.use(errorViewRouter.routes(), errorViewRouter.allowedMethods()); // 404 路由注册到最后面
// error-handling
app.on("error", (err, ctx) => {
  console.error("server error", err, ctx);
});

module.exports = app;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

此时我们就能在路由中的ctx.session中获取到我们的缓存信息了。

下面就是创建 controller 层,services 层。

# 整体项目架构