Closed lerouxju closed 8 years ago
The file you are importing is the standalone build that assumes browser environment. But regardless, I don't think it's possible (or involves non-trivial effort) to do Vue SSR in PHP V8js because:
vue-server-renderer
package has other Node package dependencies, e.g. he
and de-indent
. This can be solved by bundling the whole package and these dependencies into one file;vm
and stream
. So even if you can get normal SSR working, you wouldn't be able to use stream mode or the bundleRenderer
.Basically, this is not something we are planning to work on, but we are definitely open to community contributions if anyone wants to make it work.
This is also a major decision blocker between React and Vuejs. The react have a v8js plugin and works perfectly. I can allocate sometime next week to look if I can get any workaround. But if anyone have any progress in this use case, please inform here in this topic
Sever-side rendering without a node dependency would be a huge improvement for us as our backend heavily depends on a python stack. A V8 plugin would come in very handy.
Has any progress been made in this area? The Laravel community really needs something like this where Vuejs is concerned.
If vue has to be used with php(Laravel), Then we have to sacrifice SEO for app. If you need SEO (Serverside Rendering), Then you have to rely on node.js.If v8js is supported in vue, then that will be huge help to laravel community.
Has any progress been made in this area?
How cool would it be to have a blade directive @render_vue('my-vue-component', ['prop' => 1]) ?
Maybe you can try this package https://github.com/lukechilds/browser-env if you had document not defined
I'm not sure yet
+1
We definitely need a workaround for setTimeout and the other missing things in non-Node V8 implementations.
I was trying to render my Vue.js app with some Go-based JS environments the other day and it didn't work for the same reason – setTimeout missing.
+1
@yyx990803 Could you please revisit this issue ?
@yyx990803 would be really awesome to have this! +9001
Please, do not spam. The answer below is clear We are open to community contributions, so if you have something to share, please, do it by commenting here. But do not comment to say +1 or Any updates? or any equivalent phrase This issue may also be interesting: https://github.com/vuejs/vue/issues/5415
It looks like (nearly?) all the calls to setTimeout are using it to either defer a function call immediately (so they'll be called next pass in the event loop, ie 4ms), or for transition effects (which would be irrelevant for server side rendering).
A vue solution would be to implement your own stack to push functions to run on the next tick to instead of using setTimeout's stack. Shouldn't be too hard to write, but personally I rather like the pattern of using setTimeout
to push await things I don't want blocking me.
This could be solved outside of vue by using an event loop implementation in your V8js. It does support a sleep()
function already, which is all you'd really need to create your own loop with setTimeout & setInterval implemented. For it to work with php, ultimately your code will need to resolve at some point (ie resume synchronous execution), so doing events more advanced than that could be tricky (and some may argue, not very valuable).
let timeouts = [];
window.setTimeout = (cb, delay = 0, ...args) => {
timeouts = timeouts.concat({ cb, args, end: Date.now() + delay });
};
/* require your actual code..., then: */
const endTimeCompare = ({ end: a }, { end: b }) => a - b;
timeouts = timeouts.sort(endTimeCompare);
while (timeouts.length > 0) {
sleep(0.004);
const runNow = timeouts.filter(({ end }) => end <= Date.now());
for (const { cb, args } of runNow) cb(...args);
timeouts = timeouts.filter(timeout => !runNow.includes(timeout)).sort(endTimeCompare);
}
I'm writing this from bed at midnight, haven't run any of this, am sure there's some es7 I'll need to make less-pretty so it works on older engines, and am very sleepy, but you can get the general idea from this. Please let me know if this idea solves what everyone's looking for here, and I'll make a repo and put this in with something that includes setInterval too.
This may be of interest to those finding this thread in the future: Server-Side Rendering With Laravel and Vue.js 2.5
@SevenEcks Legendary! :tada: Thank you.
Feature description
PHP V8Js allows to execute JS server side. It is some sort of alternative to node.js.
Currently it is not possible to execute Vue.js this way. It complains that "setTimeout" & "document" are not defined.
As Vue.js is running fine server side with node.js it should be possible to run it with PHP V8Js.
Code sample
`<?php
$vueSource = file_get_contents('https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js'); $v8 = new V8Js(); $result = $v8->executeString($vueSource); ?>`
Result
V8Js::executeString():5628: ReferenceError: document is not defined"