生产环境用Inertia渲染Vue组件时currentRenderingInstance.ce为null
Laravel 11 + Inertia Vue3生产环境渲染空白,报错
TypeError: Cannot read properties of null (reading 'ce') 问题现象
使用Laravel 11、Inertia.js与Vue 3构建的多页Web应用,通过Coolify搭配nixpacks部署到服务器后:
- 服务器请求响应正常,无后端报错
- 客户端页面短暂渲染后变为空白,查看HTML发现Vue组件已被卸载
- 控制台抛出异常:
TypeError: Cannot read properties of null (reading 'ce'),该错误触发于resources/js/app.ts的应用挂载阶段,原因是currentRenderingInstance为null
已排查信息
- 环境差异:本地将
NODE_ENV和APP_ENV设为production无法复现问题,仅生产服务器出现 - 触发条件:仅在使用自定义组件(如
Column.vue)时触发,使用纯HTML不导入组件则无异常 - 初步推测:怀疑是多版本Vue同时运行导致,但尚未验证成功;尝试在vite.config.js中配置Vue解析和去重,无效果
错误代码片段
错误发生在Vue的runtime-core.esm-bundler.js中:
function renderSlot(slots, name, props = {}, fallback, noSlotted) { if (currentRenderingInstance.ce || currentRenderingInstance.parent && isAsyncWrapper(currentRenderingInstance.parent) && currentRenderingInstance.parent.ce) { if (name !== "default") props.name = name; return openBlock(), createBlock( Fragment, null, [createVNode("slot", props, fallback && fallback())], 64 ); } // ...
相关代码示例
测试页面组件
<script setup lang="ts"> import {Head} from "@inertiajs/vue3"; import Column from "@/components/utils/Column.vue"; </script> <template> <div> <Head title="Log in" /> <Column> hi! </Column> </div> </template>
Column.vue组件
<script setup lang="ts"> import {cn} from "@/lib/utils"; import {type Component, type HTMLAttributes} from "vue"; import type {AsTag} from "radix-vue"; const props = withDefaults( defineProps<{ class?: HTMLAttributes['class'], as?: AsTag | Component }>(), { as: "div" } ); </script> <template> <component :is="as" :class="cn('flex flex-col justify-center items-start w-full', props.class)"> <slot /> </component> </template>
配置文件
package.json
{ "private": true, "type": "module", "scripts": { "dev": "vite", "typecheck": "vue-tsc", "build": "vite build", }, "devDependencies": { "@tailwindcss/forms": "^0.5.3", "@vitejs/plugin-vue": "^5.0.0", "autoprefixer": "^10.4.12", "laravel-vite-plugin": "^1.0", "postcss": "^8.4.31", "tailwindcss": "^3.2.1", "typescript": "^5.5.3", "vite": "^5.0", "vue": "^3.5.13", "vue-tsc": "^2.0.24" }, "dependencies": { "@iconify/vue": "^4.1.2", "@inertiajs/vue3": "^1.0.0", "axios": "^1.7.4", "@dzangolab/vue-country-flag-icon": "^0.3.0", "@inertia-vue-form/zod": "^0.1.1", "@tanstack/vue-table": "^8.20.5", "@vee-validate/zod": "^4.13.2", "@vitejs/plugin-vue-jsx": "^4.0.1", "@vueuse/core": "^11.1.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "date-fns": "^4.1.0", "lucide-vue-next": "^0.446.0", "radix-vue": "^1.9.6", "tailwind-merge": "^2.5.2", "tailwindcss-animate": "^1.0.7", "vaul-vue": "^0.2.0", "vee-validate": "^4.13.2", "vue-json-viewer": "^3.0.4", "zod": "^3.23.8" } }
vite.config.js
import {defineConfig} from 'vite'; import laravel from 'laravel-vite-plugin'; import vue from '@vitejs/plugin-vue'; import {fileURLToPath, URL} from "url"; import vueJsx from '@vitejs/plugin-vue-jsx' export default defineConfig({ plugins: [ laravel({ input: ['resources/js/app.ts', 'resources/css/app.css'], refresh: true, }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), vueJsx({}) ], resolve: { alias: [ {find: '~', replacement: fileURLToPath(new URL('./resources/js', import.meta.url))}, {find: '@', replacement: fileURLToPath(new URL('./resources/js', import.meta.url))}, {find: '@pages', replacement: fileURLToPath(new URL('./resources/js/pages', import.meta.url))}, {find: '@layouts', replacement: fileURLToPath(new URL('./resources/js/layouts', import.meta.url))}, {find: '@components', replacement: fileURLToPath(new URL('./resources/js/components', import.meta.url))}, // 尝试过在此配置Vue解析,无效果 ] }, build: { sourcemap: true, }, });
resources/js/app.ts
import './bootstrap'; import '../css/app.css'; import {createApp, DefineComponent, h} from 'vue'; import {createInertiaApp} from '@inertiajs/vue3'; import {resolvePageComponent} from 'laravel-vite-plugin/inertia-helpers'; import {ZiggyVue} from '../../vendor/tightenco/ziggy'; import.meta.glob('../images/**'); const appName = import.meta.env.VITE_APP_NAME || 'ImagineY'; createInertiaApp({ title: (title) => `${title} - ${appName}`, resolve: (name) => resolvePageComponent(`./pages/${name}.vue`, import.meta.glob<DefineComponent>('./pages/**/*.vue')), setup({el, App, props, plugin}) { createApp({ render: () => h(App, props), }) .use(ZiggyVue) .use(plugin) .mount(el); }, progress: { color: '#4B5563' }, }).catch(error => console.error(error));
resources/views/app.blade.php
<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title inertia>{{ config('app.name', 'ImagineY') }}</title> <!-- Scripts --> @routes @vite(['resources/js/app.ts']) @inertiaHead </head> <body class="font-sans antialiased @if (session('dark-mode')) dark @endif"> @inertia </body> </html>
请求帮助
已尝试在vite.config.js中配置Vue别名解析和去重,但未解决问题。希望得到针对该问题的排查思路或具体解决方案。
内容的提问来源于stack exchange,提问作者Matthias Vandersanden
相关产品推荐
相关产品推荐

