Clearing console on Nuxt hot reload? - vue.js

In Vue I just edited the main.js file to add:
// on hot-reload clear the console
window.addEventListener("message", (e) => {
if (e.data && typeof e.data === "string" && e.data.match(/webpackHotUpdate/)) {
console.clear();
}
});
But in Nuxt you only have the config file. I tried adding that script to the plugins folder but the console never cleared.
onReload.js in plugins folder. This file only seems to run when I refresh the page manually but not on hot reload (i.e. when I save any file):
console.log("hello there");
window.addEventListener("message", (e) => {
console.log("e.data is > ", e.data);
console.log("=== string > ", typeof e.data === "string");
console.log("does it match > ", e.data.match(/webpackHotUpdate/));
if (e.data && typeof e.data === "string" && e.data.match(/webpackHotUpdate/)) {
console.log("hello world");
console.clear();
}
});
Nuxt config file:
plugins: [{ mode: "client", src: "~/plugins/onReload" }],
Any ideas are appreciated!

You will need to add a plugin.
/plugins/onReload.js would contain your function:
Object.keys(window.__whmEventSourceWrapper).forEach((key) => {
window.__whmEventSourceWrapper[key].addMessageListener((e) => {
if (e.data.match(/built/)) {
console.clear()
}
})
})
Then in nuxt.config.js you would need to import the plugin, and disable server side rendering
plugins: [
{ mode: client, src: '~/plugins/onReload' }
]

The accepted answer didn't work for me so I ended up creating clear-console.client.js with the following...
export default () => {
if (module.hot) {
module.hot.accept() // already had this init code
module.hot.addStatusHandler((status) => {
if (status === 'prepare') console.clear()
})
}
}
Then in nuxt.config.js add the follwing plugins: ['~/plugins/clear-console.client.js']
Hope this helps others.

Related

Vue3 vue-intersect not working with v-if?

When I use
<intersect v-if="activated == true" #enter=" addImages();" > <div class="h-1 w-full border"></div> </intersect>
The intersect appears in the dom when the condition is met, but the intersect is not doing any method anymore when I scroll to it.
If I remove the if then I have the problem that with a big screen when the page loads, the intersect gets activated a couple of times while loading.
How to make the intersect work with v-if? what is the reason that its not working?
Here the code of the intersect component ( from this project vue-intersect):
import Vue from 'vue'
const warn = (msg) => {
if (!Vue.config.silent) {
console.warn(msg)
}
}
export default {
name: 'intersect',
abstract: true,
props: {
threshold: {
type: Array,
required: false,
default: () => [0, 0.2]
},
root: {
type: typeof HTMLElement !== 'undefined' ? HTMLElement : Object,
required: false,
default: () => null
},
rootMargin: {
type: String,
required: false,
default: () => '0px 0px 0px 0px'
}
},
mounted () {
this.observer = new IntersectionObserver((entries) => {
if (!entries[0].isIntersecting) {
this.$emit('leave', [entries[0]])
} else {
this.$emit('enter', [entries[0]])
}
this.$emit('change', [entries[0]])
}, {
threshold: this.threshold,
root: this.root,
rootMargin: this.rootMargin
})
this.$nextTick(() => {
if (this.$slots.default && this.$slots.default.length > 1) {
warn('[VueIntersect] You may only wrap one element in a <intersect> component.')
} else if (!this.$slots.default || this.$slots.default.length < 1) {
warn('[VueIntersect] You must have one child inside a <intersect> component.')
return
}
this.observer.observe(this.$slots.default[0].elm)
})
},
destroyed () {
this.$emit('destroyed')
this.observer.disconnect()
},
render () {
return this.$slots.default ? this.$slots.default[0] : null
}
}
It seems you're installing the old version of this component which is not compatible with Vue 3, try to uninstall the installed version and install the next one
npm uninstall vue-intersect --save
then
npm install vue-intersect#next --save

Built code errors in Electron: Failed to execute 'querySelector' on 'Document'

Using Vite to build the app, I am getting the following error inside Electron:
index.c160f204.js:9 DOMException: Failed to execute 'querySelector' on 'Document': 'link[href="/C:UsersrankDocumentsSchoolCheckInElectronReaderdist/assets/Home.b0f26e4d.js"]' is not a valid selector.
It appears to me that the path inside the built code has the slashes removed, but I have no idea on how to solve that since it's generated code.
Using Node 17.9.0 on Windows 11 10.0.22000 Build 22000
Electron main.js:
const { app, BrowserWindow } = require("electron");
const path = require("path");
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, "preload.js"),
},
});
win.loadFile("dist/index.html");
}
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
Electron preload.js:
window.addEventListener("DOMContentLoaded", () => {
const replaceText = (selector, text) => {
const element = document.getElementById(selector);
if (element) element.innerText = text;
};
for (const type of ["chrome", "node", "electron"]) {
replaceText(`${type}-version`, process.versions[type]);
}
});
Vite.config.ts:
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
import * as path from "path";
// https://vitejs.dev/config/
export default defineConfig({
base: path.resolve(__dirname, './dist'),
plugins: [
vue(),
],
})
Using vue-tsc --noEmit && vite build to build and electron . to start.
If you copy/paste the faulty code into a browser console, you will notice a non UTF-8 character in your link, between Users and rank.
Get rid of it and it should work.
The simplest way to fix this would be to move the project to a path which doesn't contain weird chars (e.g: C:/projects/)

Show updated PWA created in Vue

I uasing Vue.js with Vuetify and creating a PWA.
I have service-worker.js in /public folder
A snippet from vue.config.js:
pwa: {
// configure the workbox plugin
workboxPluginMode: 'InjectManifest',
workboxOptions: {
// swSrc is required in InjectManifest mode.
swSrc: 'public/service-worker.js',
// ...other Workbox options...
}
}
This looks too be working good and caching the shell etc.
I run build and serve up the project
npm run build
The problem i have is when i update any files, i can't see the updated changes.
when i navigate to the url in my android device the page remains as the old one (cached).
How can i get it to update?
I tried including this code in index.html, but no success:
https://developers.google.com/web/tools/workbox/guides/advanced-recipes#offer_a_page_reload_for_users
service-worker.js
importScripts("/precache-manifest.8812c20b1b3401cbe039782d13cce03d.js", "https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js");
console.log(`Hello from service worker`);
if (workbox) {
console.log(`Workbox is loaded`);
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
skipWaiting();
}
});
}
else {
console.log(`Workbox didn't load`);
}
Not sure what exactly your setup setup is, but it should be similar. Using the #vue/cli-plugin-pwa and with minimal setup below.
This will show a dialog when a new version of your app is available. Clicking yes will update your app. You will have to refresh the page somehow to actually show the new version, but that is up to you on how solve that.
vue.config.js:
module.exports = {
pwa: {
name: "name-of-your-app",
short_name: "noya",
themeColor: "#000000",
workboxPluginMode: "InjectManifest",
workboxOptions: {
swSrc: "src/service-worker.js" // CHECK CORRECT PATH!
}
}
};
src/main.js:
import Vue from "vue";
import App from "./App.vue";
import "./registerServiceWorker";
// whatever other imports...
new Vue({
render: h => h(App)
}).$mount("#app");
src/registerServiceWorker.js:
import { register } from "register-service-worker";
if (process.env.NODE_ENV === "production") {
register(`${process.env.BASE_URL}service-worker.js`, {
updated(registration) {
if (window.confirm("A new version is available, update now?")) {
const worker = registration.waiting;
worker.postMessage({ action: "SKIP_WAITING" });
// refresh the page or trigger a refresh programatically!
}
}
});
}
src/service-worker.js:
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
self.addEventListener("message", (event) => {
if (event.data.action == "SKIP_WAITING") self.skipWaiting();
});
I get it work by following the offer_a_page_reload_for_users. The original registerServiceWorker.js seems redundant though.
src/registerServiceWorker.js
import { Workbox } from "workbox-window";
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
const wb = new Workbox("/service-worker.js");
wb.addEventListener("waiting", () => {
const result = window.confirm("refresh now?");
if (result) {
wb.messageSW({ type: "SKIP_WAITING" });
}
});
wb.addEventListener("controlling", () => {
window.location.reload();
});
wb.register();
}

how to fix blank page if i am using vue router with electron js?

I'm trying to use vue router with an application on an Electron JS. If I use a router on the render page, then the router work done. But I do not understand how to make the transition to the page, for example,- 'Settings' using the Tray. At attempt of transition the empty page opens.
I have prepared a working example of the project. This problem exists only build project. In development mode all work well.
This is my work example on github. Please need help.
git clone https://github.com/DmtryJS/electron-vue-example.git
cd electron-vue-example
npm install
npm run build
and run dist\win-unpacked\example_for_stackoverflow.exe
my main.js file
'use strict'
import { app, protocol, BrowserWindow, Menu, ipcMain, Tray } from 'electron'
import { format as formatUrl } from 'url'
const electron = require('electron');
const path = require('path');
const isDevelopment = process.env.NODE_ENV !== 'production';
let imgBasePath;
if(isDevelopment) {
imgBasePath = path.join('src','assets', 'img');
} else {
imgBasePath = path.join(path.dirname(__dirname), 'extraResources', 'img');
}
let win;
let tray;
protocol.registerStandardSchemes(['app'], { secure: true })
const trayIcon = path.join(__static, 'img', 'icon.png');
function createWindow () {
win = new BrowserWindow({
width: 800,
height: 600,
icon: trayIcon
})
routeTo(win, "")
win.on('closed', () => {
win = null
})
//убрать меню
win.setMenuBarVisibility(true)
win.on('show', function() {
tray.setHighlightMode('always')
})
win.on('hide', function() {
tray.setHighlightMode('never')
})
}
// Quit when all windows are closed.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null) {
createWindow()
}
})
app.on('ready', () => {
createWindow()
win.webContents.openDevTools(); //открыть dev tools
createTray()
})
// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
if (process.platform === 'win32') {
process.on('message', data => {
if (data === 'graceful-exit') {
app.quit()
}
})
} else {
process.on('SIGTERM', () => {
app.quit()
})
}
}
function createTray()
{
let traiIconPath = path.join(imgBasePath, 'preloader_tray_icon.png')
tray = new Tray(traiIconPath)
const contextMenu = Menu.buildFromTemplate(
[
{
label: 'Settings',
type: 'normal',
click: function()
{
routeTo(win, "/settings")
let contents = win.webContents
contents.on('dom-ready', function()
{
if(!win.isVisible())
{
showWindow()
}
})
}
},
{
label: 'Exit',
type: 'normal',
click: function()
{
win = null
app.quit()
}
}
])
tray.setContextMenu(contextMenu)
tray.on('click', function() {
toggleWindow();
})
}
function showWindow() {
var position = getPosition();
win.setPosition(position.x, position.y, false)
win.show()
win.focus()
}
ipcMain.on('routerEvent', function(event, arg) {
routeTo(win, arg)
})
function routeTo(win, to) {
if (isDevelopment) {
win.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}` + to)
} else {
win.loadURL(formatUrl({
pathname: path.join(__dirname, 'index.html' + to);,
protocol: 'file',
slashes: true
}))
}
}
And
router.js
import Vue from 'vue'
import Router from 'vue-router'
import Main from './../views/Main.vue'
import Settings from './../views/Settings.vue'
Vue.use(Router)
export default new Router({
//mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Main
},
{
path: '/settings',
name: 'settings',
component: Settings
}
]
})
You need to add created to the main Vue app check docs
// src/main.js
new Vue({
router,
render: h => h(App),
created() {
// Prevent blank screen in Electron builds
this.$router.push('/')
}
}).$mount('#app')
The solution for me was to remove the history mode in the vue router.
Sorry, but after one day of googling, I just found a solution. The case turned out to be
win.loadURL(formatUrl({
pathname: path.join(__dirname, 'index.html' + to);,
protocol: 'file',
slashes: true
}))
I delete formaUrl and everything works well
win.loadURL(path.join(__dirname, 'index.html' + to));
For me solution was this:
Check if app is running at addresses like this:
Local: http://x86_64-apple-darwin13.4.0:8080/
Network: http://localhost:8080/
Check if you can access x86_64..url in browser. If you are not seeing a webpage but can see it from localhost, then map 127.0.0.1 to x86_64-apple-darwin13.4.0 in hosts file. in mac its located in /etc/hosts in windows its in system32/drivers/etc.

How to use Electron API with Vue js component?

I'm using the electron-vue boilerplate, and I want to make my mainWindow a fullScreen after clicking a button.
Electron Window API: electron.atom.io/docs/api/browser-window
HTML:
<button #click="setFullScreen">Switch to Full Screen</button>
Vue:
export default {
name: 'mainComponent',
methods: {
setFullScreen: function() {
mainWindow.setFullScreen(true);
}
}
This is not working. How can I use the Electron API in electron-vue?
and the index.js:
'use strict'
import { app, BrowserWindow } from 'electron'
let mainWindow
const winURL = process.env.NODE_ENV === 'development'
? `http://localhost:${require('../../../config').port}`
: `file://${__dirname}/index.html`
function createWindow () {
/**
* Initial window options
*/
mainWindow = new BrowserWindow({
height: 728,
width: 1024,
fullscreen: false,
})
mainWindow.loadURL(winURL)
mainWindow.on('closed', () => {
mainWindow = null
})
// eslint-disable-next-line no-console
console.log('mainWindow opened')
}
app.on('ready', createWindow)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (mainWindow === null) {
createWindow()
}
})
you will find it as it is in electron-Vue
the picture shows How the Structure of the folder
enter image description here
mainWindow is not available in your Vue code because it is defined in your main process.
In your single file component, however, you can import remote from electron, where you can get access to the current window. So your code would look something like this.
const {remote} = require("electron")
export default {
name: 'mainComponent',
methods: {
setFullScreen: function() {
remote.getCurrentWindow().setFullScreen(true);
}
}
}