如何在Next.js项目中接入并适配原有独立TypeScript非TSX代码
解决方案
Next.js 原生支持编译独立的 .ts 类型文件,不需要手动修改 Webpack 配置,按以下步骤调整即可正常使用你的 Three.js 逻辑:
步骤1:调整旧TS文件的导出逻辑
原来的 typescript/my_threejs.ts 如果是直接在顶层执行 DOM 获取、场景初始化逻辑,需要改造成导出可调用的初始化函数,避免服务端渲染阶段执行 DOM 操作报错(服务端不存在 window、document 等浏览器API)。
改造示例:
// typescript/my_threejs.ts import * as THREE from 'three' // 其他你用到的依赖导入 // 把原来的全局执行逻辑封装成导出函数,接收canvas元素作为参数 export function initThreeScene(canvas: HTMLCanvasElement) { // 此处放置你原来的所有Three.js逻辑,直接用传入的canvas即可 const scene = new THREE.Scene() const camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000) const renderer = new THREE.WebGLRenderer({ canvas }) // 剩余的场景搭建、渲染逻辑、动画逻辑都放在这个函数内 } // 如果有销毁逻辑也可以单独导出 export function destroyThreeScene() { // 场景销毁、动画帧取消、资源释放逻辑 }
步骤2:在React组件中调用TS逻辑
在需要展示Three.js场景的 .tsx 组件中,通过 useEffect 确保仅在客户端 DOM 加载完成后调用你封装的初始化方法即可:
// 按你的实际文件路径调整导入路径 import { initThreeScene, destroyThreeScene } from '../typescript/my_threejs' import { useEffect, useRef } from 'react' export default function ThreePage() { const canvasRef = useRef<HTMLCanvasElement>(null) useEffect(() => { if (!canvasRef.current) return // 客户端执行初始化 initThreeScene(canvasRef.current) // 组件卸载时销毁场景,避免内存泄漏 return () => destroyThreeScene() }, []) return <canvas ref={canvasRef} style={{ width: '100%', height: '600px' }} /> }
额外注意事项
- 如果你用
create-next-app初始化的TypeScript项目,默认的tsconfig.json已经支持普通.ts文件的编译,不需要额外修改配置 - 所有浏览器专属API的调用都放在初始化函数内部,不要放在
.ts文件的顶层执行,避免服务端渲染阶段报错
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

