using external component in Nuxt not working - vue.js

I have component I install from npm
it called vue-3d-model
I create a file like this ~/plugins/ModelGltf.js
import Vue from 'vue';
import { ModelGltf } from 'vue-3d-model';
Vue.use(ModelGltf)
and then I register it in nuxt.config.js
plugins: [
{ src: '~/plugins/ModelGlft.js', ssr: false },
],
and I called in my component like <model-gltf> ...........
but it was not rendering, in my console terminal it called Critical dependency: the request of a dependency is an expression and in my inspect it said <model-gltf> component is not register yet
I have been saw some question on stack overflow and tried their answers , still can't work

try to this,
in your ~/plugins/ModelGltf.js
import Vue from 'vue';
import { ModelGltf } from 'vue-3d-model';
Vue.component('ModelGltf', ModelGltf)
and then I register it in nuxt.config.js
{ src: '~/plugins/ModelGlft.js', ssr: false },
or
{ src: '#/plugins/ModelGlft.js', ssr: false },

Related

Vite + VueJS 3 + Bootstrap 5.2 - How to avoid importing Bootstrap scss file in all VueJS components?

I'm currently building a VueJS 3 application using Vite and Bootstrap 5.2
I want to use reakpoint mixins in some of my components but I cannot manage to do it without having to import bootstrap .scss file in all of them.
I'd like to import it just once and be capable of using all bootstrap functions/mixins throughout the whole code.
This is what I have already tried (none of them worked for me):
1. Add `bootstrap` file import to `css > preProcessors > scss > additionalData` `vite.config.js` settings:
// vite.config.js
import { defineConfig } from 'vite'
import vue from '#vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
server: {
port: 8080
},
resolve: {
alias: {
'#': path.resolve(__dirname, './src'),
find: '#vue/runtime-core',
replacement: '#vue/runtime-core/dist/runtime-core.esm-bundler.js',
'~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap')
}
},
plugins: [vue()],
css: {
preprocessorOptions: {
scss: {
additionalData: `#import "~bootstrap/scss/bootstrap";`
}
}
}
})
Create a ./src/assets/styles.scss file, import bootstrap in it and add it to css > preProcessors > scss > additionalData vite.config.js settings:
// vite.config.js (rest of settings equal to the one above)
css: {
preprocessorOptions: {
scss: {
additionalData: `#import "./src/assets/styles.scss";`
}
}
}
./src/assets/styles.scss
#import "~bootstrap/scss/bootstrap";
Import the same ./src/assets/styles.scss file within main.js file
Import bootstrap file within main.js
Along with that I have a question: if I do the only thing that worked which is importing the bootstrap file on every Vue component I want: will it affect performance since (as far as I understand) bootstrap will be fully imported all of the times?
I'm more than happy to share any additional details of the project in order to try to get some answers.

Vite vuetify plugin doesn't load components listed in external libraries

I am creating a library that wraps Vuetify 3 components. But when I try to use the library it gives the following error:
[Vue warn]: Failed to resolve component: v-btn If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
Library vite.config.ts :
import { fileURLToPath, URL } from 'node:url';
import { resolve } from 'node:path';
import { defineConfig } from 'vite';
import vue from '#vitejs/plugin-vue';
import vueJsx from '#vitejs/plugin-vue-jsx';
import vuetify from 'vite-plugin-vuetify';
export default defineConfig({
plugins: [
vue(),
vueJsx(),
// vuetify({ autoImport: true, styles: 'none' }), // Don't export vuetify
],
resolve: {
alias: {
'#': fileURLToPath(new URL('./src', import.meta.url)),
},
},
build: {
lib: {
entry: resolve(__dirname, 'src/main.ts'),
name: '#my/ui',
// the proper extensions will be added
fileName: 'my-ui',
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ['vue', 'vuetify'],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: 'Vue',
vuetify: 'Vuetify',
},
},
},
},
});
Nuxt project nuxt.config.ts:
import { defineNuxtConfig } from 'nuxt';
import vuetify from 'vite-plugin-vuetify';
export default defineNuxtConfig({
css: ['#/assets/css/main.css'],
modules: [
async (options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) =>
config.plugins.push(vuetify({ autoImport: true }))
);
},
],
build: {
transpile: ['#my/ui', 'vuetify'],
},
});
Nuxt project app.vue:
<template>
<v-app>
<v-main>
<HelloWorld label="Test" primary />
</v-main>
</v-app>
</template>
<script lang="ts" setup>
import { HelloWorld } from '#my/ui';
</script>
Nuxt project plugin vuetify.ts:
import 'vuetify/styles';
import { createVuetify } from 'vuetify';
import * as components from 'vuetify/components';
import * as directives from 'vuetify/directives';
export default defineNuxtPlugin((nuxtApp) => {
const vuetify = createVuetify({
// components, if imported components getting resolved but treeshaking doesn't work.
// directives
});
nuxtApp.vueApp.use(vuetify);
});
Expected Behavior
Vuetify components from the Library project should be auto imported.
Current workaround:
If the vuetify components are imported in the parent project then the components are resolved. But this causes issue as the library users has to know what to import or import on global which is creating larger bundle size.
Is there an alternative way to implement and meet the following criteria:
Wrapping module doesn't depend on vuetify (Peer dep only)
Consuming app can auto import and get all of the benefits of tree shaking
Consuming app doesn't need to import any of the peer dependencies of the wrapping module.
Thank you so much in advance.
Just to create an answer for the workaround Sasank described:
If you just want to get rid of the error, import the components into the parent project as described in this link: https://next.vuetifyjs.com/en/features/treeshaking/#manual-imports

I installed vue-ellipse-progress plugin and "document is not defined" error getting every time

`import VueEllipseProgress from 'vue-ellipse-progress';
export default {
components: {
VueEllipseProgress
}
}`
document is not defined error when everytime this is running
i also checked to remove server side rendering and same also
Here an example how you can include vue-ellipse-progress globally to your project.
plugins/vue-ellipse-progress.js Create plugin.
import Vue from 'vue';
import VueEllipseProgress from "vue-ellipse-progress";
Vue.use(VueEllipseProgress);
nuxt.config.js Include plugin in config.
plugins: [
{
src: '#/plugins/vue-ellipse-progress.js',
mode: 'client'
},
],
your-component.vue Use component.
<client-only>
<vue-ellipse-progress :progress="50" />
</client-only>
The official guide for nuxt plugins https://nuxtjs.org/docs/2.x/directory-structure/plugins

Vue3, Typescript and Eslint raise: "Parsing error: '}' expected"

I am writing code by Vue3 and Typescript, and this is the code of App.vue, which is the root component:
<template>
<router-view v-if="inited" />
<div v-else>
Initing...
</div>
</template>
<script lang="ts">
import router from './router';
import { defineComponent } from 'vue';
import { useStore } from 'vuex';
import { key } from './store';
const store = useStore(key);
export default defineComponent({
data() {
return { inited: store.state.inited };
},
});
</script>
But the eslint tell me:
/home/peter/proj/skogkatt-next/src/App.vue
17:9 error Parsing error: '}' expected
I use many time on Google and so on, but still cannot find a useful solution. This is the config of eslint in package.json:
{
// ...
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"parser": "#typescript-eslint/parser",
"plugins": [
"#typescript-eslint"
],
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"#vue/typescript",
"plugin:#typescript-eslint/eslint-recommended",
"plugin:#typescript-eslint/recommended"
],
"parserOptions": {
"parser": "#typescript-eslint/parser"
},
"rules": {
"#typescript-eslint/camelcase": "off"
}
},
// ...
}
I am not sure which config is useful or not, so I post those out. Thanks.
The error is caused by "plugin:#typescript-eslint/recommended", which sets the top-level parser, which collides with Vue's vue-eslint-parser. In addition, your own config duplicates the top-level parser setting already set in the plugin, and should also be removed.
Vue's ESLint config for TypeScript projects addresses this problem, so consider copying it:
module.exports = {
plugins: ['#typescript-eslint'],
// Prerequisite `eslint-plugin-vue`, being extended, sets
// root property `parser` to `'vue-eslint-parser'`, which, for code parsing,
// in turn delegates to the parser, specified in `parserOptions.parser`:
// https://github.com/vuejs/eslint-plugin-vue#what-is-the-use-the-latest-vue-eslint-parser-error
parserOptions: {
parser: require.resolve('#typescript-eslint/parser'),
extraFileExtensions: ['.vue'],
ecmaFeatures: {
jsx: true
}
},
extends: [
'plugin:#typescript-eslint/eslint-recommended'
],
overrides: [{
files: ['*.ts', '*.tsx'],
rules: {
// The core 'no-unused-vars' rules (in the eslint:recommeded ruleset)
// does not work with type definitions
'no-unused-vars': 'off',
}
}]
}
Another option is to generate a TypeScript project with Vue CLI, and copying the resulting ESLint config.
I think it should be:
import { router } from './router';
Check if you have eslintConfig specified in both package.json and separate eslint config file. Both of these conflict and give this inconsistent state.
Its best to remove eslintConfig from package.json and move those to eslint config file.

Vuetify VIcon doesn't show up in Storybook

I'm developing a Vue app with Vuetify and also document the components with Storybook.
I'm writing the stories nicely, all components seem to show up in Storybook (like my custom components & the Vuetify components too). Except for VIcon.
I have a component that uses Vuetify's VIcon, and I couldn't get the icon to show up (in the real app there's no problem with that).
The setup:
src/plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'mdiSvg',
}
});
.storybook/vuetify_storybook.js
import Vue from 'vue';
import Vuetify from 'vuetify'; // loads all components
import 'vuetify/dist/vuetify.min.css'; // all the css for components
import config from '#/plugins/vuetify'; // basic config with theme
Vue.use(Vuetify);
export default new Vuetify(config);
.storybook/preview.js
import { addDecorator } from '#storybook/vue';
import vuetify from './vuetify_storybook';
addDecorator(() => ({
vuetify,
template: `
<v-app>
<story />
</v-app>
`,
}));
.storybook/main.js
const path = require('path');
module.exports = {
stories: [
'../stories/**/*.stories.js',
'../src/**/*.stories.js'
],
addons: [
'#storybook/addon-actions',
'#storybook/addon-links',
'#storybook/addon-knobs',
'#storybook/addon-storysource'
],
webpackFinal: async (config, { configType }) => {
config.resolve.extensions.push('.vue', '.css', '.less', '.scss', '.sass', '.html')
// Use Sass loader for vuetify components
config.module.rules.push({
test: /\.sass$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
include: path.resolve(__dirname, '../'),
});
config.module.rules.push({
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
additionalData: "#import '#/styles/variables.scss';"
}
}
],
});
config.module.rules.push({
resolve: {
alias: {
'#': path.resolve(__dirname, '../src'),
vue: 'vue/dist/vue.js',
'vue$': 'vue/dist/vue.esm.js',
},
},
});
// Return the altered config
return config;
},
};
CustomVIcon.stories.js
import { withKnobs } from '#storybook/addon-knobs'
export default {
title: 'Display that icon',
decorators: [withKnobs]
}
export const displayIcon = () => {
return {
template: `<v-icon>mdi-alert</v-icon>`
}
}
If I add a text that is not an mdi icon (like <v-icon>notmditext</v-icon>, then the text is displayed - but as soon as I add a - (dash/minus sign) to the string, it doesn't show up.
I can see the icon's HTML (well, part of it) in the console, only the ::before part is missing (that should be the actual icon). So styles are set, classes are added, etc when I inspect the Storybook page (where the icon should be).
Already tried adding https://www.npmjs.com/package/storybook-addon-jsx (as in the real case the component is rendered with JSX), nothing changed (no v-icon)
Already tried putting other components in the story (like VCard), and they showed up (and other stories work just perfectly)
Vue is 2.6.12, Vuetify 2.3.10, #storybook/vue 6.0.21 - so quite fresh
Also tried to import components from vuetify/lib (and not just vuetify) in the .storybook/vuetify_storybook.js & registering them locally (in the preview.js and the story file - no change)
OK, just needed another view on the things:
removed the link to the Material design icons CDN:
// remove this from public/index.html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/#mdi/font#latest/css/materialdesignicons.min.css">
changed the package from #mdi/js to #mdi/font
npm remove #mdi/js
npm install #mdi/font -D
imported the corresponding CSS in two places:
// add this to src/main.js & .storybook/vuetify_storybook.js
import '#mdi/font/css/materialdesignicons.css';
changed the Vuetify config
// in src/plugins/vuetify.js
icons: {
// iconfont: 'mdiSvg', // change this
iconfont: 'mdi', // to this
},
AND VOILÁ! VIcon shows up.
So, the problem was that I thought everything had been set up correctly, but it wasn't the case: the icons in the app were coming from the CDN (have not looked at the Network tab), and when I removed the CDN link from the index.html it immediately became apparent.
More on setting up the icons in Vuetify: Install Material Design Icons