从 v1 到 v2 的迁移指南
H3 版本 2 包含一些行为和 API 变更,您在迁移时需要考虑应用这些更改。
最新的 Node.js 和 ESM-only
如果您的应用当前使用 CommonJS 模块(require
和 module.exports
),得益于最新 Node.js 版本支持 require(esm)
,您仍可以使用 require("h3")
。
Web 标准
在使用 Node.js 时,H3 采用兼容层(💥 srvx),在其他运行时使用原生 Web 兼容 API。
仅在 Node.js 运行时服务器中才能访问原生的 event.node.{req,res}
。
event.web
更名为 event.req
(web Request 的实例)。
响应处理
如果您之前使用了以下方法,可以改为用返回语句 return
返回文本、JSON、流或 Web Response
(H3 会智能识别并处理每种类型):
send(event, value)
:迁移为return <value>
。sendError(event, <error>)
:迁移为throw createError(<error>)
。sendStream(event, <stream>)
:迁移为return <stream>
。sendWebResponse(event, <response>)
:迁移为return <response>
。
其他更名且需要显式 return
的发送工具:
sendNoContent(event)
/return null
:迁移为return noContent(event)
。sendIterable(event, <value>)
:迁移为return iterable(event, <value>)
。sendProxy(event, target)
:迁移为return proxy(event, target)
。handleCors(event)
:检查返回值(布尔型),如果已处理则提前return
。serveStatic(event, content)
:确保添加return
。sendRedirect(event, location, code)
:迁移为return redirect(event, location, code)
。
H3 与 Router
任何 handler 都可以返回一个响应。如果中间件不返回响应,则会尝试后续处理,最终若无响应则返回 404。Router 处理程序可以返回也可以不返回响应,此时 H3 会发送一个简单的 200 空内容响应。
H3 迁移到了全新的路由匹配引擎(🌳 rou3)。您可能会体验到更加直观但稍有不同的匹配行为变化。
v1 的其他变更:
- 使用
app.use("/path", handler)
添加的中间件仅匹配/path
(不会匹配/path/foo/bar
)。如需匹配所有子路径,请改为使用app.use("/path/**", handler)
。 - 每个 handler 中接收的
event.path
将是完整路径,不会省略前缀。请使用工具函数withBase(base, handler)
构建带前缀的应用(示例:withBase("/api", app.handler)
)。 router.add(path, method: Method | Method[])
签名更改为router.add(method: Method, path)
。router.use(path, handler)
已废弃,请改用router.all(path, handler)
。- 不再支持
app.use(() => handler, { lazy: true })
,请改用app.use(defineLazyEventHandler(() => handler), { lazy: true })
。 - 不再支持
app.use(["/path1", "/path2"], ...)
与app.use("/path", [handler1, handler2])
,请使用多次app.use()
代替。 - 移除
app.resolve(path)
。
请求体
Request
接口的 event.req.*
原生方法。readBody(event)
根据请求的 content-type
使用 JSON.parse
或 URLSearchParams
解析 application/x-www-form-urlencoded
格式内容。
- 文本:使用 event.req.text()。
- JSON:使用 event.req.json()。
- formData:使用 event.req.formData()。
- 流:使用 event.req.body。
行为变更:
- 针对无请求体的请求(例如 GET 方法),Body 工具不会抛出异常,而是返回空值。
- 原生
request.json
和readBody
不再使用 unjs/destr,您需自行严格过滤和清理用户数据以防范 原型污染攻击。
Cookie 和 Headers
Headers
来支持所有工具。Header 值现在始终为纯 string
类型(不再可能是 null
、undefined
、number
或 string[]
)。
针对 Set-Cookie
头,可以使用 headers.getSetCookie
方法,该方法始终返回字符串数组。
其他废弃内容
H3 v2 废弃了一些老旧及别名工具。
App 和路由工具
createApp
/createRouter
:迁移为new H3()
。
错误工具
createError
/H3Error
:迁移为HTTPError
isError
:迁移为HTTPError.isError
Handler 工具
eventHandler
/defineEventHandler
:迁移为defineHandler
(您也可以直接使用函数)。lazyEventHandler
:迁移为defineLazyEventHandler
。toEventHandler
:移除包装器。isEventHandler
:(移除)任何函数均可作为事件处理器。useBase
:迁移为withBase
。defineRequestMiddleware
和defineResponseMiddleware
已移除。
请求工具
getHeader
/getRequestHeader
:迁移为event.req.headers.get(name)
。getHeaders
/getRequestHeaders
:迁移为Object.fromEntries(event.req.headers.entries())
。getRequestPath
:迁移为event.path
或event.url
。getMethod
:迁移为event.method
。
响应工具
getResponseHeader
/getResponseHeaders
:迁移为event.res.headers.get(name)
。setHeader
/setResponseHeader
/setHeaders
/setResponseHeaders
:迁移为event.res.headers.set(name, value)
。appendHeader
/appendResponseHeader
/appendResponseHeaders
:迁移为event.res.headers.append(name, value)
。removeResponseHeader
/clearResponseHeaders
:迁移为event.res.headers.delete(name)
。appendHeaders
:迁移为appendResponseHeaders
。defaultContentType
:迁移为event.res.headers.set("content-type", type)
。getResponseStatus
/getResponseStatusText
/setResponseStatus
:请使用event.res.status
和event.res.statusText
。
Node.js 工具
defineNodeListener
:迁移为defineNodeHandler
。fromNodeMiddleware
:迁移为fromNodeHandler
。toNodeListener
:迁移为toNodeHandler
。createEvent
:移除,使用 Node.js 适配器(toNodeHandler(app)
)。fromNodeRequest
:移除,使用 Node.js 适配器(toNodeHandler(app)
)。promisifyNodeListener
:移除。callNodeListener
:移除。
Web 工具
fromPlainHandler
:移除,迁移为 Web API。toPlainHandler
:移除,迁移为 Web API。fromPlainRequest
:移除,迁移为 Web API 或使用测试工具mockEvent
。callWithPlainRequest
:移除,迁移为 Web API。fromWebRequest
:移除,迁移为 Web API。callWithWebRequest
:移除。
Body 工具
readRawBody
:迁移为event.req.text()
或event.req.arrayBuffer()
。getBodyStream
/getRequestWebStream
:迁移为event.req.body
。readFormData
/readMultipartFormData
/readFormDataBody
:迁移为event.req.formData()
。
其他工具
isStream
:迁移为instanceof ReadableStream
。isWebResponse
:迁移为instanceof Response
。splitCookiesString
:请使用 cookie-es 中的splitSetCookieString
。MIMES
:移除。
类型导出
App
:迁移为H3
。AppOptions
:迁移为H3Config
。_RequestMiddleware
:迁移为RequestMiddleware
。_ResponseMiddleware
:迁移为ResponseMiddleware
。NodeListener
:迁移为NodeHandler
。TypedHeaders
:迁移为RequestHeaders
和ResponseHeaders
。HTTPHeaderName
:迁移为RequestHeaderName
和ResponseHeaderName
。H3Headers
:迁移为原生Headers
。H3Response
:迁移为原生Response
。MultiPartData
:迁移为原生FormData
。RouteNode
:迁移为RouterEntry
。CreateRouterOptions
:迁移为RouterOptions
。
移除的类型导出包括:WebEventContext
、NodeEventContext
、NodePromisifiedHandler
、AppUse
、Stack
、InputLayer
、InputStack
、Layer
、Matcher
、PlainHandler
、PlainRequest
、PlainResponse
、WebHandler
。