1.0.2
This commit is contained in:
parent
a6fd705801
commit
118b8f9d3a
257
README.md
257
README.md
@ -1,5 +1,4 @@
|
|||||||
Koa2 RESTful API 服务器脚手架
|
# Koa2 RESTful API 服务器脚手架
|
||||||
=============================
|
|
||||||
|
|
||||||
这是一个基于 Koa2 的轻量级 RESTful API Server 脚手架,支持 ES6。
|
这是一个基于 Koa2 的轻量级 RESTful API Server 脚手架,支持 ES6。
|
||||||
|
|
||||||
@ -13,70 +12,65 @@ Koa2 RESTful API 服务器脚手架
|
|||||||
|
|
||||||
因此脚手架主要提供 RESTful API,故暂时不考虑前端静态资源处理,只提供静态资源访问的基本方法便于访问用户上传到服务器的图片等资源。基本目录结构与 vue-cli 保持一致,可配合 React、AngularJS、Vue.js 等前端框架使用。在 Cordova/PhoneGap、Electron 中使用时需要开启跨域功能。
|
因此脚手架主要提供 RESTful API,故暂时不考虑前端静态资源处理,只提供静态资源访问的基本方法便于访问用户上传到服务器的图片等资源。基本目录结构与 vue-cli 保持一致,可配合 React、AngularJS、Vue.js 等前端框架使用。在 Cordova/PhoneGap、Electron 中使用时需要开启跨域功能。
|
||||||
|
|
||||||
**免责声明:** 此脚手架仅为方便开发提供基础环境,任何人或组织均可随意克隆使用,使用引入的框架需遵循原作者规定的相关协议(部分框架列表及来源地址在下方)。采用此脚手架产生的任何后果请自行承担,本人不对此脚手架负任何法律责任,使用即代表同意此条。
|
**免责声明:** 此脚手架仅为方便开发提供基础环境,任何人或组织均可随意克隆使用,使用引入的框架需遵循原作者规定的相关协议(部分框架列表及来源地址在下方)。项目维护者均不对采用此脚手架产生的任何后果负责。
|
||||||
|
|
||||||
目前暂未加入软件测试模块,下一个版本会加入该功能并提供集成方案。建议自行集成jest。
|
|
||||||
|
|
||||||
**基于 Vue 2,Webpack 4,Koa 2 的 SSR 脚手架:**[https://github.com/yi-ge/Vue-SSR-Koa2-Scaffold](https://github.com/yi-ge/Vue-SSR-Koa2-Scaffold)。
|
**基于 Vue 2,Webpack 4,Koa 2 的 SSR 脚手架:**[https://github.com/yi-ge/Vue-SSR-Koa2-Scaffold](https://github.com/yi-ge/Vue-SSR-Koa2-Scaffold)。
|
||||||
|
|
||||||
开发使用说明
|
## 开发使用说明
|
||||||
------------
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git clone https://github.com/yi-ge/koa2-API-scaffold.git
|
git clone https://github.com/yi-ge/koa2-API-scaffold.git
|
||||||
|
|
||||||
$ cd mv koa2-API-scaffold
|
cd mv koa2-API-scaffold
|
||||||
$ npm install
|
npm install
|
||||||
$ npm run dev # 可执行npm start跳过ESlint检查。
|
npm run dev # 可执行npm start跳过ESlint检查。
|
||||||
```
|
```
|
||||||
|
|
||||||
访问: http://127.0.0.1:3000/
|
访问: http://127.0.0.1:3000/
|
||||||
|
|
||||||
调试说明
|
## 调试说明
|
||||||
--------
|
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ npm run dev --debug
|
npm run dev --debug
|
||||||
|
|
||||||
Or
|
Or
|
||||||
|
|
||||||
$ npm start --debug
|
npm start --debug
|
||||||
```
|
```
|
||||||
|
|
||||||
支持 Node.js 原生调试功能:https://nodejs.org/api/debugger.html
|
支持 Node.js 原生调试功能:https://nodejs.org/api/debugger.html
|
||||||
|
|
||||||
开发环境部署
|
## 开发环境部署
|
||||||
------------
|
|
||||||
|
|
||||||
生成 node 直接可以执行的代码到 dist 目录:
|
生成 node 直接可以执行的代码到 dist 目录:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ npm run production # 生产模式运行
|
npm run production # 生产模式运行
|
||||||
|
|
||||||
Or
|
# Or
|
||||||
|
|
||||||
$ node dist/app.js
|
node dist/app.js
|
||||||
```
|
```
|
||||||
|
|
||||||
### PM2 部署说明
|
### PM2 部署说明
|
||||||
|
|
||||||
提供了 PM2 部署 RESTful API Server 的示例配置,位于“pm2.js”文件中。
|
提供了 PM2 部署 RESTful API Server 的示例配置,位于“pm2.js”文件中。
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ pm2 start pm2.js
|
pm2 start pm2.js
|
||||||
```
|
```
|
||||||
|
|
||||||
PM2 配合 Docker 部署说明: http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs/
|
PM2 配合 Docker 部署说明: http://pm2.keymetrics.io/docs/usage/docker-pm2-nodejs/
|
||||||
|
|
||||||
### Docker 部署说明
|
### Docker 部署说明
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ docker pull node
|
docker pull node
|
||||||
$ docker run -itd --name RESTfulAPI -v `pwd`:/usr/src/app -w /usr/src/app node node ./dist/app.js
|
docker run -itd --name RESTfulAPI -v `pwd`:/usr/src/app -w /usr/src/app node node ./dist/app.js
|
||||||
```
|
```
|
||||||
|
|
||||||
通过'docker ps'查看是否运行成功及运行状态
|
通过'docker ps'查看是否运行成功及运行状态
|
||||||
@ -85,26 +79,26 @@ $ docker run -itd --name RESTfulAPI -v `pwd`:/usr/src/app -w /usr/src/app node n
|
|||||||
|
|
||||||
有时候为了简单,我们也这样做:
|
有时候为了简单,我们也这样做:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ nohup node ./dist/app.js > logs/out.log &
|
nohup node ./dist/app.js > logs/out.log &
|
||||||
```
|
```
|
||||||
|
|
||||||
查看运行状态(如果有'node app.js'出现则说明正在后台运行):
|
查看运行状态(如果有'node app.js'出现则说明正在后台运行):
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ ps aux|grep app.js
|
ps aux|grep app.js
|
||||||
```
|
```
|
||||||
|
|
||||||
查看运行日志
|
查看运行日志
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ cat logs/out.log
|
cat logs/out.log
|
||||||
```
|
```
|
||||||
|
|
||||||
监控运行状态
|
监控运行状态
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ tail -f logs/out.log
|
tail -f logs/out.log
|
||||||
```
|
```
|
||||||
|
|
||||||
### 配合 Vue-cli 部署说明
|
### 配合 Vue-cli 部署说明
|
||||||
@ -113,7 +107,7 @@ Vue-cli(Vue2)运行'npm run build'后会在'dist'目录中生成所有静态
|
|||||||
|
|
||||||
推荐的 Nginx 配置文件:
|
推荐的 Nginx 配置文件:
|
||||||
|
|
||||||
```
|
```text
|
||||||
server
|
server
|
||||||
{
|
{
|
||||||
listen 80;
|
listen 80;
|
||||||
@ -143,31 +137,33 @@ server
|
|||||||
|
|
||||||
Docker 中 Nginx 运行命令(将上述配置文件任意命名放置于 nginx_config 目录中即可):
|
Docker 中 Nginx 运行命令(将上述配置文件任意命名放置于 nginx_config 目录中即可):
|
||||||
|
|
||||||
```
|
```bash
|
||||||
$ docker run -itd -p 80:80 -p 443:443 -v `pwd`/nginx_config:/etc/nginx/conf.d nginx
|
docker run -itd -p 80:80 -p 443:443 -v `pwd`/nginx_config:/etc/nginx/conf.d nginx
|
||||||
```
|
```
|
||||||
|
|
||||||
### 关于 Token 使用的特别说明(JWT 身份认证)
|
### 关于 Token 使用的特别说明(JWT 身份认证)
|
||||||
|
|
||||||
`src\app.js`目录中有一行代码:
|
`src\app.js`目录中有一行代码:
|
||||||
```.use(jwt({ secret: publicKey }).unless({ path: [/^\/public|\/user\/login|\/assets/] }))```
|
`.use(jwt({ secret: publicKey }).unless({ path: [/^\/public|\/user\/login|\/assets/] }))`
|
||||||
|
|
||||||
在 path 里面的开头路径则不进行身份认证,否则都将进行 鉴权。
|
在 path 里面的开头路径则不进行身份认证,否则都将进行 鉴权。
|
||||||
|
|
||||||
前端处理方案:
|
前端处理方案:
|
||||||
```
|
|
||||||
import axios from "axios"
|
|
||||||
import { getToken } from "./tool"
|
|
||||||
|
|
||||||
const DevBaseUrl = "http://127.0.0.1:8080"
|
```javascript
|
||||||
const ProdBashUrl = "https://xxx.xxx"
|
import axios from 'axios'
|
||||||
|
import { getToken } from './tool'
|
||||||
|
|
||||||
|
const DevBaseUrl = 'http://127.0.0.1:8080'
|
||||||
|
const ProdBashUrl = 'https://xxx.xxx'
|
||||||
|
|
||||||
let config = {
|
let config = {
|
||||||
baseURL: process.env.NODE_ENV !== "production" ? DevBaseUrl : ProdBashUrl // 配置API接口地址
|
baseURL: process.env.NODE_ENV !== 'production' ? DevBaseUrl : ProdBashUrl // 配置API接口地址
|
||||||
}
|
}
|
||||||
|
|
||||||
let token = getToken()
|
let token = getToken()
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers = { Authorization: "Bearer " + token }
|
config.headers = { Authorization: 'Bearer ' + token }
|
||||||
}
|
}
|
||||||
|
|
||||||
let request = axios.create(config)
|
let request = axios.create(config)
|
||||||
@ -196,94 +192,92 @@ export default request
|
|||||||
```
|
```
|
||||||
|
|
||||||
`tool.js`文件
|
`tool.js`文件
|
||||||
```
|
|
||||||
|
|
||||||
|
```javascript
|
||||||
// 写 cookies
|
// 写 cookies
|
||||||
export let setCookie = function setCookie(name, value, time) {
|
export let setCookie = function setCookie(name, value, time) {
|
||||||
if (time) {
|
if (time) {
|
||||||
let strsec = getsec(time);
|
let strsec = getsec(time)
|
||||||
let exp = new Date();
|
let exp = new Date()
|
||||||
exp.setTime(exp.getTime() + parseInt(strsec));
|
exp.setTime(exp.getTime() + parseInt(strsec))
|
||||||
document.cookie = name +
|
document.cookie =
|
||||||
"=" +
|
name + '=' + escape(value) + ';expires=' + exp.toGMTString()
|
||||||
escape(value) +
|
|
||||||
";expires=" +
|
|
||||||
exp.toGMTString();
|
|
||||||
} else {
|
} else {
|
||||||
document.cookie = name + "=" + escape(value);
|
document.cookie = name + '=' + escape(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 读 cookies
|
// 读 cookies
|
||||||
export let getCookie = function(name) {
|
export let getCookie = function(name) {
|
||||||
let reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
|
let reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)')
|
||||||
let arr = document.cookie.match(reg);
|
let arr = document.cookie.match(reg)
|
||||||
return arr ? unescape(arr[2]) : null;
|
return arr ? unescape(arr[2]) : null
|
||||||
};
|
}
|
||||||
|
|
||||||
// 删 cookies
|
// 删 cookies
|
||||||
export let delCookie = function(name) {
|
export let delCookie = function(name) {
|
||||||
var exp = new Date();
|
var exp = new Date()
|
||||||
exp.setTime(exp.getTime() - 1);
|
exp.setTime(exp.getTime() - 1)
|
||||||
var cval = getCookie(name);
|
var cval = getCookie(name)
|
||||||
if (cval != null) {
|
if (cval != null) {
|
||||||
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
|
document.cookie = name + '=' + cval + ';expires=' + exp.toGMTString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 获取Token
|
// 获取Token
|
||||||
export let getToken = function() {
|
export let getToken = function() {
|
||||||
if (window.sessionStorage && window.sessionStorage.Bearer) {
|
if (window.sessionStorage && window.sessionStorage.Bearer) {
|
||||||
return window.sessionStorage.Bearer;
|
return window.sessionStorage.Bearer
|
||||||
} else if (window.localStorage && window.localStorage.Bearer) {
|
} else if (window.localStorage && window.localStorage.Bearer) {
|
||||||
return window.localStorage.Bearer;
|
return window.localStorage.Bearer
|
||||||
} else if (window.document.cookie) {
|
} else if (window.document.cookie) {
|
||||||
return getCookie("Bearer");
|
return getCookie('Bearer')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 设置Token
|
// 设置Token
|
||||||
export let setToken = function(token, rememberTime) {
|
export let setToken = function(token, rememberTime) {
|
||||||
if (window.sessionStorage) {
|
if (window.sessionStorage) {
|
||||||
window.sessionStorage.Bearer = token;
|
window.sessionStorage.Bearer = token
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rememberTime && window.localStorage) || !window.sessionStorage) {
|
if ((rememberTime && window.localStorage) || !window.sessionStorage) {
|
||||||
window.localStorage.Bearer = token;
|
window.localStorage.Bearer = token
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
window.document.cookie && !window.sessionStorage && !window.localStorage
|
window.document.cookie &&
|
||||||
|
!window.sessionStorage &&
|
||||||
|
!window.localStorage
|
||||||
) {
|
) {
|
||||||
if (rememberTime) {
|
if (rememberTime) {
|
||||||
setCookie("Bearer", token, rememberTime);
|
setCookie('Bearer', token, rememberTime)
|
||||||
} else {
|
} else {
|
||||||
setCookie("Bearer", token);
|
setCookie('Bearer', token)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// 删除Token
|
// 删除Token
|
||||||
export let delToken = function() {
|
export let delToken = function() {
|
||||||
if (window.sessionStorage && window.sessionStorage.Bearer) {
|
if (window.sessionStorage && window.sessionStorage.Bearer) {
|
||||||
window.sessionStorage.removeItem("Bearer");
|
window.sessionStorage.removeItem('Bearer')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.localStorage && window.localStorage.Bearer) {
|
if (window.localStorage && window.localStorage.Bearer) {
|
||||||
window.localStorage.removeItem("Bearer");
|
window.localStorage.removeItem('Bearer')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.document.cookie) {
|
if (window.document.cookie) {
|
||||||
delCookie("Bearer");
|
delCookie('Bearer')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
```
|
```
|
||||||
|
|
||||||
大概原理:
|
大概原理:
|
||||||
通过某个 API(通常是登录 API)获取成功后的 Token,存于本地,然后每次请求的时候在 Header 带上`Authorization: "Bearer " + token`,通常情况下无需担心本地 Token 被破解。
|
通过某个 API(通常是登录 API)获取成功后的 Token,存于本地,然后每次请求的时候在 Header 带上`Authorization: "Bearer " + token`,通常情况下无需担心本地 Token 被破解。
|
||||||
|
|
||||||
引入插件介绍
|
## 引入插件介绍
|
||||||
------------
|
|
||||||
|
|
||||||
> 引入插件的版本将会持续更新
|
> 引入插件的版本将会持续更新
|
||||||
|
|
||||||
@ -407,8 +401,7 @@ Koa的错误拦截中间件,需要配合上面的插件使用:https://github
|
|||||||
Synopsis: Multer is a node.js middleware for handling multipart/form-data for koa.
|
Synopsis: Multer is a node.js middleware for handling multipart/form-data for koa.
|
||||||
From: https://github.com/koa-modules/multer
|
From: https://github.com/koa-modules/multer
|
||||||
|
|
||||||
目录结构说明
|
## 目录结构说明
|
||||||
------------
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
.
|
.
|
||||||
@ -440,8 +433,7 @@ Koa的错误拦截中间件,需要配合上面的插件使用:https://github
|
|||||||
└── logs # 日志目录
|
└── logs # 日志目录
|
||||||
```
|
```
|
||||||
|
|
||||||
集成NUXT请求时身份认证说明
|
## 集成 NUXT 请求时身份认证说明
|
||||||
--------------------------
|
|
||||||
|
|
||||||
```
|
```
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
@ -482,12 +474,11 @@ axios.interceptors.request.use(
|
|||||||
Vue.prototype.$request = request
|
Vue.prototype.$request = request
|
||||||
```
|
```
|
||||||
|
|
||||||
各类主流框架调用RESTful API的示例代码(仅供参考)
|
## 各类主流框架调用 RESTful API 的示例代码(仅供参考)
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
### AngularJS (Ionic 同)
|
### AngularJS (Ionic 同)
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
$http({
|
$http({
|
||||||
method: 'post',
|
method: 'post',
|
||||||
url: 'http://localhost:3000/xxx',
|
url: 'http://localhost:3000/xxx',
|
||||||
@ -495,14 +486,18 @@ $http({
|
|||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded'
|
'Content-Type': 'application/x-www-form-urlencoded'
|
||||||
}
|
}
|
||||||
}).success(function (data) {
|
})
|
||||||
}).error(function (data) {
|
.success(function(data) {
|
||||||
|
// do something
|
||||||
|
})
|
||||||
|
.error(function(data) {
|
||||||
|
// do something
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
### jQuery
|
### jQuery
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
$.ajax({
|
$.ajax({
|
||||||
cache: false,
|
cache: false,
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
@ -512,8 +507,7 @@ $.ajax({
|
|||||||
},
|
},
|
||||||
async: false,
|
async: false,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: function (result) {
|
success: function(result) {},
|
||||||
},
|
|
||||||
error: function(err) {
|
error: function(err) {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
}
|
}
|
||||||
@ -539,18 +533,17 @@ $.ajax({
|
|||||||
if (data.result == 'ok') {
|
if (data.result == 'ok') {
|
||||||
$('#zzzz').attr('src', data.img_url)
|
$('#zzzz').attr('src', data.img_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
### MUI
|
### MUI
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
mui.ajax({ url: 'http://localhost:3000/xxx', dataType: 'json',
|
mui.ajax({
|
||||||
success: function(data){
|
url: 'http://localhost:3000/xxx',
|
||||||
|
dataType: 'json',
|
||||||
},
|
success: function(data) {},
|
||||||
error: function(data) {
|
error: function(data) {
|
||||||
console.log('error!')
|
console.log('error!')
|
||||||
}
|
}
|
||||||
@ -559,13 +552,13 @@ mui.ajax({ url: 'http://localhost:3000/xxx', dataType: 'json',
|
|||||||
|
|
||||||
### JavaScript
|
### JavaScript
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
var xhr = new XMLHttpRequest()
|
var xhr = new XMLHttpRequest()
|
||||||
xhr.open('POST', 'http://localhost:3000/xxx', true) //POST或GET,true(异步)或 false(同步)
|
xhr.open('POST', 'http://localhost:3000/xxx', true) //POST或GET,true(异步)或 false(同步)
|
||||||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
|
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
|
||||||
xhr.withCredentials = true
|
xhr.withCredentials = true
|
||||||
xhr.onreadystatechange = function() {
|
xhr.onreadystatechange = function() {
|
||||||
if (obj.readyState == 4 && obj.status == 200 || obj.status == 304) {
|
if ((obj.readyState == 4 && obj.status == 200) || obj.status == 304) {
|
||||||
var gotServices = JSON.parse(xhr.responseText)
|
var gotServices = JSON.parse(xhr.responseText)
|
||||||
} else {
|
} else {
|
||||||
console.log('ajax失败了')
|
console.log('ajax失败了')
|
||||||
@ -578,7 +571,7 @@ mui.ajax({ url: 'http://localhost:3000/xxx', dataType: 'json',
|
|||||||
|
|
||||||
https://github.com/pagekit/vue-resource
|
https://github.com/pagekit/vue-resource
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
// global Vue object
|
// global Vue object
|
||||||
Vue.http.post('/someUrl', [body], {
|
Vue.http.post('/someUrl', [body], {
|
||||||
headers: {'Content-type', 'application/x-www-form-urlencoded'}
|
headers: {'Content-type', 'application/x-www-form-urlencoded'}
|
||||||
@ -589,7 +582,7 @@ Vue.http.post('/someUrl', [body], {
|
|||||||
|
|
||||||
https://github.com/github/fetch
|
https://github.com/github/fetch
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
fetch('/users', {
|
fetch('/users', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@ -622,7 +615,7 @@ fetch('/avatars', {
|
|||||||
|
|
||||||
https://github.com/visionmedia/superagent
|
https://github.com/visionmedia/superagent
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
request.post('/user')
|
request.post('/user')
|
||||||
.set('Content-Type', 'application/json')
|
.set('Content-Type', 'application/json')
|
||||||
.send('{'name':'tj','pet':'tobi'}')
|
.send('{'name':'tj','pet':'tobi'}')
|
||||||
@ -633,67 +626,71 @@ request.post('/user')
|
|||||||
|
|
||||||
https://github.com/request/request
|
https://github.com/request/request
|
||||||
|
|
||||||
```
|
```javascript
|
||||||
request.post('/api').form({key:'value'}), function(err,httpResponse,body){ /* ... */ })
|
request.post('/api').form({key:'value'}), function(err,httpResponse,body){ /* ... */ })
|
||||||
```
|
```
|
||||||
|
|
||||||
在 React 中可以将上述任意方法其置于 componentDidMount()中,Vue.js 同理。
|
在 React 中可以将上述任意方法其置于 componentDidMount()中,Vue.js 同理。
|
||||||
|
|
||||||
彻底移除ESlint方法
|
## 彻底移除 ESlint 方法
|
||||||
------------------
|
|
||||||
|
|
||||||
删除 package.json 的 devDependencies 中所有 eslint 开头的插件,根目录下的“.eslintignore、.eslintrc.js”文件,并且修改 package.json 的 dev 为:
|
删除 package.json 的 devDependencies 中所有 eslint 开头的插件,根目录下的“.eslintignore、.eslintrc.js”文件,并且修改 package.json 的 dev 为:
|
||||||
|
|
||||||
```
|
```bash
|
||||||
'dev': 'gulp start'
|
'dev': 'gulp start'
|
||||||
```
|
```
|
||||||
|
|
||||||
删除 gulpfile.js 中的 lint、eslint_start 两个任务,并且把 default 改为“gulp.task('default', ['start']”。
|
删除 gulpfile.js 中的 lint、eslint_start 两个任务,并且把 default 改为“gulp.task('default', ['start']”。
|
||||||
|
|
||||||
更新说明
|
## 更新说明
|
||||||
--------
|
|
||||||
*v1.0.1 2019年06月02日21:54:00*
|
_v1.0.2 2019 年 06 月 07 日 15:15:37_
|
||||||
|
|
||||||
|
1. 解决`WS-2019-0064`警告,升级依赖项版本。
|
||||||
|
2. 规范路由引入方式,增加不同写法的示例。
|
||||||
|
|
||||||
|
_v1.0.1 2019 年 06 月 02 日 21:54:00_
|
||||||
|
|
||||||
1. 添加 Dockerfile
|
1. 添加 Dockerfile
|
||||||
|
|
||||||
*v1.0.0 2019年04月07日21:19:59*
|
_v1.0.0 2019 年 04 月 07 日 21:19:59_
|
||||||
|
|
||||||
1. 升级依赖项版本(node11.13.0)。
|
1. 升级依赖项版本(node11.13.0)。
|
||||||
2. 添加 Jest。
|
2. 添加 Jest。
|
||||||
|
|
||||||
*v0.2.6 2018年03月24日22:16:43*
|
_v0.2.6 2018 年 03 月 24 日 22:16:43_
|
||||||
|
|
||||||
1. 升级依赖项版本(node9.9.0)。
|
1. 升级依赖项版本(node9.9.0)。
|
||||||
|
|
||||||
*v0.2.5 2018年01月13日10:37:29*
|
_v0.2.5 2018 年 01 月 13 日 10:37:29_
|
||||||
|
|
||||||
1. 升级依赖项版本(node9.3.0)。
|
1. 升级依赖项版本(node9.3.0)。
|
||||||
2. 添加了 Token 使用说明。
|
2. 添加了 Token 使用说明。
|
||||||
|
|
||||||
*v0.2.4 2017年12月01日14:16:03*
|
_v0.2.4 2017 年 12 月 01 日 14:16:03_
|
||||||
|
|
||||||
1. 升级依赖项版本(node9.2.0)。
|
1. 升级依赖项版本(node9.2.0)。
|
||||||
|
|
||||||
*v0.2.3 2017年10月23日23:26:56*
|
_v0.2.3 2017 年 10 月 23 日 23:26:56_
|
||||||
|
|
||||||
1. 升级依赖项版本(node8.7.0)。
|
1. 升级依赖项版本(node8.7.0)。
|
||||||
|
|
||||||
*v0.2.2 2017年09月17日17:45:07*
|
_v0.2.2 2017 年 09 月 17 日 17:45:07_
|
||||||
|
|
||||||
1. 升级依赖项版本(在 node8.5.0 测试)。
|
1. 升级依赖项版本(在 node8.5.0 测试)。
|
||||||
|
|
||||||
*v0.2.1 2017年07月19日19:38:19*
|
_v0.2.1 2017 年 07 月 19 日 19:38:19_
|
||||||
|
|
||||||
1. 移除 MySQL 模块(重复了)。
|
1. 移除 MySQL 模块(重复了)。
|
||||||
2. 添加更详细的说明。
|
2. 添加更详细的说明。
|
||||||
|
|
||||||
*v0.2 2017年07月16日22:48:34*
|
_v0.2 2017 年 07 月 16 日 22:48:34_
|
||||||
|
|
||||||
1. 升级 koa 为 2.3.0 版本。
|
1. 升级 koa 为 2.3.0 版本。
|
||||||
2. 将 koa-session2 替换为 koa-jwt,添加了 jsonwebtoken。
|
2. 将 koa-session2 替换为 koa-jwt,添加了 jsonwebtoken。
|
||||||
3. 升级了以下依赖的版本: koa@2.3.0, koa-body@2.3.0, koa-router@7.2.1, babel-cli@6.24.1, babel-preset-es2015@6.24.1, babel-preset-stage-2@6.24.1, babel-register@6.24.1, eslint-plugin-promise@3.5.0, koa-compose@4.0.0, nodemailer@4.0.1, sequelize@4.3.2, eslint@4.2.0, eslint-config-standard@10.2.1, eslint-friendly-formatter@3.0.0, eslint-plugin-html@3.1.0, gulp-eslint@4.0.0, koa-logger@3.0.1
|
3. 升级了以下依赖的版本: koa@2.3.0, koa-body@2.3.0, koa-router@7.2.1, babel-cli@6.24.1, babel-preset-es2015@6.24.1, babel-preset-stage-2@6.24.1, babel-register@6.24.1, eslint-plugin-promise@3.5.0, koa-compose@4.0.0, nodemailer@4.0.1, sequelize@4.3.2, eslint@4.2.0, eslint-config-standard@10.2.1, eslint-friendly-formatter@3.0.0, eslint-plugin-html@3.1.0, gulp-eslint@4.0.0, koa-logger@3.0.1
|
||||||
|
|
||||||
*v0.1 2017年04月07日11:46:02*
|
_v0.1 2017 年 04 月 07 日 11:46:02_
|
||||||
|
|
||||||
1. 升级 koa 为 2.2.0 版本。
|
1. 升级 koa 为 2.2.0 版本。
|
||||||
2. 升级了以下依赖版本到“建议版本”:
|
2. 升级了以下依赖版本到“建议版本”:
|
||||||
@ -707,17 +704,17 @@ promise-mysql 3.0.0 3.0.1 3.0.1 koa2-API-scaffold
|
|||||||
sequelize 3.30.2 3.30.4 3.30.4 koa2-API-scaffold
|
sequelize 3.30.2 3.30.4 3.30.4 koa2-API-scaffold
|
||||||
```
|
```
|
||||||
|
|
||||||
*v0.0.9_1 2017年03月30日15:51:03*
|
_v0.0.9_1 2017 年 03 月 30 日 15:51:03_
|
||||||
|
|
||||||
1. 完善了 gulpfile.js,不是重要的更新。
|
1. 完善了 gulpfile.js,不是重要的更新。
|
||||||
|
|
||||||
*v0.0.9 2017年03月27日17:25:58*
|
_v0.0.9 2017 年 03 月 27 日 17:25:58_
|
||||||
|
|
||||||
1. 修改了`src/controllers/upload.js`文件,添加了上传文件示例代码。
|
1. 修改了`src/controllers/upload.js`文件,添加了上传文件示例代码。
|
||||||
2. 修复了`src/lib/mysql.js`引用路径错误的 BUG。
|
2. 修复了`src/lib/mysql.js`引用路径错误的 BUG。
|
||||||
3. 修改了`src/controllers/api.js`GET 参数获取的示例。
|
3. 修改了`src/controllers/api.js`GET 参数获取的示例。
|
||||||
|
|
||||||
*v0.0.8 2017年03月01日23:03:44*
|
_v0.0.8 2017 年 03 月 01 日 23:03:44_
|
||||||
1、在 src/app.js 18 行 后添加了
|
1、在 src/app.js 18 行 后添加了
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -728,17 +725,17 @@ sequelize 3.30.2 3.30.4 3.30.4 koa2-API-
|
|||||||
|
|
||||||
以免表单过长导致提交失败。
|
以免表单过长导致提交失败。
|
||||||
|
|
||||||
*v0.0.7 2017年02月18日19:01:48*
|
_v0.0.7 2017 年 02 月 18 日 19:01:48_
|
||||||
1、修改了 index.js、config.js(详情请看 github 记录),完善了对跨域的处理。 更新建议:对应 github 修改记录同步修改,方便将来部署调试。
|
1、修改了 index.js、config.js(详情请看 github 记录),完善了对跨域的处理。 更新建议:对应 github 修改记录同步修改,方便将来部署调试。
|
||||||
|
|
||||||
*v0.0.6 2017年02月17日21:17:23*
|
_v0.0.6 2017 年 02 月 17 日 21:17:23_
|
||||||
1、修改了 src/lib/sequelize.js 文件,添加了对 utf8mb4 的支持(要求 MySQL 版本>5.5)。
|
1、修改了 src/lib/sequelize.js 文件,添加了对 utf8mb4 的支持(要求 MySQL 版本>5.5)。
|
||||||
|
|
||||||
*v0.0.5 2017年02月12日01:25:34*
|
_v0.0.5 2017 年 02 月 12 日 01:25:34_
|
||||||
1、修改了 gulpfile.js 文件,在更改文件热重启的时候无需检查全部文件,仅检查改动文件,开发速度更快。
|
1、修改了 gulpfile.js 文件,在更改文件热重启的时候无需检查全部文件,仅检查改动文件,开发速度更快。
|
||||||
2、修改了 package.json 中"start"项的值为"gulp nodemon"配合 gulpfile.js 文件的修改。
|
2、修改了 package.json 中"start"项的值为"gulp nodemon"配合 gulpfile.js 文件的修改。
|
||||||
|
|
||||||
*v0.0.4 2017年02月07日15:57:17*
|
_v0.0.4 2017 年 02 月 07 日 15:57:17_
|
||||||
1、修改了部分配置文件的配置方法,使之更为规范(老版本用户无须理会,对程序没有影响)。
|
1、修改了部分配置文件的配置方法,使之更为规范(老版本用户无须理会,对程序没有影响)。
|
||||||
2、修改了 eslintrc.js 文件中的 JavaScript 版本配置,改为 ES8,兼容 async、await。
|
2、修改了 eslintrc.js 文件中的 JavaScript 版本配置,改为 ES8,兼容 async、await。
|
||||||
3、修改 gulpfile.js 文件第 12 行,检查`src/**/*.js`文件。
|
3、修改 gulpfile.js 文件第 12 行,检查`src/**/*.js`文件。
|
||||||
|
9908
package-lock.json
generated
9908
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
27
package.json
27
package.json
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "koa2-API-scaffold",
|
"name": "koa2-api-scaffold",
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"description": "Koa2 RESTful API 服务器的脚手架",
|
"description": "Koa2 RESTful API 服务器的脚手架",
|
||||||
"author": "yi-ge <a@wyr.me>",
|
"author": "yi-ge <a@wyr.me>",
|
||||||
@ -19,32 +19,31 @@
|
|||||||
"koa-jwt": "^3.5.1",
|
"koa-jwt": "^3.5.1",
|
||||||
"koa-router": "^7.4.0",
|
"koa-router": "^7.4.0",
|
||||||
"koa-static2": "^0.1.8",
|
"koa-static2": "^0.1.8",
|
||||||
"nodemailer": "^6.1.0",
|
"nodemailer": "^6.2.1",
|
||||||
"promise-mysql": "^3.3.1",
|
"promise-mysql": "^3.3.2",
|
||||||
"require-directory": "^2.1.1",
|
"sequelize": "^5.8.7"
|
||||||
"sequelize": "^5.2.12"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.4.4",
|
"@babel/cli": "^7.4.4",
|
||||||
"@babel/core": "^7.4.5",
|
"@babel/core": "^7.4.5",
|
||||||
"@babel/plugin-external-helpers": "^7.2.0",
|
"@babel/plugin-external-helpers": "^7.2.0",
|
||||||
"@babel/plugin-transform-runtime": "^7.4.3",
|
"@babel/plugin-transform-runtime": "^7.4.4",
|
||||||
"@babel/preset-env": "^7.4.3",
|
"@babel/preset-env": "^7.4.5",
|
||||||
"@babel/register": "^7.4.0",
|
"@babel/register": "^7.4.4",
|
||||||
"@babel/runtime": "^7.4.3",
|
"@babel/runtime": "^7.4.5",
|
||||||
"babel-core": "^7.0.0-bridge.0",
|
"babel-core": "^7.0.0-bridge.0",
|
||||||
"babel-eslint": "^10.0.1",
|
"babel-eslint": "^10.0.1",
|
||||||
"babel-jest": "^24.8.0",
|
"babel-jest": "^24.8.0",
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
"eslint-config-standard": "^12.0.0",
|
"eslint-config-standard": "^12.0.0",
|
||||||
"eslint-friendly-formatter": "^4.0.1",
|
"eslint-friendly-formatter": "^4.0.1",
|
||||||
"eslint-plugin-html": "^5.0.3",
|
"eslint-plugin-html": "^5.0.5",
|
||||||
"eslint-plugin-import": "^2.16.0",
|
"eslint-plugin-import": "^2.17.3",
|
||||||
"eslint-plugin-jest": "^22.4.1",
|
"eslint-plugin-jest": "^22.6.4",
|
||||||
"eslint-plugin-node": "^8.0.1",
|
"eslint-plugin-node": "^9.1.0",
|
||||||
"eslint-plugin-promise": "^4.1.1",
|
"eslint-plugin-promise": "^4.1.1",
|
||||||
"eslint-plugin-standard": "^4.0.0",
|
"eslint-plugin-standard": "^4.0.0",
|
||||||
"gulp": "^4.0.0",
|
"gulp": "^4.0.2",
|
||||||
"gulp-eslint": "^5.0.0",
|
"gulp-eslint": "^5.0.0",
|
||||||
"gulp-nodemon": "^2.4.2",
|
"gulp-nodemon": "^2.4.2",
|
||||||
"jest": "^24.8.0",
|
"jest": "^24.8.0",
|
||||||
|
@ -1,31 +1,39 @@
|
|||||||
export let Get = (ctx) => {
|
export const Get = (ctx, next) => {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
result: 'get',
|
result: 'get',
|
||||||
name: ctx.params.name,
|
name: ctx.params.name,
|
||||||
para: ctx.query
|
para: ctx.query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
export let Post = async (ctx) => {
|
export const Post = async (ctx, next) => {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
result: 'post',
|
result: 'post',
|
||||||
name: ctx.params.name,
|
name: ctx.params.name,
|
||||||
para: ctx.request.body
|
para: ctx.request.body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
export let Put = (ctx) => {
|
export const Put = (ctx, next) => {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
result: 'put',
|
result: 'put',
|
||||||
name: ctx.params.name,
|
name: ctx.params.name,
|
||||||
para: ctx.request.body
|
para: ctx.request.body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
|
|
||||||
export let Delete = (ctx) => {
|
export const Delete = (ctx, next) => {
|
||||||
ctx.body = {
|
ctx.body = {
|
||||||
result: 'delete',
|
result: 'delete',
|
||||||
name: ctx.params.name,
|
name: ctx.params.name,
|
||||||
para: ctx.request.body
|
para: ctx.request.body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ const publicKey = fs.readFileSync(path.join(__dirname, '../../publicKey.pub'))
|
|||||||
/**
|
/**
|
||||||
* 检查授权是否合法
|
* 检查授权是否合法
|
||||||
*/
|
*/
|
||||||
export let CheckAuth = (ctx) => {
|
const CheckAuth = (ctx, next) => {
|
||||||
let token = ctx.request.header.authorization
|
let token = ctx.request.header.authorization
|
||||||
try {
|
try {
|
||||||
let decoded = jwt.verify(token.substr(7), publicKey)
|
let decoded = jwt.verify(token.substr(7), publicKey)
|
||||||
@ -39,11 +39,11 @@ export let CheckAuth = (ctx) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export let Post = (ctx) => {
|
export const Post = (ctx, next) => {
|
||||||
switch (ctx.params.action) {
|
switch (ctx.params.action) {
|
||||||
case 'check':
|
case 'check':
|
||||||
return CheckAuth(ctx).then(result => { ctx.body = result })
|
return CheckAuth(ctx).then(result => { ctx.body = result; next() })
|
||||||
default:
|
default:
|
||||||
return CheckAuth(ctx).then(result => { ctx.body = result })
|
return CheckAuth(ctx).then(result => { ctx.body = result; next() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,9 @@
|
|||||||
let requireDirectory = require('require-directory')
|
import upload from './upload'
|
||||||
module.exports = requireDirectory(module)
|
import * as api from './api'
|
||||||
|
import * as auth from './auth'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
upload,
|
||||||
|
api,
|
||||||
|
auth
|
||||||
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
import KoaRouter from 'koa-router'
|
import KoaRouter from 'koa-router'
|
||||||
import controllers from '../controllers/index.js'
|
import controllers from '../controllers'
|
||||||
|
|
||||||
const router = new KoaRouter()
|
const router = new KoaRouter()
|
||||||
|
|
||||||
router
|
export default router
|
||||||
.get('/public/get', function (ctx, next) {
|
.get('/public/get', function (ctx, next) {
|
||||||
ctx.body = '禁止访问!'
|
ctx.body = '禁止访问!'
|
||||||
}) // 以/public开头则不用经过权限认证
|
}) // 以/public开头则不经过权限认证
|
||||||
.all('/upload', controllers.upload.default)
|
.all('/upload', controllers.upload)
|
||||||
.get('/api/:name', controllers.api.Get)
|
.get('/public/api/:name', controllers.api.Get)
|
||||||
.post('/api/:name', controllers.api.Post)
|
.post('/api/:name', controllers.api.Post)
|
||||||
.put('/api/:name', controllers.api.Put)
|
.put('/api/:name', controllers.api.Put)
|
||||||
.del('/api/:name', controllers.api.Delect)
|
.del('/api/:name', controllers.api.Delete)
|
||||||
.post('/auth/:action', controllers.auth.Post)
|
.post('/auth/:action', controllers.auth.Post)
|
||||||
|
|
||||||
module.exports = router
|
|
||||||
|
Loading…
Reference in New Issue
Block a user