Vuejs DevTools not showing panel in developer tools - vue.js

I cannot get the vue development tools to show it's panel.
I've tried deleting and re-installing the extension, Hard refreshing, closing the tools and opening again, adding Vue.config.devtools = true; and a combination of all of them and it still does not show the panel. Any ideas?
I did notice that __VUE_DEVTOOLS_GLOBAL_HOOK__ doesn't have a Vue value... but I don't have a working dev tool to see if that should be otherwise.
macOS Catalina (version 10.15.5)
Version 83.0.4103.106 (Official Build) (64-bit)

UPDATE: Turns out the devTool github repo had an even better answer:
const app = new Vue(vueConfig).$mount('#app');
window.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue = app.constructor;
See here: https://github.com/vuejs/vue-devtools
Turns out it was a jest work around that was causing the problem. My jest tests weren't working with my normal vue instance so I had to mock it with the createLocalVue.
const localVue = createLocalVue();
localVue.use(VueRouter);
const router = new VueRouter();
The problem was that some tests were not liking that I had two vue instances (the one in main.js) with a router.
So I added logic to only add the router if it wasn't a test:
import Vue from 'vue';
import VueRouter from 'vue-router';
if (!process || process.env.NODE_ENV !== 'test') {
Vue.use(VueRouter);
}
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
const vueConfig = {
render: (h) => h(App),
};
// excluding for jest tests
if (!process || process.env.NODE_ENV !== 'test') {
vueConfig.router = router;
}
new Vue(vueConfig).$mount('#app');
Unfortunately the if around the Vue.use() is what broke it:
// removing this if() fixed it and the vue dev tools panel now shows up.
if (!process || process.env.NODE_ENV !== 'test') {
Vue.use(VueRouter);
}
Something about the way the dev tools inits needed the router to be installed. I also wonder if they use a process with "test" or something. Either way, this is resolved for me. Hope it helps someone else.

I was facing the same issue and able to solve by avoiding vue.min.js for development purpose. Use original version (vue.js) instead of the minify version.

load the page without Devtools open
press the Vue Devtools button in the extensions area (might say "Vue.js not
detected", but don't let that bother you). In some setups, this step is
crucial.
only then open Devtools by hitting F12. Vue tab should appear (check to the
very right of all tabs, you can drag it to the left)
https://stackoverflow.com/a/62446093/15265413

Related

Quasar SSR app, "window is not defined" from vue-router

I'm taking a fairly simple Vue app built with Quasar, and adding ssr.
I'm using the Quasar CLI, and added ssr with quasar mode add ssr. This created the src-ssr/ folder and files as expected.
When I launch it with quasar dev -m ssr, I get:
App • Opening default browser at http://localhost:9100/
/Users/stevex/src/myapp/node_modules/vue-router/dist/vue-router.cjs:478
const { history, location } = window;
^
ReferenceError: window is not defined
at useHistoryStateNavigation (/Users/stevex/src/myapp/node_modules/vue-router/dist/vue-router.cjs:478:35)
at createWebHistory (/Users/stevex/src/myapp/node_modules/vue-router/dist/vue-router.cjs:570:31)
at Module.eval [as default] (/src/router/index.ts:14:14)
at __vite_ssr_exports__.default (/.quasar/app.js:91:44)
at async eval (/Users/stevex/src/myapp/.quasar/server-entry.js:86:9)
Node.js v18.7.0
Found the problem, it was the history mode.
I was using createWebHistory in routes/index.ts, but for SSR the history mode must be createMemoryHistory. With that change, the server-side-rendered page loads.
Details here:
https://router.vuejs.org/guide/essentials/history-mode.html#memory-mode
The default createHistory checks for the environment and picks a compatible one; I'd replaced that. Here's the default, which works:
const createHistory = process.env.SERVER
? createMemoryHistory
: process.env.VUE_ROUTER_MODE === 'history'
? createWebHistory
: createWebHashHistory;

Vue 3 external component/plugin loading in runtime

I am designing an architecture for the Vue 3 app with distributed module-based ownership. Module system will be represented with plugins (seems like the most appropriate solution allowing vuex module and vue-router dynamic injects). Each such module/plugin will be developed by dedicated team working within isolated repos. We cannot use npm package-per-plugin approach as deployment process should be isolated as well, and with npm approach core app team will have to rebuild app each time npm package plugin has updates. This means we will have to load such plugins/pages at runtime via http.
So far this approach by Markus Oberlehner seems like some sort of the way to go - it uses custom Promise based solution for webpack's missing "load external url script at runtime" functionality. While it works fine with Vue 2, Vue 3 gives VNode type: undefined error.
The above mentioned article offers the following webpack external component loading solution:
// src/utils/external-component.js
export default async function externalComponent(url) {
const name = url.split('/').reverse()[0].match(/^(.*?)\.umd/)[1];
if (window[name]) return window[name];
window[name] = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.async = true;
script.addEventListener('load', () => {
resolve(window[name]);
});
script.addEventListener('error', () => {
reject(new Error(`Error loading ${url}`));
});
script.src = url;
document.head.appendChild(script);
});
return window[name];
}
But above, as I said, does not work with Vue 3 defineAsyncComponent mechanism.
// 2.x version WORKS
const oldAsyncComponent = () => externalComponent('http://some-external-script-url.js')
// 3.x version DOES NOT WORK
const asyncComponent = defineAsyncComponent(
() => externalComponent('http://some-external-script-url.js')
)
So I have two questions:
Are there any known better solutions/suggestions for above architectural specification?
Is there any working webpack dynamic external import solutions tested with Vue 3 out there?
UPD: Here is small reproduction repo
We solved this problem together via chat.
Components built via the Vue 3 vue-cli rely on Vue being available in the global scope. So in order to render components loaded via the technique described in my article, you need to set window.Vue to a reference to Vue itself. Then everything works as expected.
update:
If import vue from vue/dist/vue.esm-bundler and set to global, then no need to change webpack / Vite config, and no need to load vue from cdn.
import * as Vue from 'vue/dist/vue.esm-bundler';
window.Vue = Vue;
Besides setting window.Vue, some other webpack or Vite configuration should also be set, otherwise some error is presented in console: vue warn invalid vnode type symbol(static) (symbol)
Vue3 + webpack:(https://github.com/vuejs/vue-next/issues/2913#issuecomment-753716888)
// index.html:
<script src="https://cdn.jsdelivr.net/npm/vue#3.0.4"></script>
// vue.config.js
configureWebpack: config => {
...
config.externals = { vue: 'Vue' }
...
}
Vue3 + vite:(https://github.com/crcong/vite-plugin-externals)
// vite.config.js
import { viteExternalsPlugin } from 'vite-plugin-externals'
export default {
plugins: [
viteExternalsPlugin({
vue: 'Vue'
}),
]
}

How do I use require('electron') in a quasar vue component environment?

How do I access the main electron process fs module from within a renderer side module like a vue component running within the Quasar framework.
I've tried a few variations in a component with the following error:
const { app } = require('electron')
vue-router.esm.js?8c4f:1897 TypeError: fs.existsSync is not a function
const { app } = window.require('electron')
TypeError: window.require is not a function
After looking at what I could find through my friend Google, I am still searching for an answer on how to access the electron main process functions from within a vue component running under the quasar framework. Anyone... anyone? I've seen some github examples of file explorers, but based on the electron documentation it seems the implementation of just simply calling something like fs.readdirSync() should be a lot simpler than what I'm seeing in those implementations.
Your problem is explained in the Quasar docs
https://quasar.dev/quasar-cli/developing-electron-apps/node-integration
Quasar's suggestion is to use a preload script to attach the node APIs that you want in your renderer processes (ie: BrowserWindows) to the global window object.
https://quasar.dev/quasar-cli/developing-electron-apps/electron-preload-script
Attach preload script to BrowserWindow (Main Process)
src-electron/electron-main.js:
import path from 'path'
win = new BrowserWindow({
...
webPreferences: {
preload: path.resolve(__dirname, 'electron-preload.js')
}
})
Attach Node APIs to window global (Preload Script)
src-electron/electron-preload.js:
window.electron = require('electron')
Use Node API through the window global (Renderer Process)
somefile.vue
window.electron.ipcRenderer.sendSync(
'message',
payload
)
The answer was just beyond my understanding of how all these components are working together. Hopefully this will help someone else just coming up to speed on developing a Quasar/Vue/Electron app. If you launch your app/website using
quasar dev
you get a browser (renderer) that communicates with main electron process that cannot handle node main process stuff like:
const electron = require('electron')
const fs = require('fs')
const files = fs.readdirSync('/')
console.log(files)
I couldn't find a clear, concise and simple way. It appears there is a webpack config that can provide the same 'deep' integration, but I was looking for a more out of the box solution.
If you launch your app
quasar dev -m electron
You get deep integration and now can 'require()' or import the above modules within Vue components in your Quasar app.
const electron = require('electron')

Vue.js not working on safari 7.1 desktop (old maverick version)

I know is an old version but just wondering if there is a way to support vue.js there
import Vue from 'vue'
import { sync } from 'vuex-router-sync'
import App from './components/App'
import router from './router'
import store from './store'
sync(store, router);
const root = document.getElementById('app-stuff');
const app = new Vue({
router,
store,
propsData: {
'stuff': root.getAttribute('data-stuff')
},
...App
})
export { app, router, store }
The error is:
TypeError: undefined is not a function (evaluating
'Object.assign({router:a.a,store:s.a,propsData:{language:c.getAttribute("data-stuff")}},o.a)')
Could it be fixed or not at all really?
Safari 7.1 does not define Object.assign. If you need functionality that is not available in older browsers, you can add it by defining it yourself. Doing so is called a "polyfill". A polyfill for this specific function can be found on mdn. For a more full-fledged polyfill you could for example use babel's polyfill. Please note that I am not 100% what that polyfills for Safari 7.1, as I normally work with somewhat newer browsers.

In the webpack-simple Vue.js template, how can I access the Vue app from the console?

I've created a Vue.js app using vue-cli with the webpack-simple template, and it works great. In the provided main.js, I changed the new Vue(... line to var vm = new Vue(..., so that I could access the Vue instance from the Chrome Dev Console, but the variable vm still shows as undefined.
What is the correct way for me to get a reference to the Vue object so that I can do things like manually generating events in components, or manually modifying data from the console?
Try with window.vm = vm;
var vm = new Vue({
el: '#app',
store,
template: '<App/>',
components: { App }
})
window.vm = vm;
And than just type vm in console. Your Vue object will be available now.
Another option is:
Do not modify main.js / main.ts generated by vue-cli
Install Vue.js devtools (available for Firefox and Chrome)
On your Vue-powered website press F12 (open dev console) and go to Vue tab
Every component gets assigned to $vmX variable which you can use in the console.