我正在尝试为使用Inertia和Laravel构建的Vue.js SPA设置服务器端渲染。每当我尝试加载包含Map的页面时,我都会从SSR服务器进程中获得如下错误:
[Vue warn]: Unhandled error during execution of setup function
at <Map errors= {} venues= [
{
name: 'Some Hall',
lat: '45.492480',
lng: '0.336327',
address: '1 Interesting Street',
url: 'http://localhost/venues/some-hall'
},
**** Lots more prop data elements here ****
}
] key=null >
TypeError: Loader is not a constructor
at setup (file:///var/www/html/bootstrap/ssr/ssr.js:510:20)
at _sfc_main$4.setup (file:///var/www/html/bootstrap/ssr/ssr.js:613:25)
at callWithErrorHandling (/var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:156:18)
at setupStatefulComponent (/var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7244:25)
at setupComponent (/var/www/html/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7205:36)
at renderComponentVNode (/var/www/html/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:614:15)
at renderVNode (/var/www/html/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:743:14)
at renderComponentSubTree (/var/www/html/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:698:7)
at renderComponentVNode (/var/www/html/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:631:12)
at renderVNode (/var/www/html/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:743:14)
字符串
该网站使用composer包laravel/ [[email protected]](https://stackoverflow.com/cdn-cgi/l/email-protection)
和inertiajs/ [[email protected]](https://stackoverflow.com/cdn-cgi/l/email-protection)
。我的package.json
看起来像这样:
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && vite build --ssr"
},
"devDependencies": {
"axios": "^1.1.2",
"laravel-vite-plugin": "^0.8.0",
"vite": "^4.0.0"
},
"dependencies": {
"@googlemaps/js-api-loader": "^1.16.2",
"@inertiajs/vue3": "^1.0.12",
"@vitejs/plugin-vue": "^4.4.0",
"@vue/server-renderer": "^3.3.7",
"bootstrap": "^5.3.2",
"vue": "^3.3.6"
}
}
型
我的resources/js/app.js
看起来像这样:
import {createSSRApp, h} from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true });
return pages[`./Pages/${name}.vue`];
},
setup({ el, App, props, plugin }) {
createSSRApp({ render: () => h(App, props) })
.use(plugin)
.mount(el);
},
});
型
我的resources/js/ssr.js
看起来像这样:
import { createInertiaApp } from '@inertiajs/vue3'
import createServer from '@inertiajs/vue3/server'
import { renderToString } from '@vue/server-renderer'
import { createSSRApp, h } from 'vue'
createServer(page =>
createInertiaApp({
page,
render: renderToString,
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
setup({ App, props, plugin }) {
return createSSRApp({
render: () => h(App, props),
}).use(plugin)
},
}),
)
型
到目前为止,我一直在寻找答案,这是否是一个CommonJS/ESM兼容性问题(尽管我并不完全理解这一点),所以在导入js-api-loader
模块时,我尝试了以下两种方法:
// Initially this...
import { Loader } from "@googlemaps/js-api-loader";
// And also this...
import * as GMaps from '@googlemaps/js-api-loader'
const { Loader } = GMaps
型
据我所知,第二个选择是处理CJS模块,但我不认为Google模块使用CommonJS标准,据我所知。
在我的*.vue
页面中,似乎导致错误的代码是:
const loader = new Loader({
apiKey: env.google_maps_api_key,
version: "weekly",
libraries: ['places'],
});
型
真的很感激一些指导!
更新
我在报告错误的地方放了一些console.log()
行:
const { Loader } = GMaps;
const props = __props;
console.log(GMaps);
console.log(Loader);
const loader = new Loader({
apiKey: env.google_maps_api_key,
version: "weekly",
libraries: ["places"]
});
型
输出为:
[Module: null prototype] {
default: {
LoaderStatus: {
'0': 'INITIALIZED',
'1': 'LOADING',
'2': 'SUCCESS',
'3': 'FAILURE',
INITIALIZED: 0,
LOADING: 1,
SUCCESS: 2,
FAILURE: 3
},
DEFAULT_ID: '__googleMapsScriptId',
Loader: [Function: o]
}
}
undefined
型
1条答案
按热度按时间vdzxcuhz1#
好吧,我现在已经解决了这个问题,但我真的不明白发生了什么。如果有人能提供一个更好的解释,在模块类型,导入,节点和浏览器方面,我很乐意改变接受的答案。
基本上,我的工作导入现在看起来像这样:
字符串
似乎在一个示例中(我想是浏览器?),模块被导入为包含模块导出属性的对象(即
{ LoaderStatus: ..., DEFAULT_ID: ..., Loader: ... }
),而在另一个示例中(我想是服务器上的节点),模块被导入 Package 在父对象的default
属性(即{ default: { LoaderStatus: ..., DEFAULT_ID: ..., Loader: ... }}
)中。我不知道为什么。上面的解决方案基本上使用
??
操作符首先尝试解构default
属性,如果它存在,如果不存在,则返回到解构父对象本身。这些链接帮助我走了这么远。