-
Notifications
You must be signed in to change notification settings - Fork 246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: 500 error using Vue+Meteor SSR after update vue-meta
version to 2.3.4
#569
Conversation
…g `vue-meta` with Vue Meteor SSR
Codecov Report
@@ Coverage Diff @@
## master #569 +/- ##
=======================================
Coverage 98.68% 98.68%
=======================================
Files 33 33
Lines 684 684
Branches 211 211
=======================================
Hits 675 675
Misses 5 5
Partials 4 4
Continue to review full report at Codecov.
|
vue-meta
version to 2.3.4vue-meta
version to 2.3.4
@mrauhu Hey, thanks for this PR. Could you please create a reproduction of the issue you are experiencing? After reading your explanation it doesnt become immediately clear unfortunately what you are trying to solve. You mention Thanks! |
@pimlie I'm created the repository with code and instructions for reproduction of the bug: Thank you for participating. |
@mrauhu Thanks for the repro. I have little xp with Meteor but why does the beforeMount / mounted Vue lifecycle hook run at all when there is no global document available? The Vue SSR docs state that these methods dont run during SSR, so why do they run for Meteor? |
I'm updated the repository, and added logs for Vue lifecycle hooks: First runOn a server reload after change any Server
Log with timestamps and full stack trace
Client
Next runsOn page reload. Server
Log with timestamps and full stack trace
Client
@pimlie my suggestion is instead of debugging the Vue+Meteor platform add one check for the Line 43 in 5b0c2ad
|
@atinux @manniL What do you think, should we merge this? Its not a big fix, but still it seems wrong to fix something that shouldn't happen in the first place. The Vue SSR docs clearly state the mounted hooks shouldnt run, but for some reason they do with Meteor. Im slightly leaning to not merging until we know why Meteor behaves differently then the Vue SSR docs specify as it could just be an upstream bug in Meteor |
Agree @pimlie |
You sure you want to merge? I can take a look at the Meteor Vue package and see if I can fix it there. If this makes it into nuxt it might lead to other people with problems. |
@chris-visser If you could have a look that would be awesome! I have zero to none xp with meteor, so maybe it is correct that mounted hooks runs on ssr and we should just merge this. But if not then either there is a bug in vue-meteor or a bug/config issue in the reproduction. I did check the vue-meteor-ssr example (which it seems the repro is based on) and I didnt notice anything wrong. |
If its a Meteor Vue SSR bug, its fixable via Meteor Vue and it will be there within a very short time. I would not recommend merging this |
@chris-visser thank you for debugging. |
I have been diving trough the Vue code, but there seems to be nothing that prevents the beforeMount hook from triggering on the server: https://github.com/vuejs/vue/blob/dev/src/core/instance/lifecycle.js#L141 export function mountComponent (
vm: Component,
el: ?Element,
hydrating?: boolean
): Component {
vm.$el = el
if (!vm.$options.render) {
vm.$options.render = createEmptyVNode
if (process.env.NODE_ENV !== 'production') {
/* istanbul ignore if */
if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
vm.$options.el || el) {
warn(
'You are using the runtime-only build of Vue where the template ' +
'compiler is not available. Either pre-compile the templates into ' +
'render functions, or use the compiler-included build.',
vm
)
} else {
warn(
'Failed to mount component: template or render function not defined.',
vm
)
}
}
}
callHook(vm, 'beforeMount') If this is true, then maybe it is valid to accept this PR and that would fix it for Meteor too. However, maybe its just better to check if this.$el is defined? |
@chris-visser there is already check for Line 39 in 14eb4af
And this check do nothing with an undefined |
What I mean is that the Vue instance does this: el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating) The The below code would return a falsey value, because this.$el is on the server always undefined. That means that wasServerRendered = this.$el && this.$el.nodeType === 1 && this.$el.hasAttribute('data-server-rendered') Any check for the opposite would of course result in exactly the opposite - which is the bug that you now have: !wasServerRendered && $root[rootConfigKey] && $root[rootConfigKey].appId === 1 This one results in true on the server: |
Thanks for your contribution to vue-meta! This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you would like this issue to remain open:
|
@chris-visser Thanks for your time looking into this! And sorry for the late response, but its still unclear why the beforeMount hook is even run on the server. @mrauhu I am very sorry but I dont want to merge a fix in, however simple it is, just because we didnt uncover the real cause of the issue. Again, this section: https://ssr.vuejs.org/guide/universal.html#component-lifecycle-hooks of the Vue SSR docs clearly state that beforeMount should only run on the client and isnt executed on the server. So I dont know whats going wrong here but it seems there is either a bug in vue, vue-server-renderer or vue-meteor? Although if this was a general vue or vue-server-renderer issue then I would have expected that we had also seen this issue with Nuxt.js, but as we haven't my guess is still that this is a vue-meteor issue. These beforeMount hooks and the var The only recommenddation I can give you is to try if you can narrow it down by trying the following things:
export default {
beforeMount() {
console.log('SFC beforeMount')
}
export default {
mixins: [myMixinWithBeforeMountHook]
export default {
beforeCreate() {
this.$once('hook:beforeMount', () => console.log('SFC beforeCreate listen'))
export default {
mixins: [myMixinWithBeforeCreateHookThatListensToBeforeMount] If any of these are logging something on the server then it would be an indication of a vue-meteor issue. |
@pimlie thank you for the recommendation. |
Greetings, @pimlie
This pull-request fixes the 500 error with
document is not defined
message when we using Vue Meta and Vue+Meteor SSR.Problem is the Vue+Meteor SSR package doesn't have
this.$el
onhook:beforeMount
, so thegetTag()
function is called in{ ssr: true }
context.Bug was introduced in #563.
Best wishes,
Sergey.