using the vue-cli-service which uses webpack under the hood, is there a way to set things up so on hot reload the browsers console is cleared?
It is not very efficient to constantly see old messages in the console log that are not relevant to the current state of the app on last save.
Simple keep clearing the console every time a hot reload happen by adding this to the main.js file
if (module.hot) {
module.hot.accept() // already had this init code
module.hot.addStatusHandler(status => {
if (status === 'prepare') console.clear()
})
}
main.js file now would be
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
if (module.hot) {
module.hot.accept() // already had this init code
module.hot.addStatusHandler(status => {
if (status === 'prepare') console.clear()
})
}
Related
I'm trying to make a global function with help of plugin which it worked fine but i couldn't show my notification. I was doing my homework and i tried to not write everywhere those show notification methods, so I've searched and i found this solution and i managed to add plugin now i wan to use it in my component. here's the code :
AppNotifications.js
export default {
failedNotification(title, data) {
return this.$vs.notify({
title:title,
text:data,
color:'danger',
position:'bottom-center',
});
}
};
App.js
import Vue from 'vue'
import notifications from './Helpers/AppNotifications'
const plugin = {
install () {
Vue.notifications = notifications
Vue.prototype.$notifications = notifications
}
}
Vue.use(plugin)
const app = new Vue({
vuetify,
el: '#app',
render: h => h(App),
router
});
And in componenets when i use a button with #click="SomeMethod" i use plugin like this :
this.$notifications.failedNotification('Test','Just Failed, yay')
So function work but i get this error
Error in v-on handler: "TypeError: Cannot read property 'notify' of undefined"
Since I'm in learning process i wasn't familiar with this issue and I've tried to import vue and notification component itself but didn't worked.
Edit 01 : Notification is belong to Vuesax library and it's already imported in App.js and it's working fine when i use it in vue components but it's not working when i use it in AppNotification.js
So i found the solution for my problem and it fixed with sending this as parameter to function.
Vue Component :
//this was before the problem
this.$notifications.failedNotification('Test','Just Failed, yay')
//then i added this as parameter
this.$notifications.failedNotification(this,'Test','Just Failed, yay')
And in AppNotification.js
//Before changing
failedNotification(title, data) {
return this.$vs.notify({
title:title,
text:data,
color:'danger',
position:'bottom-center',
});
}
//Then i added self and replaced self with `this`
failedNotification(self,title, data) {
return self.$vs.notify({
title:title,
text:data,
color:'danger',
position:'bottom-center',
});
}
And it's worked.
The error you're getting suggests that the notification library you're using isn't being loaded and if you posted the entire code of your App.js file then it looks like you're missing some code.
The file probably needs to look something like this:
import Vue from 'vue'
import Vuesax from 'vuesax'
import notifications from './Helpers/AppNotifications'
import 'vuesax/dist/vuesax.css' //Vuesax styles
const plugin = {
install () {
Vue.notifications = notifications
Vue.prototype.$notifications = notifications
}
}
Vue.use(Vuesax)
Vue.use(plugin)
const app = new Vue({
vuetify, // <-- not sure where vuetify is coming from?
el: '#app',
render: h => h(App),
router
});
I am looking for help in understanding what are the best practices people are using for a VueJs app that is not an SPA. In my project I have multiple pages and currently I'm treating every page as an SPA. But I'm noticing that my app.js size is increases after adding a new page. This is what I have so far
require('./bootstrap');
var Vue = require('vue');
import GlobalMixins from './mixins/GlobalMixins'
import VueFlashMessage from 'vue-flash-message'
import PortalVue from 'portal-vue'
import Treeselect from '#riophae/vue-treeselect'
Vue.prototype.$eventHub = new Vue(); //global event bus
Vue.mixin(GlobalMixins);
Vue.use(PortalVue);
Vue.use(VueFlashMessage,{
messageOptions: {
timeout: 7000,
important: false,
autoEmit: true,
pauseOnInteract: true,
createShortcuts: false,
}
});
// shared components
Vue.component('navigation', require('./components/navigation.vue').default);
Vue.component('loader',require('./components/shared/custom_loader.vue').default);
Vue.component('treeselect',Treeselect);
//parent components only for each page
Vue.component('goals', require('./components/goals/index.vue').default);
Vue.component('dashboard', require('./components/dashboard/index.vue').default);
Vue.component('twitter', require('./components/twitter/index.vue').default);
Vue.component('trends', require('./components/trends/index.vue').default);
Vue.component('settings', require('./components/settings/index.vue').default);
..........
..........
..........
require('./filters');
window.onload = function () {
new Vue ({
el: '#app'
});
}
I'm compiling my assets using laravel-mix and even after running npm run prod app.js size is around 2MB. How can I optimize this?
PS: gzip compression is already enabled on my servers.
I understand that in your jest.setup.js code, you are supposed to set
Vue.config.productionTip = false;
Vue.config.devtools = false;
and I do. In fact, here is my jest.setup.js code. Notice the console.log('yo ho');
// test/setup.js
import Vue from 'vue';
import Vuetify from 'vuetify';
import { config } from '#vue/test-utils';
import VueCompositionApi from '#vue/composition-api'; // <-- Make the import
Vue.use(Vuetify);
Vue.use(VueCompositionApi);
Vue.config.productionTip = false;
Vue.config.devtools = false;
console.log('yo ho');
// https://vue-test-utils.vuejs.org/
// and this came from: https://github.com/kazupon/vue-i18n/issues/323
// it mocks out the $t function to return the key so you can test that the right key is being used
config.mocks = {
$t: (key) => 'i18n:' + key
};
So given that, I don't expect to get these warnings - ever. But I do on about 1/3 of my unit test files. Not all my unit test files, just some of them. I am really confused.
So I then added that console log statement to ensure that on the unit tests that I am getting this warning, the jest.setup.js is actually getting called. This is the output from one of my unit tests:
PASS src/components/announcement-banner.test.ts (8.255s)
● Console
console.log tests/unit/jest.setup.js:12
yo ho
console.info node_modules/Vue/dist/vue.runtime.common.dev.js:8403
Download the Vue Devtools extension for a better development experience:
https://github.com/vuejs/vue-devtools
console.info node_modules/Vue/dist/vue.runtime.common.dev.js:8412
You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
How in the world I am I getting the Vue warning, when I am definitely executing the jest.setup?
to make these warnings go away, I have to go to the specific test file and add the config lines directly before the createLocalVue() call.
Vue.config.productionTip = false;
Vue.config.devtools = false;
const localVue = createLocalVue();
Finally solved. Looks like jest.mock('module') is importing clean Vue (into mock, behind the scenes) if Vue is imported in given file. I've solved this by creating global mock for Vue.
In root of your project (where node_modules directory is) create __mocks__/vue/index.ts (or .js if you are not using TypeScript) file with:
import Vue from 'vue'
Vue.config.productionTip = false
Vue.config.devtools = false
export default Vue
Should solve this annoying problem.
UPDATE 2022-07-04 VueI18n common error (related)
Using Vue.extend() in components will cause Jest to use version imported through this file when component is a child component of component mounted in the test. If you are using VueI18n and try to mount component or stub child component (that uses VueI18n) everything will go sideways with error _vm.$t is not a function
To avoid that, You will need to mock VueI18n in that particular file. For example by creating fake plugin (this is more advanced fake than just $t: (key) => key, you can use whatever you want):
const VueI18nStub = {
install(_Vue: typeof Vue) {
function getFormattedTranslationArgs(...args: any): string {
return args
.reduce((result: string[], arg: any) => {
result.push(typeof arg === 'object' ? JSON.stringify(arg) : arg.toString())
return result
}, [])
.join(' | ')
}
_Vue.prototype.$t = getFormattedTranslationArgs
_Vue.prototype.$tc = getFormattedTranslationArgs
_Vue.prototype.$te = () => true
},
}
Vue.use(VueI18nStub)
VueI18n is a common example, but any plugin will need to be added in this file to work, as you can't extend mock from this file inside any test.
Whole file with VueI18n stub would look like this:
import Vue from 'vue'
Vue.config.productionTip = false
Vue.config.devtools = false
const VueI18nStub = {
install(_Vue: typeof Vue) {
function getFormattedTranslationArgs(...args: any): string {
return args
.reduce((result: string[], arg: any) => {
result.push(typeof arg === 'object' ? JSON.stringify(arg) : arg.toString())
return result
}, [])
.join(' | ')
}
_Vue.prototype.$t = getFormattedTranslationArgs
_Vue.prototype.$tc = getFormattedTranslationArgs
_Vue.prototype.$te = () => true
},
}
Vue.use(VueI18nStub)
export default Vue
After upgrading to vue 2.7, all my unit tests for components using the composition-api were failing. It turns out, now that the composition-api is directly exported in the vue module, the jest mock from the accepted answer has to be updated like this:
import Vue from 'vue';
Vue.config.productionTip = false;
Vue.config.devtools = false;
export default Vue;
// this line makes available all of the non-default exports from the vue module in jest tests
export * from 'vue';
Hope this helps anyone struggling with unit tests under vue 2.7
I'm trying to create a PWA with VUE.
When trying to register the service worker I do it in the file main.js in the following way:
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
const prod = process.env.NODE_ENV === 'production';
const swLocation = '../public/sw-config.js';
if (
prod &&
('https:' === location.protocol || location.host.match(/(localhost|127.0.0.1)/)) &&
navigator.serviceWorker
) {
navigator.serviceWorker.register(swLocation).catch( error => console.log)
console.log('sw register');
}
As you can see my service worker file is called sw-config.js that is in the public folder at the same level as the index.html.
But at the moment of executing npm run build and executing this from a local server with npm http-server I get the message by console: "sw register"
But also the following errors:
A bad HTTP response code (404) was received when fetching the script.
Failed to load resource: net::ERR_INVALID_RESPONSE
I also noticed that this error is not shown in the console the first time the application is executed but if it is reloaded it is when it starts.
I tried to fix it by cleaning all the registered service workers to verify if that was the error but it did not work, this was the code that I used in the Chrome console:
navigator.serviceWorker.getRegistrations().then(function(registrations) { for(let registration of registrations) { registration.unregister() } })
On Chrome Developer Tools I have this:
Chrome=>Dev Tools=>Application=>Service Workers=>Update on reload (selected)
I do not know how to avoid that error in the console, could someone help me?
Thanks!
Everything in public folder is in the root folder of the application after the build.
So your url should be: const swLocation = '/sw-config.js';
I have a Vue.js site with Webpack Dev Middleware (served via an ASP.NET Core site by HTTP.sys web server, though I'm guessing that doesn't matter). Does anyone know how I can set up my site to clear the browser's Javascript console on every hot reload event?
Here's the only related link I can find, but it seems to be for a web server I am not using. I'm not sure why the particular web server would matter.
In my main app .js file:
if (module.hot) {
module.hot.accept() // already had this init code
module.hot.addStatusHandler(status => {
if (status === 'prepare') console.clear()
})
}
That got it to work consistently for me.
See also https://webpack.js.org/api/hot-module-replacement/#addstatushandler .
your link contains the response for your question. Just add in your main.js file:
window.addEventListener('message', (e) => {
if (e.data && typeof e.data === 'string' && e.data.match(/webpackHotUpdate/)) {
console.log('hot reload happened')
console.clear()
}
})
Example of a complete main.js file:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
window.addEventListener('message', (e) => {
if (e.data && typeof e.data === 'string' && e.data.match(/webpackHotUpdate/)) {
console.log('hot reload happened')
console.clear()
}
})
EDIT: I didn't read your answers to the github issue. Could you provide some kind of JSON.stringify(e) on your event message on multiple events so we can check what you have?