koa的一些middleware
koa的一些常用的middleware
Frameworks
Frameworks, boilerplates and other starter kits using Koa.
Middleware
Known middleware for Koa, you may want to search npm with “koa” to find more.
Security
Body Parsing
Parameter Validation
Rate Limiting
Vhost
Routing and Mounting
Documentation
File Serving
koa-static
静态文件服务中间件,是koa-send
的包装
安装
1 | npm install koa-static |
API
1 | API |
root
根目录 Stringopts
options object.
Options
maxage
浏览cache的最大时间ms 默认 0hidden
允不允许改变隐藏文件. 默认 falseindex
默认文件名, 默认 ‘index.html’defer
如果为true, 在return next()
之后, 服务器允许任何一个downstream middleware 首先回应.gzip
当用户支持gzip格式, 并且.gz这种文件存在就行. 默认 true.br
同上 .br 格式存在时 (但要注意这个只用在https中). 默认 true.setHeaders
Function to set custom headers on response.extensions
当在URL中没有匹配到扩展名时,那么会试着去从传过来的数组中匹配. 默认 false
Example
1 | const serve = require('koa-static'); |
SPDY
HTTP2
JSON and JSONP Responses
Compression
Caching
Authentication
Sessions
Templating
Services
CSS Preprocessor
Livereload
Error reporting
koa-onerror
就是一个抓错误的处理器 for koa, hack ctx.onerror.
就是handle all errors, steams’ and events’ errors
比koa-error使用简单,且抓的错误多
安装
1 | npm install koa-onerror |
使用
1 | const fs = require('fs'); |
Options
1 | onerror(app, options); |
- all: if options.all exist, ignore negotiation
- text: text error handler
- json: json error handler
- html: html error handler
- redirect: if accepct html, can redirect to another error page
check out default handler to write your own handler.
Status and Headers
koa-onerror
will automatic set err.status
as response status code, and err.headers
as response headers.
Logging
koa-logger
Development style logger middleware for koa.
注意: koa-logger@2
支持 koa@2
; 如果你想在 koa@1
中使用, 请使用 koa-logger@1
.
1 | <-- GET / |
安装
1 | npm install koa-logger |
使用
1 | const logger = require('koa-logger') |
Notes
Recommended that you .use()
this middleware near the top to “wrap” all subsequent middleware.
就是在顺序上放最上面来app.use(logger())
Metrics
Analytics
i18n or L10n
Response Transformation
Utilities
koa-convert
就是将只能在koa1中使用的middleware转换成koa2中能用的,当然也能反之咯.但注意有些不能转换 比如koa-router
安装
1 | npm install koa-convert |
使用
1 | const Koa = require('koa') // koa v2.x |
关于区分 legacy and modern middleware
就一个意思,通过 fn.constructor.name == 'GeneratorFunction'
来判断版本.
API
就3个,实现不管新版本还是旧版本都能使用middleware
一个将老的middleware转成新的,
一个混合老的和新的middleware都转成新的,
一个将新的middleware转成老的
- convert()
1 | modernMiddleware = convert(legacyMiddleware) |
- convert.compose()
1 | composedModernMiddleware = convert.compose(legacyMiddleware, modernMiddleware) |
- convert.back()
1 | legacyMiddleware = convert.back(modernMiddleware) |
strip-ansi是将转义码转换为原码
strip-ansi就是将转义后的符号复原
Install
1 | npm install strip-ansi |
Usage
1 | const stripAnsi = require('strip-ansi'); |
Related
- strip-ansi-cli - CLI for this module
- has-ansi - Check if a string has ANSI escape codes
- ansi-regex - Regular expression for matching ANSI escape codes
- chalk - Terminal string styling done right
require-dir增强require的使用
require-dir Helper to require() diretories
本来require()只能读一个文件,现在用了这个后就能读取一个目录,当做一个对象就可以使用了
例子
一个目录结构
1 | dir |
在使用requireDir('./dir')
后将会返回:看不懂这个requireDir见下面使用
1 | //也可以看到这个只是名字,而不是扩展名也有,所以有options duplicate |
安装
1 | //注意这个package不是requireDir |
使用
基本使用
1 | var requireDir = require('require-dir') |
自定义使用,增加参数options
1 | var dir = requireDir('./path/to/dir', {recurse: true}); |
Options
recurse
: 是否在子文件夹中递归require()
. (node_modules 中的会被忽略.) 默认 false.duplicates
: 默认预设的,如果多个文件有相同的名字(注意这个只看名字,不看扩展名),只有最高优先权的require()
‘d 会返回. (优先权通过require.extensions
keys的顺序决定,如果recurse
is true那么文件夹的优先权大于文件.) Specifying this optionrequire()
‘s all files and returns full filename keys in addition to basename keys. 默认 false.
例如.在上面那个例子中, 如果多了一个叫 a.json
的, 那么结果还是一样, 但如果改了 duplicates: true
结果如下:
1 | { a: require('./dir/a.js') |
filter
: 就是过滤器,在使用require前过滤夏文件名. 例如在生成环境中忽略dev开头的文件:
1 | requireDir('./dir', { |
mapKey
: 在require-ing后对 module base name进行转换. 例如将 any module names 都大写:
1 | requireDir('./dir', { |
mapValue
: 这个是对value. For example, uppercasing any text exported:
1 | requireDir('./dir', { |
Tips
如果你想在多个文件中使用同一个文件夹下的 require()
, 你就单独建一个 index.js
文件 然后如下:
1 | module.exports = require('require-dir')(); // defaults to '.' |
And don’t worry, the calling file is always ignored to prevent infinite loops.
lru_cache最近最少使用缓存处理
LRU是Least Recently Used 的缩写,翻译过来就是“最近最少使用”。
LRU缓存的处理方式如其命名,在固定的缓存空间下,把最近最少使用的数据移除,让给最新读取的数据。算法假设最常读取的数据一般也是访问次数最多的,尽力保留这部分数据可以提高cache的命中。
例子
在保持几个从MongoDB中取出来的数据
使用
1 | var LRU = require("lru-cache") |
当然要注意数据不能放太多,不然溢出
Options
max
cache的最大长度,使用length函数来对所有值检查合法性.必须设置,不然默认无穷大.maxAge
以ms为单位的最大逗留时间.length
这是一个Function用来计算 the length of stored items.你在存储 strings or buffers时, 你可能想要做如下
function(n, key){return n.length}
. The default isfunction(){return 1}
, 表示你存储大小规模是max
那设置就没事. The item is passed as the first argument, and the key is passed as the second argumnet.dispose
这个Function 是用来将items从cache中drop的. 当你关闭文件或做其他清除cache工作时,不需要用到这些items时可以使用. Called withkey, value
. 实际上是先call再把这个item是从内部cache中remove,如果你想立即put it back in, you’ll have to do that in anextTick
orsetTimeout
callback or it won’t do anything.stale
By default, if you set amaxAge
, 只有当你使用get(key)
他才会真正把 stale items 拉出cache . (也就是说在做setTimeout
oranything
前并不能做其他事.)- 如果你设置stale:true, 在你删除这个stale value前,他会返回给你.
- 如果你没有设置这个值, 那么当你试图get a stale entry, 他会返回undefined , 因为他已经被删除了
noDisposeOnSet
By default, 如果你设置了dispose()
方法,当你使用set()
操作来重写一个已经存在的key时,他会被调用 If you set this option,dispose()
will only be called when a key falls out of the cache, not when it is overwritten.
API
set(key, value, maxAge)
get(key) => value
Both of these will update the “recently used”-ness of the key. They do what you think. maxAge
is optional and overrides the cache maxAge
option if provided.
If the key is not found, get()
will return undefined
.
The key and val can be any value.
- peek(key)
Returns the key value (or undefined
if not found) without updating the “recently used”-ness of the key.
(If you find yourself using this a lot, you might be using the wrong sort of data structure, but there are some use cases where it’s handy.)
- del(key)
Deletes a key out of the cache.
- reset()
Clear the cache entirely, throwing away all values.
- has(key)
Check if a key is in the cache, without updating the recent-ness or deleting it for being stale.
- forEach(function(value,key,cache), [thisp])
Just like Array.prototype.forEach
. Iterates over all the keys in the cache, in order of recent-ness. (Ie, more recently used items are iterated over first.)
- rforEach(function(value,key,cache), [thisp])
The same as cache.forEach(...)
but items are iterated over in reverse order. (ie, less recently used items are iterated over first.)
- keys()
Return an array of the keys in the cache.
- values()
Return an array of the values in the cache.
- length
Return total length of objects in cache taking into account length options function.
- itemCount
Return total quantity of objects currently in cache. Note, that stale
(see options) items are returned as part of this item count.
- dump()
Return an array of the cache entries ready for serialization and usage with ‘destinationCache.load(arr)`.
- load(cacheEntriesArray)
Loads another cache entries array, obtained with sourceCache.dump()
, into the cache. The destination cache is reset before loading new entries
- prune()
Manually iterates over the entire cache proactively pruning old entries
mongoose操作MongoDB数据库的模块
mongoose让你用js的方式来操纵mongodb数据库
首先理下思路
- 有个数据库叫mongodb
- nodejs中有个模块叫mongoose
- nodejs不通过shell命令行而是通过使用mongoose的API来控制mongodb
quick start
安装mongoose
1 | npm install mongoose |
例子
例子就是我们想在mongodb中创建一个叫test的数据库,然后再数据库中增加一个collection,这个collection中存入fuzzy kittens
这其实就对应着3块,Schemas,Models,Documents
使用开始
要在nodejs中使用mongoose,先得连接mongodb数据库.指的是在shell中
1 | mongod --dbpath d:/db |
不懂得话先看mongodb教程熟悉一下.然后
1 | // getting-started.js |
当然这个test同mongodb那样,要存入数据口才能show dbs看到
接下来看看有没有连接成功
1 | var mongoose = require('mongoose'); |
然后启动
1 | node app.js |
接着连接成功,那么如何往MongoDB中存入数据呢,这个看例子,注意理清Schema,Model,Documents关系
1 | //Schema,相当于规定好数据的属性 |
接着上面,除了规定属性外,当然还有方法咯(注意顺序)
1 | //给猫加个猫猫叫 |
接下来就是保存到MongoDB数据库中了
1 | //将Documents存入MongoDB中去,第一个参数是error的callback |
当然存入后还能查找所有kittens中的(find咯),和save一样的格式
1 | Kitten.find(function (err, kittens) { |
过滤下查找结果,条件查找,查找所有name叫fluff的,然后通过callback返回一组array
1 | Kitten.find({ name: /^fluff/ }, callback); |
配置
moment一款管理date格式的轻量级js库
Moment.js是一款解析,验证,控制和格式化时间的轻量级javascript库
可以使用在browser和Node.js中
安装
Node.js
1 | npm install moment |
Browser
1 | //就是使用CDN 在cdnjs.com或jsDelivr上都有 |
官方推荐用Require.js(但我不会)
先通过bower或node_modules安装依赖,然后通过packages config
Browserify
1 | npm install moment |
Note: There is a bug that prevents moment.locale from being loaded.
1 | var moment = require('moment'); |
Use the workaround below
1 | var moment = require('moment'); |
In order to include all the locales
1 | var moment = require('moment'); |
Typescript 2.13.0+
这个要moment版本大于2.13.0才能用
1 | //install via NPM |
Note: If you have trouble importing moment, try adding "allowSyntheticDefaultImports": true
in compilerOptions in yourtsconfig.json
file and then use the syntax
1 | import moment from 'moment'; |
Locale Import(就是设置时区)
To use moment.locale
you first need to import the language you are targeting.
1 | import * as moment from 'moment'; |
解析
为了修改原生的 Date.prototype
, Moment.js 创建了一个 wrapper for the Date
object. 获取这个wrapper object, 只需要简单的调用 moment()
输入支持的类型即可.
The Moment
prototype is exposed through moment.fn
.如果你想增加你自定义的函数,可以通过这个
为了简单使用,所有在 Moment.prototype
中的方法 都会指到 moment#method
. So Moment.prototype.format == moment.fn.format == moment#format
.
Now
1 | moment(); |
获得当前时间只需要调用 moment()
不需要参数.
1 | var now = moment(); |
本质上就是和调用 moment(new Date())
一样.
Note: From version 2.14.0, moment([])
and moment({})
also return now. They used to default to start-of-today before 2.14.0, but that was arbitrary so it was changed.
String
要用到时查下
md5使用MD5来hash
使用MD5来哈希消息的一个js函数
版本
version 2.0.0 前有2个package谁叫md5 on npm,一个小写,一个大写(你看到的这个就是). version 2.0.0之后,所有的版本就都是小写的md5 on npm. 如果你想在versions >= 2.0.0正确使用这个module,那么你就得改一下 require(‘MD5’) 为 require(‘md5’) .
安装
1 | npm install md5 |
API
1 | md5(message) |
- message: String or Buffer
- 返回 String
使用
1 | var md5 = require('md5'); |
结果
1 | 78e731027d8fd50ed642340b7c9a63b3 |
如果支持buffer
1 | var fs = require('fs'); //这个fs不是通过npm安装,而是node自带的 |
simplemde一款markdown编辑器
SimpleMDE is a simple, embeddable, and beautiful JS markdown editor
simplemde marked highlight.js区别
第一个是编辑器,第二个是解析器,第三个是语法高亮
安装
通过npm
1 | npm install simplemde --sava |
通过 jsDelivr.但这个更新会有延迟
1 | <link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css"> |
快速开始
1 | //这个会自动加载到页面上第一个textarea上,不建议这么做 |
获取/设置内容
1 | //get |
配置参数
- autoDownloadFontAwesome: 默认是undefined,可选true/false 是否自动下载字体,图标.建议false,因为速度会变慢.我们npm下载就好了
- autofocus: 默认false, true/false, 自动聚焦到编辑器.
- autosave: 自动保存
- enabled: 默认false
- delay: 默认延迟 10000 (10s). 延迟10s自动保存
- uniqueId: 设置自动保存就一定要设置一个id
- blockStyles: 自定义bold code italic怎么标记
- bold ** or __. Defaults to **.
- code ``` or ~~~. Defaults to ```.
- italic * or _. Defaults to *.
- element: DOM元素挂载点 默认就是页面中第一个textarea标签.建议修改掉,用id=””指定
- forceSync: 前置同步. 默认false.
- hideIcons: 要隐藏图标的一个数组
- indentWithTabs: 缩进用tab 默认 true. 否则就是space
- initialValue: 自定义一个初始值,不是placeholder
- insertTexts: 自定义插入文本的行为,是一个有2个元素的数组. 第1个元素时鼠标或高亮前插入,第2个之后插入, For example, this is the default link value: [““, ““].
- horizontalRule
- image
- link
- table
- lineWrapping: 自动换行. 默认 true.
- parsingConfig: 在编辑的时候对解析markdown的设置进行调整(不是预先写入)
- allowAtxHeaderWithoutSpace: 如果是true就在对标题渲染的时候在#后面不会带一个空格. 默认 false.
- strikethrough: false的话不处理 GFM strikethrough 语法. 默认 true.
- underscoresBreakWords: true的话下划线当做分隔符,默认 false
- placeholder: 自定义placeholder显示
- previewRender: 自定义解析markdown到html的函数. 当用户预览的时候会加载
- promptURLs: true的话, 会有2个js弹窗出现要求link或img的url.默认false.
renderingConfig: 在预览的时候解析markdown的设置进行调整.(不是在编辑时)
- singleLineBreaks: false的话, 不会解析GFM single line breaks. 默认 true.
- codeSyntaxHighlighting: true的话 将会对使用 highlight.js的进行高亮. 默认 false. 使用这个功能的话你必须在你的页面上加载 highlight.js . For example, include the script and the CSS files like:
1
2<script src="https://cdn.jsdelivr.net/highlight.js/latest/highlight.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/highlight.js/latest/styles/github.min.css">
shortcuts: 快捷键 默认有一张表.
- showIcons: 一组显示图标名字
- spellChecker: 拼写检查. 默认true.
- status: 默认 true 显示状态栏
- 当然这个也可以你定义
- styleSelectedText: false的话, 从选择的行中移除CodeMirror-selectedtext class . 默认 true.
- tabSize: 自定义tab大小. 默认 2.
- toolbar: false的话, 隐藏工具栏. 默认是展示
- toolbarTips: false的话, 关闭工具栏按钮提示. 默认true.
1 | // Most options demonstrate the non-default behavior |
高度(2种都可以,在html中或css中)
To change the minimum height (before it starts auto-growing):
1 | .CodeMirror, .CodeMirror-scroll { |
事件绑定
You can catch the following list of events:
1 | var simplemde = new SimpleMDE(); |
从textarea中移除simplemde
通过调用 toTextArea 方法. 注意这个也会清除自动保存,就是textarea内容重置了.
1 | var simplemde = new SimpleMDE(); |
一些常用方法
1 | var simplemde = new SimpleMDE(); |
How it works
SimpleMDE began as an improvement of lepture’s Editor project, but has now taken on an identity of its own. It is bundled with CodeMirror and depends on Font Awesome.
CodeMirror is the backbone of the project and parses much of the Markdown syntax as it’s being written. This allows us to add styles to the Markdown that’s being written. Additionally, a toolbar and status bar have been added to the top and bottom, respectively. Previews are rendered by Marked using GFM.
marked一个简易markdown功能实现模块
marked模块-简易markdown功能实现
Markdown不是HTML,目前还不能被浏览器解析,所以我们需要Markdown的解析器(不是编辑器,编辑器另选simplemde),把Markdown翻译成浏览器认识的HTML文档展示出来。Marked就是一个基于Nodejs的Markdown解析引擎!
安装
使用
1 | npm isntall marked --sava |
使用
使用就很简单了,直接用div或者textarea都行,id指明后用innerHTML插入
1 | <!doctype html> |
详细说明marked()方法
1 | marked(markdownString [,options] [,callback]) |
markdownString
是你渲染的内容,必须是字符串。options
是你渲染的设置——它是一个对象。当然,你用marked.setOptions
也是不错的。callback
是回调函数。如果 options
参数没有定义,它就是第二个参数。
关于Options(详细解说,毕竟配合highlight.js一起用)
1 | var rendererMD = new marked.Renderer(); |
当然首先highlight.js要引入
1 | <link href="http://cdn.bootcss.com/highlight.js/8.0/styles/monokai_sublime.min.css" rel="stylesheet"> |
因为highlight.js不能渲染接口返回的代码,所以需要node中的marked配合options
1 | var rendererMD = new marked.Renderer(); |
所以以上有两点参数说明
highlight中 高亮的参数
完整的highlight方法包含三个参数:code,lang和callback
code——代码内容——是一个字符串。
lang——编程语言的种类——也是字符串。
这个需要在highlight.registerLanguage中设置
callback就是回调函数。
renderer(渲染)
render存放的是一个对象,不声明时默认为new Renderer()
。
自定义渲染方式(这个略过吧)
渲染选项允许你以自定义的方式渲染内容,并把之前的规则设置覆盖掉。——这是比较底层的方法了。
比如,我想渲染# heading+
,但是默认的规则是:<h1></h1>
,我想改为更为复杂的结构——
1 | var rendererMD = new marked.Renderer(); |
渲染结果
1 | <h1> |
以上就用了heading的渲染。
块级支持以下渲染
- code(string code, string language)
- blockquote(string quote)
- html(string html)
- heading(string text, number level)
- hr()
- list(string body, boolean ordered)
- listitem(string text)
- paragraph(string text)
- table(string header, string body)
- tablerow(string content)
- tablecell(string content, object flags)
flags
拥有以下属性:
1 | { |
行级支持以下渲染:
- strong(string text)
- em(string text)
- codespan(string code)
- br()
- del(string text)
- link(string href, string title, string text)
- image(string href, string title, string text)
其它渲染参数(都是boolean)
gfm
它是一个布尔值,默认为true。
允许 GitHub标准的markdown.
tables
它是一个布尔值,默认为true。
支持支持github表格语法。该选项要求 gfm 为true。
breaks
它是一个布尔值,默认为false。
支持github回车换行。该选项要求 gfm 为true。
pedantic
它是一个布尔值,默认为false。
尽可能地兼容 markdown.pl的晦涩部分。不纠正原始模型任何的不良行为和错误。
sanitize
它是一个布尔值,默认为false。
对输出进行过滤(清理),将忽略任何已经输入的html代码(标签)
smartLists
它是一个布尔值,默认为false。
使用比原生markdown更时髦的列表。 旧的列表将可能被作为pedantic的处理内容过滤掉.
smartypants
它是一个布尔值,默认为false。
使用更为时髦的标点,比如在引用语法中加入破折号。
使用lexer和parser
如果你想,还可以使用词法分析器。通过它可以追加规则:
1 | var tokens = marked.lexer('text');//把text解析为一个marked.js的内部对象 |