自己写的类koa-static
- 上一章我已经分析了中间件的基本机构,现在来写一写 类koa-static功能的插件
- 所谓的类koa-static功能的插件,就是 和koa-static功能基本一样,大致上就是自己定义一个存放静态资源的文件夹,然后把左右的静态资源文件存放进去,然后获取静态资源的时候,可以直接去静态资源的文件夹找到然后直接返回
- 这个插件,我叫做他 static-resource
来看看大致的构架
module.exports = function(){
return async function static(ctx,next){
}
}
- 首先是参数的确认,第一个参数肯定是自己设置的要存放静态资源的文件夹的路径,也可以是文件夹,第二个参数就是选项参数,这个可有可无,但是为了以后的更多的配置,还是要形式上的添加上,于是架构就变成了这样子
module.exports = function(static_path,options){
return async function static(ctx,next){
}
}
- 当然啦,主要还是第一个参数,存放静态资源的路径(或者说文件夹),在这里,如果说没有传递参数,那么第一个参数(也就是存放静态资源的路径)会默认是在项目的根目录下的static文件夹里,如果有参数,那就是自己自定义的文件夹里
- 在这里会遇到一个问题就是怎么获取项目的根目录
获取项目根目录的代码
function isDesktop(url){
var arr = url.split("\\")
return arr[arr.length-2] === "Desktop"
}
function rootpath(url){
var s = "/"
var cache = []
while(!isDesktop(url)){
s += "../"
cache.push(url)
url = path.join(__dirname,s)
}
return cache.pop()
}
- 这个代码实际上是有局限性的,适用于所有在桌面上创建的项目,在其他地方创建的项目就不适用了,至于这个获取项目根目录的问题,之后我再去研究更全面的在任何地方创建项目都可以获取项目更目录的方法,现在主要还是要实现static-resource
const path = require("path")
module.exports = function(static_path,options){
var staticpath = static_path && path.join(rootpath(__dirname),static_path) ||
path.join(rootpath(__dirname),"/static")
return async function static(ctx,next){
}
}
- 接下来就是主要的代码实现
- 首先要判断一个http请求的是不是静态资源,静态资源可以是一个js文件,css文件,一张图片等等,现在创建一个总体的对象fileType 来包括所有可能用到的静态资源。
const fileType = {
'css': 'text/css',
'less': 'text/css',
'gif': 'image/gif',
'html': 'text/html',
'ico': 'image/x-icon',
'jpeg': 'image/jpeg',
'jpg': 'image/jpeg',
'js': 'text/javascript',
'json': 'application/json',
'pdf': 'application/pdf',
'png': 'image/png',
'svg': 'image/svg+xml',
'swf': 'application/x-shockwave-flash',
'tiff': 'image/tiff',
'txt': 'text/plain',
'wav': 'audio/x-wav',
'wma': 'audio/x-ms-wma',
'wmv': 'video/x-ms-wmv',
'xml': 'text/xml'
}
- 可以看见,对象的key就是静态资源的扩展名,而对应的值value就是相应的文件形式,实际上就是 Content-Type的值
- 所以判断是不是静态资源的方法很简单,就是:请求的url地址的扩展名有没有出现在 fileType 里边,如果有,那就是要获取静态资源,如果没有,那说明请求不是获取静态资源
说到这里,那怎怎么获取url的扩展名?
function parseFileType(url){
var extname = path.extname(url)
extname = extname ? extname.slice(1) : "unkown"
return fileType[extname]
}
const path = require("path")
const fs = require("fs")
module.exports = function(static_path,options){
var staticpath = static_path && path.join(rootpath(__dirname),static_path) ||
path.join(rootpath(__dirname),"/static")
return async function static(ctx,next){
var type = parseFileType(ctx.url)
if(type){
ctx.type = type
ctx.body = fs.createReadStream(staticpath + ctx.url)
}
await next()
}
}
- 到这里,static-resource基本上已经完成了
这是全部的代码
const path = require("path")
const fs = require("fs")
const fileType = {
'css': 'text/css',
'less': 'text/css',
'gif': 'image/gif',
'html': 'text/html',
'ico': 'image/x-icon',
'jpeg': 'image/jpeg',
'jpg': 'image/jpeg',
'js': 'text/javascript',
'json': 'application/json',
'pdf': 'application/pdf',
'png': 'image/png',
'svg': 'image/svg+xml',
'swf': 'application/x-shockwave-flash',
'tiff': 'image/tiff',
'txt': 'text/plain',
'wav': 'audio/x-wav',
'wma': 'audio/x-ms-wma',
'wmv': 'video/x-ms-wmv',
'xml': 'text/xml'
}
module.exports = function(static_path,options){
var staticpath = static_path && path.join(rootpath(__dirname),static_path) || path.join(rootpath(__dirname),"/static")
return async function static(ctx,next){
var type = parseFileType(ctx.url)
if(type){
ctx.type = type
ctx.body = fs.createReadStream(staticpath + ctx.url)
}
await next()
}
}
function parseFileType(url){
var extname = path.extname(url)
extname = extname ? extname.slice(1) : "unkown"
return fileType[extname]
}
function isDesktop(url){
var arr = url.split("\\")
return arr[arr.length-2] === "Desktop"
}
function rootpath(url){
var s = "/"
var cache = []
while(!isDesktop(url)){
s += "../"
cache.push(url)
url = path.join(__dirname,s)
}
return cache.pop()
}
这个插件我已经上传到npm里了
npm i static-resource-plugin