多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Midway 静态资源(Static File)托管实战指南:Egg / Koa / Express / Serverless 四场景配置详解

Midway 静态资源(Static File)托管实战指南:Egg / Koa / Express / Serverless 四场景配置详解 后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载静态资源托管是 Web 应用中高频且基础的能力用于将前端构建产物js / css / html / png 等以 HTTP 方式直接对外提供访问。本文以 Midway 官方文档site/versioned_docs/version-2.0.0/static_file.md为核心脉络完整讲解 Midway 在midwayjs/webEgg、midwayjs/koa、midwayjs/express以及 Serverless 四种场景下托管静态资源的标准做法并结合当前仓库中midwayjs/static-file组件的源码packages/static-file深入剖析其底层配置解析、缓存机制与多目录支持。读者读完本文可以针对不同运行时快速落地一套可运行的静态资源方案并理解每种方案在缓存、性能与平台差异上的取舍。一、静态资源在 Midway 中的定位静态资源泛指不需要服务端动态计算的资源文件典型如前端框架打包后的js、css、图片、字体以及html入口文件。在 Midway 中静态资源托管并不是框架核心内置的能力而是依托各 Web 运行时自带的静态中间件方案来实现的Eggmidwayjs/web自带egg-static插件Koamidwayjs/koa社区常用koa-static-cache中间件Expressmidwayjs/express内置express.staticServerlessmidwayjs/faas因网关不支持流式处理需要选用支持 buffer 返回的中间件。因此选择哪套静态方案取决于你当前使用的 Web 运行时。下面按场景逐一展开。二、在 midwayjs/webEgg中使用egg-static 插件Egg.js 默认提供了static插件Midway 下只需要在插件配置中将其启用即可// src/config/plugin.ts exports.static true;egg-static插件基于koa-static-cache模块实现因此它支持 koa-static-cache 的全部配置项。插件默认的 config 配置为{ prefix: /public/, dir: path.join(appInfo.baseDir, app/public), }prefixURL 路径前缀。例如文件放在${baseDir}/app/public/a.js开启插件后通过http://127.0.0.1:7001/public/a.js即可访问。dir静态文件在磁盘上的存放目录默认指向应用目录下的app/public。需要自定义配置时在src/config/config.default.ts或对应环境的配置文件中覆盖static配置节即可例如修改前缀、更换存放目录、调整缓存策略maxAge、gzip等。其余能力动态加载、预加载、gzip 压缩、别名 alias 等均透传至koa-static-cache。三、在 midwayjs/koa 中使用koa-static-cache 中间件Koa 场景与 Egg 类似直接引入koa-static-cache模块即可$ npm i koa-static-cache --save然后在src/configuration.ts中将静态中间件挂载到应用中。下面的示例把资源目录放在项目根目录下的public目录中// src/configuration.ts import { Configuration, App } from midwayjs/decorator; import { Application } from midwayjs/koa; import * as staticCache from koa-static-cache; Configuration() export class AutoConfiguration { App() app: Application; async onReady() { this.app.use( staticCache({ prefix: /public/, dir: path.join(this.app.getAppDir(), public), }) ); } }要点说明通过App()注入当前 Koa 应用实例this.app.getAppDir()可拿到项目根目录保证dir路径在不同工作目录下依然正确中间件在onReady生命周期中注册确保在应用启动、路由生效前完成挂载prefix与dir配合决定了「URL 前缀 → 磁盘目录」的映射关系例如prefix: /public/时public/logo.png通过/public/logo.png访问。四、在 midwayjs/express 中使用express.staticExpress 本身内置了静态资源支持无需额外安装中间件直接在src/configuration.ts中加入即可// src/configuration.ts import { Configuration, App } from midwayjs/decorator; import { Application } from midwayjs/express; import * as express from express; Configuration() export class AutoConfiguration { App() app: Application; async onReady() { this.app.use(express.static(public)); } }此时位于public目录中的文件可以直接访问http://localhost:3000/images/kitten.jpg http://localhost:3000/css/style.css http://localhost:3000/js/app.js http://localhost:3000/images/bg.png http://localhost:3000/hello.html:::caution 注意 Express 是相对于静态目录查找文件的因此静态目录的名称public不会出现在 URL 路径中——URL 直接以目录内的相对路径访问。 :::如果想调整路由前缀可以通过下面的方式指定挂载路径app.use(/static, express.static(path.join(__dirname, public)));这样public/hello.html的访问地址就变成了http://localhost:3000/static/hello.html。express.static还支持第二个参数传入配置对象可设置maxAge缓存时长、setHeaders自定义响应头、index、fallthrough等选项详见 Express 官方文档的静态文件章节。五、在 Serverless 场景使用必须开启 buffer 返回Serverless 场景较为特殊网关不支持流式处理因此不能使用默认的流式响应方式返回文件需要选择支持 buffer一次性读入内存并返回的静态中间件。koa-static-cache恰好支持 buffer 返回。首先安装依赖$ npm i koa-static-cache --save然后在src/configuration.ts中注册中间件注意将buffer显式设为true// src/configuration.ts import { Configuration, App } from midwayjs/decorator; import { Application } from midwayjs/faas; import * as staticCache from koa-static-cache; Configuration() export class AutoConfiguration { App() app: Application; async onReady() { this.app.use( staticCache({ prefix: /public/, dir: join(__dirname, ../public), dynamic: true, preload: false, buffer: true, // 注意这里是 true maxFiles: 1000, }) ); } }各选项含义buffer: true将文件内容读入内存一次性返回规避网关不支持流式响应的问题dynamic: true动态加载文件不在初始化时一次性扫描目录preload: false配合dynamic使用不在启动时预加载全部文件maxFiles: 1000动态缓存最多缓存的条目数超出后按 LRU 策略淘汰。在非高密度场景普通函数下还需要提供一个/*的路由函数否则请求根本不会进入函数逻辑自然也就走不到中间件中。为了保证中间件可进入可以增加一个空的Get /public/*路由——写成public/*是为了防止其他非 public 静态资源的请求误入这个函数import { Inject, Provide, Controller, Get } from midwayjs/decorator; import { Context } from midwayjs/faas; Provide() export class ServerlessHelloService { Inject() ctx: Context; // 普通路由 ServerlessTrigger(ServerlessTriggerType.HTTP, { path: /:user_id, method: get, }) async hello1() { return 22; } ServerlessTrigger(ServerlessTriggerType.HTTP, { path: /public/*, method: get, }) async render() { // 这个函数的作用是为了让 static 全局中间件被执行。 } }说明本文示例引用自 Midway 2.x 文档site/versioned_docs/version-2.0.0/static_file.md其中使用的ServerlessTrigger等装饰器为 2.x 时代 API。当前仓库的midwayjs/faas已演进为midwayjs/hooks等新一代函数式 API但「Serverless 网关不支持流式、需用 buffer 返回 兜底路由触发中间件」的核心原理与约束仍然成立。六、组件化方案midwayjs/static-file 统一托管除了在各运行时手工挂载中间件Midway 还提供了开箱即用的静态文件组件midwayjs/static-file源码位于仓库 packages/static-file。它基于koa-static-cache封装同时适用于 koa / egg / faas并把默认配置、多目录支持、缓存策略和 Range 请求支持都收敛到组件内部。6.1 安装与引入$ npm i midwayjs/static-file --save在configuration.ts中引入组件import * as koa from midwayjs/koa; import * as staticFile from midwayjs/static-file; import { join } from path; Configuration({ imports: [ koa, staticFile, ], importConfigs: [ join(__dirname, ./config) ] }) export class ContainerConfiguration { }组件注册后$appDir/public目录下的所有静态文件都可以通过/public前缀访问且默认懒加载dynamic 模式首次访问才读盘。6.2 默认配置解析源码级组件的默认配置定义在 src/config/config.default.tsexport default appInfo { return { staticFile: { dirs: { default: { prefix: /public, dir: join(appInfo.appDir, public), }, }, dynamic: true, preload: false, buffer: false, maxFiles: 1000, }, } as { staticFile: StaticFileOptions; }; };生产环境配置定义在 src/config/config.prod.tsexport const staticFile { maxAge: 31536000, buffer: true, } as StaticFileOptions;两套配置合起来形成了组件完整的默认行为配置项开发环境默认值生产环境默认值说明dirs.default.prefix/public/publicURL 路径前缀dirs.default.dir$appDir/public$appDir/public静态文件磁盘目录dynamictruetrue动态加载不在初始化时扫描全目录preloadfalsefalse不预加载文件缓存bufferfalsetrue生产环境改为内存 buffer 返回maxFiles10001000动态缓存条目上限LRUmaxAge031536000缓存控制 max-age生产一年由此可以得出两组实用结论开发环境文件不做缓存、走磁盘流式读取修改静态资源后刷新浏览器即可立即生效生产环境文件在首次访问后被缓存buffer 模式读入内存更新资源后需要重启进程才能生效同时maxAge被设置为 31536000一年利于浏览器长期缓存。6.3 多目录支持dirs 配置组件基于 src/interface.ts 中的StaticFileOptions额外提供了dirs字段允许同时托管多个静态目录每个目录可以有自己的前缀与独立配置// {app_root}/src/config/config.default.ts export const staticFile { dirs: { default: { prefix: /public, dir: xxx }, anotherDir: { prefix: /, dir: xxx } } };可以看到中间件 src/middleware/static.middleware.ts 的实现启动时会遍历staticFileConfig.dirs的所有值若配置了顶层dir也会追加进去对每个目录分别执行staticCache(newOptions)生成一个静态服务最后用middlewareService.compose把多个中间件组合起来。也就是说一个应用可以同时以不同前缀服务多套资源目录例如/public服务前端构建产物、/服务 favicon 等根路径资源。若只想覆盖默认目录的前缀例如把/public改为/直接覆盖dirs.default即可// {app_root}/src/config/config.default.ts export const staticFile { dirs: { default: { prefix: /, }, } };6.4 中间件底层原理中间件核心逻辑位于 src/middleware/static.middleware.ts关键点如下Range 请求支持组件额外集成了koa-range依赖声明见 packages/static-file/package.json当请求路径命中任一静态前缀时会先经过 range 中间件使大文件如视频、PDF支持 HTTP 断点续传与分段下载。LRU 动态缓存当dynamic为true且未显式传入files时会自动创建一个容量为maxFiles的 LRU 缓存基于ylru实现避免无上限缓存撑爆内存。目录存在性校验启动时会检查dir是否存在不存在则抛出组件定义的DirectoryNotFoundError错误码static_file/10000定义在 src/error.ts并打印[midway:static] starting static serve prefix - dir日志便于排查。环境感知的 faas 适配配置类 src/configuration.ts 中onConfigLoad检测到当前应用为faas时会自动把buffer置为true呼应本文第五节「Serverless 必须 buffer 返回」的结论onReady则把StaticMiddleware注册到 koa / faas / egg 三类应用上——若同时启用了cross-domain组件会插入到 cors 中间件之后否则插入到最前。6.5 完整配置项一览组件透传koa-static-cache的全部配置接口定义见 packages/static-file/src/interface.ts常用项说明配置项类型说明prefixstringURL 路径前缀dirstring要托管的磁盘目录dirsobject多目录配置key 为目录别名value 为目录级配置对象dynamicboolean是否动态加载文件不在初始化时全量缓存preloadboolean是否在初始化时预加载全部文件通常与dynamic搭配使用bufferboolean是否将文件读入内存返回Serverless 场景必须为truemaxFilesnumber动态缓存的最大条目数仅dynamic: true时生效默认1000maxAgenumber缓存控制 max-age秒默认0生产环境31536000cacheControlstring自定义 Cache-Control 响应头优先级高于maxAgegzipboolean请求 Accept-Encoding 含 gzip 时对文件做 gzip 压缩aliasobject路径别名映射可用不同 URL 访问同一文件filterfunction \| string[]初始化扫描目录时过滤文件可排除源文件等非构建产物传数组则只允许列出的文件七、场景选型速查与注意事项运行时推荐方案关键点midwayjs/webEggegg-static插件src/config/plugin.ts中exports.static true默认prefix: /public/、dir: $baseDir/app/publicmidwayjs/koakoa-static-cacheonReady中app.use(staticCache({ prefix, dir }))midwayjs/express内置express.static目录名不进入 URL可app.use(/static, express.static(...))指定前缀midwayjs/faasServerlesskoa-static-cache或midwayjs/static-filebuffer: true普通函数需提供/public/*兜底路由以触发中间件实践中的常见注意点路径前缀与目录名Egg / Koa 方案中prefix会体现在 URL 上如/public/a.jsExpress 方案中静态目录名默认不体现需按需挂载前缀避免前端资源引用路径 404。缓存一致性使用midwayjs/static-file时生产环境资源访问后被缓存更新文件必须重启进程开发环境则实时生效两者行为差异来自config.prod.ts的buffer: true与maxAge配置。Serverless 的双重约束既要开启buffer: true适配网关又要准备兜底路由让静态请求能进入函数与中间件链路二者缺一不可。目录校验组件启动时会强制校验dir存在目录路径拼错会直接抛DirectoryNotFoundError日志中的[midway:static] starting static serve是定位问题的第一线索。大文件与 Rangemidwayjs/static-file内置koa-range支持分段请求适合音视频等大文件场景自行使用koa-static-cache时如需 Range 能力需额外引入。综上Midway 的静态资源托管既可以通过各运行时原生的中间件快速接入Egg / Koa / Express / Serverless 四种写法也可以直接使用midwayjs/static-file组件获得多目录、LRU 缓存、Range 与 faas 自动 buffer 等能力。选择哪一种取决于你的运行时类型、是否需要组件化统一管理以及对缓存与 Serverless 网关约束的具体要求。赞分享后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载相关推荐RevokeMsgPatcher 防撤回补丁完整教程被撤回的消息留在本地5 分钟装完自测RevokeMsgPatcher 防撤回补丁完整教程被撤回的消息留在本地5 分钟装完自测 RevokeMsgPatcher 是一款 Windows 平台的防后端微服务云原生Midway 静态资源托管组件基于 midwayjs/static-file 的实践与源码解析Midway 静态资源托管组件基于 midwayjs/static file 的实践与源码解析 导读 midwayjs/static file 是 Mid后端微服务云原生Midway 静态文件托管实战指南基于 midwayjs/static-file 的 public 目录与多目录静态资源服务Midway 静态文件托管实战指南基于 midwayjs/static file 的 public 目录与多目录静态资源服务 midwayjs/stati后端微服务云原生上一篇Feeder重新定义RSS阅读体验的开源解决方案下一篇3个创新方案在华为HarmonyOS设备上完美部署MicroG服务创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表