
本文详解 inertia.js + vue 3 服务端渲染(ssr)配置中因混合使用 commonjs require() 与 es 模块导致的运行时错误,并提供兼容性修复方案、完整 ssr 入口代码及关键注意事项。
本文详解 inertia.js + vue 3 服务端渲染(ssr)配置中因混合使用 commonjs require() 与 es 模块导致的运行时错误,并提供兼容性修复方案、完整 ssr 入口代码及关键注意事项。
在基于 AdonisJS(或类似 Node.js 框架)集成 Inertia.js 实现 Vue 3 SSR 时,一个常见但易被忽略的陷阱是模块系统不匹配。错误信息明确指出:
require() of ES Module ...@inertiajs/vue3/dist/index.js ... not supported.
根本原因在于:你的 ssr.js 文件作为 ES 模块(由 import 语句和 package.json 中 "type": "module" 触发),却调用了 CommonJS 风格的 require() 动态加载页面组件——而现代 ES 模块规范中,require() 不可用,必须改用 import()(返回 Promise 的动态导入)。
✅ 正确写法:将 require() 替换为 import()
修改 resources/js/ssr.js 中的 resolve 函数,必须使用异步 import() 并确保返回 Promise(Inertia SSR 内部会 await 它):
// resources/js/ssr.js
import { createSSRApp, h } from 'vue'
import { renderToString } from '@vue/server-renderer'
import { createInertiaApp, Link } from '@inertiajs/vue3'
export default async function render(page) {
return createInertiaApp({
page,
render: renderToString,
// ✅ 关键修复:使用 import() 返回 Promise,而非 require()
resolve: (name) => import(`./Pages/${name}.vue`),
setup({ app, props, plugin }) {
const root = createSSRApp({
render: () => h(app, props),
})
root.use(plugin)
root.component('inertia-link', Link)
return root
},
})
}? 注意文件扩展名:显式添加 .vue 后缀(如 ./Pages/${name}.vue),避免 Webpack/Vite 或 Node.js ESM 解析器因无后缀而失败。若使用 Vite SSR,还需确保 ssr.js 在构建配置中被正确识别为 SSR 入口。
⚠️ 其他关键注意事项
- Node.js 版本要求:确保使用 Node.js ≥ 18.12(推荐 ≥ 18.18 或 ≥ 20.9),以获得稳定 ESM 支持和 import() 在服务端的可靠行为。
- SSR 构建与入口一致性:若项目使用 TypeScript,请确认 ssr.js 对应的 .d.ts 类型声明或通过 ts-node/esbuild 正确转译;AdonisJS 用户需确保 ace ssr:watch 命令能识别并监听该文件变更。
- 页面组件导出规范:所有 ./Pages/*.vue 文件必须默认导出一个 Vue 组件(支持 <script setup> 语法),且不能依赖浏览器专属 API(如 window、document),否则 SSR 渲染将抛错。</script>
- 开发环境热重载:inertia.ssr.autoreload: true 仅控制 Inertia 自身的 SSR 服务重启逻辑,实际需配合框架(如 AdonisJS 的 --watch)实现文件变更自动重建。
? 验证是否生效
执行以下命令启动 SSR 服务:
node ace serve --watch node ace ssr:watch
若不再出现 require() of ES Module 错误,且访问页面时 HTML 中包含已服务端渲染的
总之,在 ES 模块环境下,import() 是唯一合规的动态模块加载方式。坚持这一原则,不仅能解决当前 Inertia SSR 报错,更能规避未来因模块混用引发的隐蔽兼容性问题。










