Skip to content

Instantly share code, notes, and snippets.

@rtfleg
Last active January 29, 2018 10:19
Show Gist options
  • Save rtfleg/cc159e4f773a8a3d9ec3a0f8ca821464 to your computer and use it in GitHub Desktop.
Save rtfleg/cc159e4f773a8a3d9ec3a0f8ca821464 to your computer and use it in GitHub Desktop.
awaitDevtools function for vuejs dev-tools, provides promise which resolves after dev-tools ready state is determined.
import Vue from "vue"
import store from "./store";
import { awaitDevtools, refreshDevtools } from "./awaitDevtools";
awaitDevtools()
.then(bootstrapApp)
.then(refreshDevtools); // Refresh is required in order to deal with missing component tree and another issues.
function bootstrapApp() {
new Vue({
el: "#app",
store,
template: "<p>Hello world</p>",
created() {
// Dispatch some actions or make some commits here.
// All the store changes will be reflected inside devtools :-)
}
});
}
// NOTE:
// You can bootstrap app in the regular way and use awaitDevtools wherever you want.
// For example you can do something like this:
new Vue({
el: "#app",
store,
template: "<p>Hello world</p>",
created() {
awaitDevtools() // <-- just use it in lifecycle hook, refreshDevtools is not needed now of course.
.then(() => {
// Dispatch some actions or make some commits here.
// All the store changes will be reflected inside devtools :-)
});
}
});
let promise = null;
/**
* Returns promise which resolves after devtools ready state became determined (see awaitDevtoolsImpl below).
* @param {number} [timeout] - devtools ready state detection timeout (one second by default).
* @returns {Promise.<boolean|null>}
*/
export function awaitDevtools(timeout) {
return promise ? promise : (promise = awaitDevtoolsImpl(timeout || 1000));
}
/**
* Refreshes devtools, useful if you bootstrap app inside callback of the promise which returned by awaitDevtools.
* Call that function after app bootstrapped in order to deal with missing component tree and so on.
*/
export function refreshDevtools() {
window.postMessage({ source: "vue-devtools-proxy", payload: "refresh" }, "*");
}
/**
* Returns promise which resolves after devtools ready state became determined.
* This promise will be resolved in any case (we need to bootstrap app after all) except some internal error happens.
*
* Possible promise results are:
* - false - devtools are not available at the moment (good);
* - true - devtools are available and ready (good);
* - null - unable to determine devtools ready state (bad, some commits might be not reflected in devtools).
*
* NOTE:
* Function will work only in case devtools tab is opened before page load, in opposite case it's useless.
* So, if you have problems with it, then switch to devtools tab and refresh the page.
*
* @param {number} timeout - devtools ready state detection timeout.
* @returns {Promise.<boolean|null>}
*/
function awaitDevtoolsImpl(timeout) {
if (!window["__VUE_DEVTOOLS_GLOBAL_HOOK__"])
return Promise.resolve(false);
return new Promise(
resolve => {
window.addEventListener("message", onMessage, false);
const timeoutId = setTimeout(() => onTimeout(), timeout);
function onMessage(e) {
if (isReadyMessage(e)) {
clearTimeout(timeoutId);
resolve(true);
}
}
function onTimeout() {
window.removeEventListener("message", onMessage);
resolve(null);
}
function isReadyMessage(e) {
return e
&& e.data
&& e.data.source == "vue-devtools-backend"
&& e.data.payload
&& e.data.payload.event == "ready";
}
}
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment