Use sweetalert2 in axios module errorHandler - vuejs2

I am creating my first nuxtjs project and am using the axios module as my HTTP client.
The Problem
Use the sweetalert2 plugin within the axios module's errorHandler.
nuxt.config.js
module.exports = {
modules: [
'#nuxtjs/axios'
],
axios: {
errorHandler (error) {
if (process.browser) {
const swal = require('sweetalert2')
swal({
title: 'Error',
text: 'Error',
confirmButtonColor: "#895CF2",
confirmButtonText: 'Zurück',
type: 'error'
}).then(function () {
window.history.back();
})
}
},
plugins: [
{ src: '~/plugins/sweetalert2', ssr: false }
],
build: {
vendor: ['axios', 'sweetalert2']
}
}
plugins/sweetalert2.js
import Vue from 'vue'
import swal from 'sweetalert2'
Vue.use(swal)
The errorHandler works without sweetalert and the sweetalert code works, as is in the frontend (pages/components).
I would be very thankful for any kind of help!

Related

Load SVGs components in storybook VUE not working

Hello everyone I'm using vue 3 with storybook 6.5.16 and when i import the SVGs as a component using svg-inline-loader i get the following error in storybook app:
enter image description here
(Failed to execute 'createElement' on 'Document' svg is not a valid name)
Storybook main.js
const path = require('path');
module.exports = {
stories: [
'../src/**/*.stories.mdx',
'../src/**/*.stories.#(js|jsx|ts|tsx)',
],
addons: [
'#storybook/addon-links',
'#storybook/addon-essentials',
'#storybook/addon-interactions',
],
framework: '#storybook/vue3',
core: {
builder: '#storybook/builder-webpack5',
},
webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
config.module.rules.push({
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
{
loader: "sass-loader",
options: {
additionalData: `
#import "#/assets/scss/main.scss";
`,
implementation: require('sass'),
},
},
],
});
(() => {
const ruleSVG = config.module.rules.find(rule => {
if (rule.test) {
const test = rule.test.toString();
const regular = /\.(svg|ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/;
const regularString = regular.toString();
if (test === regularString) {
return rule;
}
}
});
ruleSVG.test = /\.(ico|jpg|jpeg|png|apng|gif|eot|otf|webp|ttf|woff|woff2|cur|ani|pdf)(\?.*)?$/;
})();
config.module.rules.push({
test: /\.svg$/,
use: ['svg-inline-loader'],
});
config.resolve.alias['#'] = path.resolve('src');
return config;
},
}
package.json file
enter image description here
SVG Vue components
<template>
<div
ref="icon"
class="v-icon"
#click="onClick"
>
<component
:is="iconName"
class="v-icon__svg"
/>
</div>
</template>
<script>
import Cards from '#/assets/icons/Cards.svg';
export default {
name: 'VIcon',
components: {
Cards,
},
props: {
iconName: {
type: String,
required: true,
},
},
};
</script>
.babelrc file
{
"presets": ["#babel/preset-env", "#babel/preset-react"]
}
i tried to use vue-svg-loader to replace svg-inline-loader but it didn't work and I got another error while building the app
ModuleBuildError: Module build failed: Error: Cannot find module './Block'
I also tried to use babel-loader in conjunction with vue-svg-loader but unfortunately I also got an error:
enter image description here
has anyone come across this or can you show your use cases of using SVGs components in Storybook and Vue 3?

How to use Environment Variables inside Vue3+Vite component library?

I have created a component as part of my component library that I am building with Vue3 and Vite. Everything works well, except when I try to use environment variables. I want the app that consumes this component library to be able to provide the component with environment specific data.
I have played around and found that if I have a .env file as part of the component library project, I am able to access those variables, but I want to be able to provide that during runtime and not during build time.
Here is my vite.config.ts
import { defineConfig } from "vite";
import { resolve } from "path";
import vue from "#vitejs/plugin-vue";
import dts from "vite-plugin-dts";
export default ({ mode }) => {
return defineConfig({
optimizeDeps: {
exclude: ["vue-demi"],
},
plugins: [
vue(),
dts({
insertTypesEntry: true,
}),
],
server: {
open: true,
},
build: {
lib: {
entry: resolve(__dirname, "src/lib.ts"),
name: "complib",
fileName: "complib",
},
rollupOptions: {
external: ["vue"],
output: {
globals: {
vue: "Vue",
},
exports: "named",
},
},
},
});
};
The entry looks like:
import { App, install } from "vue-demi";
import TestComp from "./components/TestComp.vue";
import "./tailwind.css";
install();
export default {
install: (app: App) => {
app.component("TestComp", TestComp);
},
};
export { Header };
And here is a minimal component TestComp.vue:
<script setup lang="ts">
import { onMounted } from "vue";
onMounted(() => {
console.log(import.meta.env.VITE_TEST_VAR);
});
</script>
<template>
<span>Test Comp</span>
</template>

How use vue-i18n with vue2, vite?

i'm migrating from webpack to vite, but there is a problem that I can't find a plugin to use i18n
I tried to use #intlify/vite-plugin-vue-i18n: 6.0.1, it doesn't seem to be work
now my package version:
vue: 2.6.11
vue-i18n: 8.17.0
#kazupon/vue-i18n-loader: 0.5.0
#intlify/vite-plugin-vue-i18n: 6.0.1
vite: 2.9.15
vite-plugin-vue2: 2.0.2
vite.config.js
/* cSpell:disable */
import { defineConfig } from 'vite';
const { resolve } = require('path');
import { createVuePlugin } from 'vite-plugin-vue2';
import copy from 'rollup-plugin-copy';
import { viteCommonjs } from '#originjs/vite-plugin-commonjs';
import clear from 'rollup-plugin-clear';
import vueI18n from '#intlify/vite-plugin-vue-i18n';
import { createI18nPlugin } from '#yfwz100/vite-plugin-vue2-i18n';
const destDir = `../var/dist/views`;
const host = 'localhost';
let filePort;
try {
const port = require('../port');
filePort = port && port.front;
// eslint-disable-next-line no-empty
} catch (error) {}
const listenPort = filePort || '10210';
const pages = {
cn: {
dir: 'pages',
template: 'cn.html',
entry: 'cn.js'
},
'vue-test': {
dir: 'vue-test/index',
template: 'index.html',
entry: 'index.js'
}
};
const multiplePagePath = 'src/pages';
const copyFileList = [];
Object.values(pages).forEach(item => {
copyFileList.push({
src: `${multiplePagePath}/${item.dir}/${item.template}`,
dest: destDir + '/' + item.dir,
transform: (contents, filename) =>
contents
.toString()
.replace(
'<!-- viteDevelopmentCopyReplaceHref -->',
`<script src="//${host}:${listenPort}/${multiplePagePath}/${item.dir}/${item.entry}" type="module" ></script>`
)
});
});
export default defineConfig({
resolve: {
alias: { src: resolve(__dirname, './src') },
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue']
},
server: {
port: listenPort,
// https: true,
hmr: { host },
origin: `//${host}:${listenPort}`
},
plugins: [
createVuePlugin(),
clear({
targets: ['../var']
}),
copy({
targets: [...copyFileList, { src: 'src/pages/*.html', dest: destDir }, { src: 'src/pages/layout', dest: destDir }],
verbose: true,
hook: 'buildStart'
}),
vueI18n({
// if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
// compositionOnly: false,
// you need to set i18n resource including paths !
// include: resolve(__dirname, './path/to/src/locales/**'),
compositionOnly: false
})
]
});
index.vue
<i18n>
{
"en-us": {
"language": "Language",
"hello": "hello, world!"
},
"zh-cn": {
"language": "言語",
"hello": "こんにちは、世界!"
}
}
</i18n>
<template>
<div id="app">
<p>{{$t('language')}}</p>
</div>
</template>
<script>
</script>
when i open the page, the text has not been translated and there is a warning in console:
[vue-i18n] Cannot translate the value of keypath 'language'. Use the value of keypath as default
Can anyone help me on this? Thanks in Advance
#intlify/vite-plugin-vue-i18n does not support custom block in Vue 2.
You should use unplugin-vue-i18n with vue-i18n-bridge.
Minimal examples of Vue2 + VueI18n custom block + Vite:
Vue<=2.6: https://stackblitz.com/edit/vitejs-vite-wk6hhj
Vue 2.7: https://stackblitz.com/edit/vitejs-vite-elfdtq
I18n Legacy API:
Vue<=2.6: https://stackblitz.com/edit/vitejs-vite-ed3cmt

Using vue slots in library gives currentRenderingInstance is null

I am creating a Vue component library with Rollup, but when I use slots it gives me the following error:
Uncaught (in promise) TypeError: currentRenderingInstance is null
I made a very simple component in my library:
<script setup></script>
<template>
<button>
<slot></slot>
</button>
</template>
<style scoped></style>
Then I simply use it like this:
<ExampleComponent>
Text
</ExampleComponent>
If I remove the slot and replace it with a prop or hard-coded text, everything works fine.
This is my rollup.config.js:
import { defineConfig } from 'rollup';
import path from 'path';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import postcss from 'rollup-plugin-postcss';
import vue from 'rollup-plugin-vue';
// the base configuration
const baseConfig = {
input: 'src/entry.js',
};
// plugins
const plugins = [
vue(),
resolve({
extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'],
}),
// process only `<style module>` blocks.
postcss({
modules: {
generateScopedName: '[local]___[hash:base64:5]',
},
include: /&module=.*\.css$/,
}),
// process all `<style>` blocks except `<style module>`.
postcss({ include: /(?<!&module=.*)\.css$/ }),
commonjs(),
];
const external = ['vue'];
const globals = {
vue: 'Vue',
};
export default [
// esm
defineConfig({
...baseConfig,
input: 'src/entry.esm.js',
external,
output: {
file: 'dist/vue-my-lib.esm.js',
format: 'esm',
exports: 'named',
},
plugins,
}),
// cjs
defineConfig({
...baseConfig,
external,
output: {
compact: true,
file: 'dist/vue-my-lib.ssr.js',
format: 'cjs',
name: 'VueMyLib',
exports: 'auto',
globals,
},
plugins,
}),
// iife
defineConfig({
...baseConfig,
external,
output: {
compact: true,
file: 'dist/vue-my-lib.min.js',
format: 'iife',
name: 'VueMyLib',
exports: 'auto',
globals,
},
plugins,
}),
];
Any idea about the problem?
After a whole day of searching, I found the solution (here and here). It's a problem with using a library locally (e.g., through npm link) where it seems there are two instances of Vue at the same time (one of the project and one of the library). So, the solution is to tell the project to use specifically its own vue through webpack.
In my case, I use Jetstream + Inertia, so I edited webpack.mix.js:
const path = require('path');
// ...
mix.webpackConfig({
resolve: {
symlinks: false,
alias: {
vue: path.resolve("./node_modules/vue"),
},
},
});
Or if you used vue-cli to create your project, edit the vue.config.js:
const { defineConfig } = require("#vue/cli-service");
const path = require("path");
module.exports = defineConfig({
// ...
chainWebpack(config) {
config.resolve.symlinks(false);
config.resolve.alias.set("vue", path.resolve("./node_modules/vue"));
},
});
Thanks to #mikelplhts
On vite + esbuild I used:
export default defineConfig({
...
resolve: {
alias: [
...
{
find: 'vue',
replacement: path.resolve("./node_modules/vue"),
},
],
},
...

import { ipcRenderer } from 'electron' produces this error: __dirname is not defined

With this simple vue page:
<template>
<div class="home">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from '#/components/HelloWorld.vue'
import { ipcRenderer } from 'electron'
export default {
name: 'Home',
components: {
HelloWorld
},
data() {
return {
dato: null
}
},
methods: {
rendererFunct () {
//ipcRenderer.on('setting', (event, arg) => {
//console.log(arg);
//})
}
}
}
</script>
The only presence of import { ipcRenderer } from 'electron' produces the error __dirname is not defined :
Is this problem is something related to webpack configuration or it is due to something else?
This is my webpack.config.js :
import 'script-loader!./script.js';
import webpack from 'webpack';
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
target: ['electron-renderer', 'electron-main', 'electron-preload'],
pluginOptions: {
electronBuilder: {
chainWebpackMainProcess: config => {
config.resolve.alias.set('jsbi', path.join(__dirname, 'node_modules/jsbi/dist/jsbi-cjs.js'));
}
},
},
};
module.exports = {
entry: './src/background.js',
target: 'node',
output: {
path: path.join(__dirname, 'build'),
filename: 'backend.js'
}
}
module.exports = config => {
config.target = "electron-renderer";
return config;
};
module.exports = {
plugins: [
new CopyPlugin({
patterns: [
{ from: 'source', to: 'dest' },
{ from: 'other', to: 'public' },
],
options: {
concurrency: 100,
},
}),
],
};
module.exports = {
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: [
// Creates `style` nodes from JS strings
'style-loader',
// Translates CSS into CommonJS
'css-loader',
// Compiles Sass to CSS
'sass-loader',
],
},
],
},
};
const supportedLocales = ['en-US', 'it'];
export default const config = {
plugins: [
new webpack.ContextReplacementPlugin(
/date\-fns[\/\\]/,
new RegExp(`[/\\\\\](${supportedLocales.join('|')})[/\\\\\]index\.js$`)
)
]
}
This is vue.config.js :
module.exports = {
configureWebpack: {
// Configuration applied to all builds
},
pluginOptions: {
electronBuilder: {
chainWebpackMainProcess: (config) => {
// Chain webpack config for electron main process only
},
chainWebpackRendererProcess: (config) => {
config.plugin('define').tap((args) => {
args[0]['IS_ELECTRON'] = true
return args
})
},
mainProcessFile: 'src/background.js',
mainProcessWatch: ['src/preload.js'],
}
}
}
module.exports = {
pluginOptions: {
electronBuilder: {
disableMainProcessTypescript: false,
mainProcessTypeChecking: false
}
}
}
Electron: version 9.0.0
webpack: version 4.44.1
System:
OS: Linux 5.4 Ubuntu 18.04.4 LTS (Bionic Beaver)
CPU: (8) x64 Intel(R) Core(TM) i7-4790K CPU # 4.00GHz
Binaries:
Node: 14.5.0 - ~/.nvm/versions/node/v14.5.0/bin/node
Yarn: 1.22.4 - /usr/bin/yarn
npm: 6.14.5 - ~/.nvm/versions/node/v14.5.0/bin/npm
Browsers:
Chrome: 84.0.4147.105
Firefox: 79.0
Looking forward to your kind help.
Marco
__dirname is a NodeJS variable, in recent electron versions, node integration is disabled by default. When opening your BrowserWindow, you should add the following to the options:
webpreferences:{
nodeIntegration: true
}
This is however STRONGLY DISCOURAGED as this opens up security issues.
this seems to solve it for most people (for me sadly enough i now get the next error:
fs.existsSync is not a function)
a better solution i to change your bundler to the correct build mode. You should not be building for node but for web, so target:esnext or something.
if something requires node access, this should be solved by running it in the background thread or the preload scripts.
You can apply the solution described on this post
How to import ipcRenderer in vue.js ? __dirname is not defined
In this way you can call this method from vue files:
window.ipcRenderer.send(channel, args...)
Just make sure you configure preload.js on vue.config.js:
// vue.config.js - project root
module.exports = {
pluginOptions: {
electronBuilder: {
preload: 'src/preload.js' //make sure you have this line added
}
}
}