Closed nathanaelphilip closed 6 years ago
I think this is a duplicate of #25. Let me know if the comment there resolves your problem.
I think that may be it, but new Event()
keeps failing during the build: 'Event' is not defined
.
I thought that it was supported, but the vue-cli
builds don’t seem to like it.
i tried this:
let event = document.createEvent('Event')
event.initEvent('vue-post-render', true, true)
but the production build seems to hang up
Edit:
document.dispatchEvent(new window.Event('vue-post-render'))
I was able to do that in main.js
, but the production build still doesn’t run fully.
ok, update – the build process seems to work, but it doesn’t allow the npm run build
to finish properly, which will probably cause issues when we deploy. Locally, the static files work fine though.
very strange
@nathanaelphilip What version of the plugin are you using? The prerendering not correctly reporting when it was finished was a bug in 1.x, but should be fixed in v2.
i’m using 2.0.1
not sure if this helps:
"autoprefixer": "^6.4.0",
"babel-core": "^6.0.0",
"babel-eslint": "^7.0.0",
"babel-loader": "^6.0.0",
"babel-plugin-transform-runtime": "^6.0.0",
"babel-preset-es2015": "^6.0.0",
"babel-preset-stage-2": "^6.0.0",
"babel-register": "^6.0.0",
"chai": "^3.5.0",
"chalk": "^1.1.3",
"chromedriver": "^2.21.2",
"connect-history-api-fallback": "^1.1.0",
"cross-spawn": "^4.0.2",
"css-loader": "^0.25.0",
"email-validator": "^1.0.7",
"eslint": "^3.7.1",
"eslint-config-standard": "^6.1.0",
"eslint-friendly-formatter": "^2.0.5",
"eslint-loader": "^1.5.0",
"eslint-plugin-html": "^1.3.0",
"eslint-plugin-promise": "^3.4.0",
"eslint-plugin-standard": "^2.0.1",
"eventsource-polyfill": "^0.9.6",
"express": "^4.13.3",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"function-bind": "^1.0.2",
"html-webpack-plugin": "^2.8.1",
"http-proxy-middleware": "^0.17.2",
"inject-loader": "^2.0.1",
"isparta-loader": "^2.0.0",
"json-loader": "^0.5.4",
"karma": "^1.3.0",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.2.0",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sinon-chai": "^1.2.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.26",
"karma-webpack": "^1.7.0",
"lolex": "^1.4.0",
"mocha": "^3.1.0",
"nightwatch": "^0.9.8",
"node-emoji": "^1.4.3",
"node-sass": "^4.0.0",
"opn": "^4.0.2",
"ora": "^0.3.0",
"paper": "^0.10.2",
"phantomjs-prebuilt": "^2.1.3",
"prerender-spa-plugin": "^2.0.1",
"rs-breakpoints": "^0.0.5",
"sass-loader": "^4.1.0",
"selenium-server": "2.53.1",
"semver": "^5.3.0",
"shelljs": "^0.7.4",
"sinon": "^1.17.3",
"sinon-chai": "^2.8.0",
"url-loader": "^0.5.7",
"velocity-animate": "^1.4.0",
"vue-head": "^2.0.10",
"vue-loader": "^10.0.0",
"vue-resource": "^1.0.3",
"vue-router": "^2.1.3",
"vue-style-loader": "^1.0.0",
"vue-svg-loader": "^0.1.2",
"vue-template-compiler": "^2.1.0",
"vuex": "^2.1.1",
"webpack": "^1.13.2",
"webpack-dev-middleware": "^1.8.3",
"webpack-hot-middleware": "^2.12.2",
"webpack-merge": "^0.14.1"
Hmm, I might be misunderstanding then. Can you describe in more detail what you mean by this?
it doesn’t allow the
npm run build
to finish properly
You’ll see here that if I remove the {captureAfterDocumentEvent: 'vue-post-render'}
line from the webpack config, it finishes the build process. If I add it back in, it never stops processing. But if i look at the static files, all of my JS fires properly on the build with {captureAfterDocumentEvent: 'vue-post-render'}
enabled (even though the process doesn’t stop). So static site is getting built – but we can’t deploy properly if the script never finishes.
Interesting. It looks like despite being asynchronous, the DOMContentLoaded
callback is being run just before PhantomJS reports the page is loaded. You can force the event to fire in the following tick (when we're actually listening for it) with this hack:
document.addEventListener('DOMContentLoaded', function () {
setTimeout(function () {
document.dispatchEvent(new Event('vue-post-render'))
}, 1)
})
I think I'll add a note about this in the README.
I’ve added that code and it’s still not finishing – is there a way to see which errors are happening? I tried --verbose but that doesn’t really help.
If there are runtime errors while rendering, they should actually be printed to the console. If they aren't in your case, there must be a bug. 😕 I'm pretty slammed right now, but I'll take a look at it when I can. If you get to it sooner and discover something, pull requests are welcome!
Same here, building hangs forever when using the captureAfterDocumentEvent
I tried moving the event from beforeMount to created, but neither seems to work.
Same thing for me. The build actually succeeded once, but every other time I've tried it just hangs (and never times out either).
Edit: wrapping the dispatchEvent in a setTimeout seems to have fixed it.
@Hyra try moving that to mounted.
Hi @nathanaelphilip ! Are you still having this issue?
hey @drewlustro i think my coworker figured it out. feel free to close!
@nathanaelphilip Would you mind sharing your solution? I'm running into the same issue.
hi @stursby I didn’t come up with the solution, but here’s the cod:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import VueRouter from 'vue-router'
import VueHead from 'vue-head'
import VueResource from 'vue-resource'
import App from './App'
import store from './store'
import routes from './routes'
import VueAnalytics from 'vue-analytics'
import comm from './comm'
Vue.use(VueRouter)
Vue.use(VueHead)
Vue.use(VueResource)
const router = new VueRouter({
mode: 'history',
root: '/',
routes // short for routes: routes
})
Vue.use(VueAnalytics, { id, router })
let root = new Vue({
router,
store,
render: h => h(App)
})
document.addEventListener('DOMContentLoaded', function () {
root.$mount('#app')
})
@nathanaelphilip Ok, I have essentially the exact same thing... but am trying to use captureAfterDocumentEvent
method. What does your PreloadWebpackPlugin
config look like if you don't mind me asking?
i don’t think i have that...
this is the production conf:
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
template: 'index.html',
inject: 'head',
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// prerendering
new PrerenderSpaPlugin(
path.join(__dirname, '../dist'),
[ '/', '/features', '/terms', '/privacy' ]
),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),
I'm having the same issue. But with one difference.
I have a page with dynamic content loaded via AJAX. after a successful request, i'm setting data with this.product = response.body
and call
document.dispatchEvent(new Event('custom-post-render-event'))
Executing npm run build
runs fine, generating static html files, boom, thank you.
Trying to render a static page (like /contact, no initial ajax calls) results in the behavior above. npm run build
never finishes. I'm calling document.dispatchEvent(new Event('custom-post-render-event'))
directly in the created() hook inside my contact component.
I tried it with
document.dispatchEvent(new Event('custom-post-render-event'))
-> no success
also
this.$nextTick(() => {
document.dispatchEvent(new Event('custom-post-render-event'))
})
-> no success
i tried it with
setTimeout(() => {
document.dispatchEvent(new Event('custom-post-render-event'))
}, 3000)
--> success
So i think it might be a timing problem that the event gets fired before the eventListener is set up (but it's just a thought)
I searched a little, added some console outputs etc. In phantom-page-render.js
is the distinction between the render trigger options. Using a custom event it depends on phantomjs's onCallback
event which is marked as experimental (http://phantomjs.org/api/webpage/handler/on-callback.html). ATM i'm trying to get a workaround if this is the line where the capture process hangs (I never used phantomJS before, so i have no clue what I'm doing :D)
If anyone has a tip, feel free :)
The more this issue resurfaces, the more I am convinced that it is a phantomjs issue, as noted by @hurradieweltgehtunter . Thanks for all your investigation into this – if anyone finds a concrete solution, please let me know!
Why aren't you using the window.callPhantom()
method as event triggered rendering method?
in mypage.html:
if (typeof window.callPhantom === 'function') {
window.callPhantom({ hello: 'world' });
}
in phantomJS (serverside)
var webPage = require('webpage');
var page = webPage.create();
page.onInitialized = function() {
page.onCallback = function(data) {
console.log('CALLBACK: ' + JSON.stringify(data));
// Prints 'CALLBACK: { "hello": "world" }'
};
}
(taken from http://phantomjs.org/api/webpage/handler/on-callback.html)
I made it work in a test, only problem was that it told me, that it needed a polyfill for this browser. I stopped at this point for now but maybe this could work?
What kind of polyfill did it need? Unfortunately PhantomJS has been sunset, so we won't see any next-generation browser features implemented until the capture engine is replaced with Chrome Headless.
Having the same issues using latest vuejs and prerender-spa-plugin:
If anybody has solution or idea please do share.
A little update about the issue, after lot of tinkering around with the code, I decided to update some packages. Surprisingly it worked! No more stuck on 'building for production' BUT still js will not fire for vuejs 2 app. :(
Here is repo with changes that worked: https://github.com/mubaidr/prerender-spa-plugin
Same here. Cant get it work when using either captureAfterElementExists or captureAfterDocumentEvent. And when skipping them I only get the CSS pre-rendered, but not the HTML.
Hi,
We are experiencing the same issue. We're using the advanced configuration captureAfterDocumentEvent :
new Promise(resolve => {
axios.get(url).then((res) => {
console.log(res.data);
this.message = res.data.short_name;
resolve();
});
}).then(() => {
document.dispatchEvent(new Event('fetch-done'));
});
We also tried it this way :
setTimeout(function () {
document.dispatchEvent(new Event('custom-post-render-event'));
}, 3000);
But none of them worked. Running the 'npm run build' command takes a really long while, waited for it for an hour and a half to pre-render a single route '/' and got an out of memory error.
Same problem here. JS never gets executed.
PS: In my case it was the ES6
problem. PhantomJS
does not support ES6
yet. They were going to introduce it in 2.5
version but looks like it will never be released.
Same problem using code splitting. My <router-view>
doesn't render, only my <footer>
component in App.vue.
Hi Everyone,
Having the same issue with my npm run build
seemingly hanging up. Been scratching my head on this for hours so I figured I'd ask for help.
For context, I'm using the vue webpack boilerplate.
Here's my configuration in webpack.prod.conf.js
(option to use captureAfterDocumentEvent
):
new PrerenderSpaPlugin(
// Absolute path to compiled SPA
path.join(__dirname, '../dist'),
// List of routes to prerender
[ '/', '/about', '/donate', '/subscribe', '/contact' ],
{captureAfterDocumentEvent: 'custom-post-render-event'}
),
Main.js:
import Vue from 'vue'
import VeeValidate from 'vee-validate'
import VuePaginate from 'vue-paginate'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
Vue.use(VeeValidate)
Vue.use(VuePaginate)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App }
})
Action (I dispatch my event, custom-post-render-event
, here after my API call):
export const trimmerActions = {
async getTrimmers({ commit }) {
commit('setTrimmers', await TrimmerService.fetchTrimmers())
document.dispatchEvent(new Event('custom-post-render-event'))
}
}
My dispatch to the action from my component (I even tried putting the dispatchEvent
in created()
:
...
async created() {
try {
await this.$store.dispatch('getTrimmers')
// (tried this as well) document.dispatchEvent(new Event('custom-post-render-event'))
} catch(e) {
console.warn(e)
}
},
computed: {
trimmers() {
return this.$store.getters.allTrimmers
},
...
Here's even my mutation:
export const trimmerMutations = {
setTrimmers(state, payload) {
state.trimmers = payload.data
}
}
Locally, my asynchronous call works fine and the DOM eventually loads with the dynamic content. However, I can't figure out why the prerender-spa-plugin script hangs up. Could it be something with my configuration? I'm using "prerender-spa-plugin": "^2.1.0",
and "vue": "^2.5.2",
if that helps.
Another thing I noticed was that when I installed prerender-spa-plugin
there was a message, phantomjs not found on path
. Seemed just like a warning but I want to mention it in-case it's critical.
@hurradieweltgehtunter , I believe I'm trying to accomplish what you successfully did in your case 1: Dynamic pages. Do you happen to have any insight?
Are we coming to the conclusion that we can't use captureAfterDocumentEvent
? When I remove this option from the plugin the build is able to successfully complete and all my static pages are created as expected (knowing that I won't have my asynchronous data prerendered).
Thanks in advance everyone for any help.
Just to add, I also tried captureAfterElementExists
on its own which succesfully generated my /dist/index.html
but npm run build
still hung. I think @bobmoff was having a similar issue with the build hanging. So close!
Anyone solve this problem?
bump
Anyone solve this problem?
Even if I am able to generate static pages with captureAfterDocumentEvent
(prerender-spa-plugin
finishes good), vuejs JavaScript/events does not work.
@mubaidr I had a similar issue where my Vue component wasn't being mounted and it came down to something as simple as id="app"
was being removed in the prerender stage so there was no identifier to mount Vue
to 🙈. Hope that helps!
Hmm... interesting. I will see if that is the case. Definitely worth a try. 👍
Any update on this issue?
+1
I am doing a major re write of this module, lets hope I can fix it. 🔢
Thanks @mubaidr and thanks for keeping us updated!
I have created a new plugin inspired by this one, you can follow progress here: https://github.com/mubaidr/prerender-plugin
@mubaidr Awesome! I looked through the issues but wasn't quite able to tell, have you gotten the custom-document-event
option to work?
@asaldivar Yes. The new plugin is not based on this one, it is re-written entirely. So, go ahead and try it.
Thanks so much! I'll try today!
Anyone got the solution?
same problems here :(
Hi Chris!
Thanks for the plugin and the demos!
I’ve got the build running properly, and the static pages are rendered, but no JS seems to be loading. I have a few
@clicks
and@submits
that aren’t firing when clicked. Is there another step when you have some JS that allows the user to interact with the page?in main.js
the other configs are set up like the example in the Vue Spa repo.