从Nexus框架迁移到Nexus库的完整指南
前言
对于正在使用Nexus框架(0.20-0.27版本)的开发者来说,迁移到Nexus库(1.0及以上版本)是一个重要的升级步骤。本文将全面解析迁移过程中需要注意的关键点,帮助开发者顺利完成过渡。
核心概念理解
首先需要明确的是,Nexus从框架转变为库意味着:
- 框架提供完整的开发体验和工具链
- 库则专注于核心功能,将周边工具的选择权交给开发者
这种转变带来了更大的灵活性,但也意味着开发者需要自行配置更多内容。
基础环境配置
依赖管理
第一步是更新核心依赖:
npm uninstall nexus
npm install nexus graphql
注意现在需要显式安装graphql作为peer dependency。
TypeScript配置
如果之前仅因为Nexus框架要求而使用TypeScript,现在可以选择继续使用TypeScript或切换回JavaScript。对于继续使用TypeScript的开发者:
- 安装必要依赖:
npm install -D typescript ts-node ts-node-dev
- 配置编辑器使用工作区TypeScript版本
- 确保tsconfig设置正确:
- 如果类型生成到node_modules/@types目录,需正确配置typeRoots
- 使用Apollo Server时需要设置skipLibCheck: true
- 建议启用strict模式以获得最佳类型体验
开发工作流调整
开发服务器
需要自行配置开发时的服务器重启逻辑:
{
"scripts": {
"dev": "ts-node-dev --transpile-only ./src/server",
"dev:typecheck": "tsc --noEmit --watch"
}
}
这种分离设计是因为:
- 开发服务器需要快速响应代码变更
- 类型检查不应阻塞程序运行(Nexus的类型反射系统需要程序运行)
类型反射系统
Nexus的类型系统需要在构建前生成类型定义,有两种主要实现方式:
方法A:独立运行类型定义模块
- 组织类型定义到独立模块
- 创建专门的schema.ts入口文件
- 添加反射脚本:
{
"scripts": {
"nexus:reflect": "ts-node --transpile-only src/schema"
}
}
方法B:主应用运行时反射
- 配置makeSchema选项:
makeSchema({
shouldExitAfterGenerateArtifacts: Boolean(process.env.NEXUS_SHOULD_EXIT_AFTER_REFLECTION)
})
- 添加反射脚本:
{
"scripts": {
"nexus:reflect": "NEXUS_SHOULD_EXIT_AFTER_REFLECTION=true ts-node src/server"
}
}
构建与部署
基本构建流程
{
"scripts": {
"build": "yarn nexus:reflect && tsc"
}
}
高级打包选项
对于Serverless部署等场景,可以考虑使用打包工具:
- esbuild - 极快的打包速度
- spack - 基于Rust的高效打包
- ncc - 专为Node.js设计的打包工具
配置示例:
{
"compilerOptions": {
"moduleResolution": "Node",
"target": "ES2015",
"module": "ES2015"
}
}
HTTP服务器配置
Nexus框架内置了Apollo Server,现在需要自行配置:
- 安装必要依赖:
npm install express apollo-server-express
npm install -D @types/express
- 基础服务器实现:
import { ApolloServer } from 'apollo-server-express'
import express from 'express'
const app = express()
const server = new ApolloServer({ schema })
server.applyMiddleware({ app })
app.listen(4000, () => {
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
})
高级功能配置
CORS支持:
server.applyMiddleware({
app,
cors: {
origin: 'https://example.com',
credentials: true
}
})
订阅功能:
import { createServer } from 'http'
const httpServer = createServer(app)
server.installSubscriptionHandlers(httpServer)
httpServer.listen(4000, () => {
console.log(`Subscriptions ready at ws://localhost:4000${server.subscriptionsPath}`)
})
类型系统增强
上下文类型安全
实现类型安全的上下文:
- 定义上下文类型:
// context.ts
export type Context = {
userId: string
log: Logger
}
- 配置schema:
makeSchema({
contextType: {
module: path.join(__dirname, 'context.ts'),
alias: 'ContextModule',
export: 'Context'
}
})
- 服务器端实现:
new ApolloServer({
context: ({ req }) => ({
userId: getUserIdFromRequest(req),
log: createRequestLogger()
})
})
自定义标量类型
实现常用标量类型:
import { DateTimeResolver, JSONObjectResolver } from 'graphql-scalars'
const jsonScalar = asNexusMethod(JSONObjectResolver, 'json')
const dateTimeScalar = asNexusMethod(DateTimeResolver, 'dateTime')
makeSchema({
types: [jsonScalar, dateTimeScalar]
})
日志系统
推荐日志方案:
- 使用floggy(原@nexus/logger):
import * as Floggy from 'floggy'
Floggy.settings({ filter: 'app:*, *@warn+' })
export const log = Floggy.log.child('app')
- 请求级日志:
context: ({ req }) => ({
log: log.child('request', { requestId: generateId() })
})
错误处理
建议方案:
- 同步错误:Node.js默认处理
- 异步错误:使用make-promises-safe
npm install make-promises-safe
import 'make-promises-safe'
总结
从Nexus框架迁移到Nexus库虽然需要一定的配置工作,但带来了更大的灵活性和对技术栈的控制权。按照本文指南逐步实施,可以确保平稳过渡,同时获得更好的类型安全和可维护性。
关键迁移步骤包括:
- 更新核心依赖
- 配置TypeScript工具链
- 实现开发工作流
- 设置构建和部署流程
- 配置HTTP服务器和高级功能
- 确保类型系统安全
- 实现日志和错误处理
通过合理配置,新的Nexus库方案能够提供与框架相当甚至更好的开发体验。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考