{"id":26187479,"url":"https://github.com/localsummer/koa2-ts-boilerplate","last_synced_at":"2026-04-07T22:31:03.716Z","repository":{"id":40761773,"uuid":"276338114","full_name":"localSummer/koa2-ts-boilerplate","owner":"localSummer","description":"koa2 + typescript 模板","archived":false,"fork":false,"pushed_at":"2023-01-06T10:36:52.000Z","size":858,"stargazers_count":1,"open_issues_count":20,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-26T10:49:55.978Z","etag":null,"topics":["gulp","jest","koa2","log4js","mysql","pm2","sequelize-cli","sequelize-orm","typescript"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/localSummer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-01T09:43:22.000Z","updated_at":"2021-01-07T12:08:21.000Z","dependencies_parsed_at":"2023-02-05T21:47:16.056Z","dependency_job_id":null,"html_url":"https://github.com/localSummer/koa2-ts-boilerplate","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/localSummer/koa2-ts-boilerplate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localSummer%2Fkoa2-ts-boilerplate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localSummer%2Fkoa2-ts-boilerplate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localSummer%2Fkoa2-ts-boilerplate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localSummer%2Fkoa2-ts-boilerplate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/localSummer","download_url":"https://codeload.github.com/localSummer/koa2-ts-boilerplate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/localSummer%2Fkoa2-ts-boilerplate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31532141,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"ssl_error","status_checked_at":"2026-04-07T16:28:06.951Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gulp","jest","koa2","log4js","mysql","pm2","sequelize-cli","sequelize-orm","typescript"],"created_at":"2025-03-11T23:50:02.559Z","updated_at":"2026-04-07T22:31:03.699Z","avatar_url":"https://github.com/localSummer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"### 技术栈\nkoa2 + typescript + sequelize + sequelize-cli + mysql + jest + log4js + pm2 + gulp\n\n### 功能支持\n1. typescript\n2. sequelize orm\n3. log4js 日志处理\n4. @koa/multer 文件上传\n5. schema-typed 请求参数校验\n6. ctx 自定义属性（及类型）扩展，如 `ctx.success` `ctx.error` `ctx.logger` [koa2+ts中为Context扩展自定义属性](https://blog.csdn.net/roamingcode/article/details/107084933)\n7. jest 测试\n\n\u003e 注意：所有自定义中间件在 `next` 调用时，需使用右侧格式 `await next()`，否则在 `controller` 中操作数据库会引发 `ctx.body` 数据丢失问题\n\n### 数据库操作\n1. `npx sequelize db:create --charset \"utf8mb4\" --collate \"utf8mb4_general_ci\"` 同步数据库\n2. `npx sequelize db:migrate` 同步表\n\n### 项目启动\n#### dev 模式\n1. `npm run compile` 编译后 nodemon 重启服务 或 `gulp-compile` 编译后延迟 `200ms（可配置）` nodemon 重启服务\n2. `npm run dev`\n\n#### prd模式\n1. `npm run build` 打包但代码未进行压缩 或 `npm run gulp-build`  打包并压缩\n2. `npm run prd`\n\n#### scripts\n```javascript\n\"scripts\": {\n  \"compile\": \"tsc --project tsconfig.json -w\",\n  \"dev\": \"cross-env NODE_ENV=development nodemon bin/www\",\n  \"build\": \"tsc --project tsconfig.json\",\n  \"prd\": \"cross-env NODE_ENV=production pm2 start bin/www\",\n  \"clear\": \"rm -r dist\",\n  \"eslint\": \"eslint src --ext .ts\",\n  \"gulp-compile\": \"gulp dev\",\n  \"gulp-build\": \"gulp build\",\n  \"test\": \"jest --passWithNoTests --updateSnapshot\",\n  \"test:watch\": \"jest --coverage --watch\",\n  \"test:prod\": \"npm run eslint \u0026\u0026 npm run test -- --no-cache\"\n},\n```\n\n#### 目录结构\n```\n|-- koa2-ts\n    |-- .eslintignore\n    |-- .eslintrc.js\n    |-- .gitignore\n    |-- .sequelizerc\n    |-- LICENCE\n    |-- README.md\n    |-- gulpfile.js\n    |-- jest.config.js\n    |-- package-lock.json\n    |-- package.json\n    |-- prettier.config.js\n    |-- tsconfig.json\n    |-- bin\n    |   |-- www\n    |-- config\n    |   |-- constant.js\n    |   |-- db.json\n    |   |-- jest\n    |       |-- cssTransform.js\n    |       |-- fileTransform.js\n    |-- coverage\n    |-- db\n    |   |-- migrations\n    |   |   |-- 20200702123744-create-user.js\n    |   |-- seeders\n    |-- dist\n    |-- logs\n    |   |-- access.log.-2020-07-04.log\n    |   |-- application.log.-2020-07-04.log\n    |-- public\n    |   |-- style.css\n    |-- src\n    |   |-- app.ts\n    |   |-- global.d.ts\n    |   |-- __test__\n    |   |   |-- format.test.ts\n    |   |-- controllers\n    |   |   |-- userController.ts\n    |   |-- middlewares\n    |   |   |-- logger.ts\n    |   |   |-- response.ts\n    |   |   |-- upload.ts\n    |   |   |-- validator.ts\n    |   |-- models\n    |   |   |-- connection.ts\n    |   |   |-- index.ts\n    |   |   |-- user.ts\n    |   |-- routes\n    |   |   |-- index.ts\n    |   |-- rules\n    |   |   |-- login.ts\n    |   |-- services\n    |   |   |-- userService.ts\n    |   |-- types\n    |   |   |-- index.ts\n    |   |-- utils\n    |       |-- helper.ts\n    |       |-- log4.ts\n    |-- uploads\n        |-- 2020-07-04\n            |-- 1593850667585.jpg\n```\n\n#### app.ts\n\n```javascript\nimport Koa from 'koa';\nimport onerror from 'koa-onerror';\nimport cors from 'koa2-cors';\nimport bodyparser from 'koa-bodyparser';\nimport json from 'koa-json';\nimport koaLogger from 'koa-logger';\nimport koaStatic from 'koa-static';\nimport path from 'path';\n\nimport koaResponse from './middlewares/response';\nimport logger from './middlewares/logger';\nimport { systemLogger, defaultLogger, accessLogger } from './utils/log4';\nimport index from './routes';\nimport Helper from './utils/helper';\n\nconst app = new Koa();\n\n// 错误处理\nonerror(app);\n\n// 中间件\napp.use(cors());\napp.use(\n  bodyparser({\n    enableTypes: ['json', 'form', 'text']\n  })\n);\napp.use(json());\napp.use(koaLogger());\n// 公共资源访问\napp.use(koaStatic(path.resolve(__dirname, '../public')));\n// 用户上传资源访问\napp.use(koaStatic(path.resolve(__dirname, '../uploads')));\n\n// logger 控制台请求输出\napp.use(async (ctx, next) =\u003e {\n  const start = Date.now();\n  await next();\n  const ms = Date.now() - start;\n  console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);\n  accessLogger.info(Helper.logFormat(ctx, ms));\n});\n\n// 自定义控制台输出日志\napp.use(logger(defaultLogger));\napp.use(koaResponse);\n\n// 路由\napp.use(index.routes());\napp.use(index.allowedMethods());\n\n// error-handling\napp.on('error', (err: Error, ctx: Koa.Context) =\u003e {\n  console.error('server error', err, ctx);\n  // 系统日志输出到文件\n  systemLogger.error(err);\n});\n\nexport default app;\n\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalsummer%2Fkoa2-ts-boilerplate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flocalsummer%2Fkoa2-ts-boilerplate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flocalsummer%2Fkoa2-ts-boilerplate/lists"}