import single Vuetify component in Nuxt.js? - javascript

I use Vuetify in nuxt.js.
How to use this only in dashboard layout?
in nuxt.config.js
modules: [
//['nuxt-leaflet', { /* module options */}],
'bootstrap-vue/nuxt',
'#nuxtjs/axios',
'#nuxtjs/pwa',
'#nuxtjs/auth',
'#nuxtjs/toast',
['#nuxtjs/vuetify', {rtl: true}],
// 'nuxt-i18n',
],

Are you using vuetify-loader with tree-shaking? If so, you can just import specific vuetify component into specific .vue component:
import { VTextField } from 'vuetify/lib';
and add:
components: { VTextField }
According to the #nuxtjs/vuetify module documentation, if you using the treeShake option, by default your Nuxt.js app will use only the needed vuetify component, and the bundle size didn't increase.
Uses vuetify-loader to enable automatic tree-shaking. Enabled only for production by default.
Another thing, If you are using Nuxt >= 2.9.0, use buildModules section instead:
{
buildModules: [
// Simple usage
'#nuxtjs/vuetify',
// With options
['#nuxtjs/vuetify', { /* module options */ }]
]
}

If you are using NuxtJS Vuetify Module (It seems that you are), I assume that your package.json does not have vuetify listed there, because it is the #nuxtjs/vuetify that imports it. Thus, you can't import it using only the module name. I suggest you to import it with it's complete path like the following:
import { VCard } from '~/node_modules/vuetify/lib';
Then register the component, of course.

Related

How to make Vue and Vite work with web components?

I want to migrate my Vue 2 project from webpack to Vite.
And have to use 3rd party web components that built with lit-element.
Those components throws errors during the runtime (by vue):
Unknown custom element: < foo-component > - did you register the
component correctly? For recursive components, make sure to provide
the "name" option.
And also (by lit-element)
Failed to set the 'adoptedStyleSheets' property on 'ShadowRoot':
Failed to convert value to 'CSSStyleSheet'.
As far as I can see those 3rd party web components do only this in theirs index files (inside node_modules):
import FooComponent from './FooComponent';
customElements.define('foo-component', FooComponent);
So before (with webpack setup) I just imported them and everything used to work. Well, actually for webpack lit-scss-loader was used also for those components.
I assume that Vite perhaps needs some additional configuration, or maybe something similar to "webpack" loader is needed here, but not sure what direction I have to move.
What I'm doing wrong?
Configure #vite/plugin-vue to ignore Lit elements, e.g., elements starting with my-lit in their registered name:
// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
// treat all components starting with `my-lit` as custom elements
isCustomElement: tag => tag.startsWith('my-lit'),
},
},
}),
],
})
demo
A couple of steps needed.
Imagine I have 3rd party webcomponents named "foo". So all of them are in node_modules/#foo.
I need to do these steps:
Tell Vite that all components starting with "foo-" are webcomponents.
isCustomElement: (tag) => tag.startsWith('foo-')
Add "postcssLit" plugin to help vite to prepare css for the webcomponents.
Tell to Vite how to threat css paths for webcomponents.
'~#foo': fileURLToPath(new URL('./node_modules/#foo', import.meta.url))
Here is the full config:
//vite.config.ts
import postcssLit from 'rollup-plugin-postcss-lit';
export default defineConfig({
plugins: [
vue(
{
template: {
compilerOptions: {
// 1. Tell Vite that all components starting with "foo-" are webcomponents
isCustomElement: (tag) => tag.startsWith('foo-')
}
}
}
),
vueJsx(),
// 2. This "postcssLit" plugin helps to make css for the webcomponents
postcssLit()
],
resolve: {
alias: {
// 3. Tell to Vite how to threat css paths for webcomponents
'~#foo': fileURLToPath(new URL('./node_modules/#foo', import.meta.url))
}
}
});

Get Vuetify icons to work when loading page from filesystem

I have a vue project created with vue cli 3 and i am using Vuetify v2.0.19.
My project requires me to be able to build the project and output a single html file so that it can be downloaded and ran offline in a phonegap app(safari v13). I am able to meet all the requirements and get my project to show up in the phonegap app but the icons do not render. For example, where I use <v-icon>info</v-icon> it will render INFO, etc.
I have followed the Vuetify Quick-Start, Icons and Browser Support pages and several other Stack Overflow threads answers but can not get my icons to render.
I basically need the fonts included in my single file. When I load the page in the phonegap app or when serving from filesystem I get 'not found' errors in the console (file:///D:/fonts/materialdesignicons-webfont.27cb2cf1.woff2) I am aware the path is wrong but how can I get the icons to be part of the build?
Is this possible?
To get the single html file with js and css I added the npm packages html-webpack-plugin and html-webpack-inline-source-plugin and in my vue.config.js I have the following:
const HtmlWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
module.exports = {
css: {
extract: false,
},
configureWebpack: {
optimization: {
splitChunks: false
},
plugins: [
new HtmlWebpackPlugin({
filename: 'output/output.html',
template: 'src/output-template.html',
inlineSource: '.(js|css)$' // embed all javascript and css inline
}),
new HtmlWebpackInlineSourcePlugin()
]
},
transpileDependencies:[/node_modules[/\\\\]vuetify[/\\\\]/]
}
and in src/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import '#mdi/font/css/materialdesignicons.css'
Vue.use(Vuetify)
export default new Vuetify({
icons: {
iconfont: 'mdi',
}
})
Finally figure out how to get this working how I needed it using the method described here.
// plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
Vue.use(Vuetify)
export default new Vuetify({
icons: {
iconfont: 'mdiSvg'
}
})
And in the components that I am using the icons (using the mdi information icon for example)
<template>
...
<v-icon>{{svgPath}}</v-icon>
...
</template>
<script>
import {mdiInformation} from '#mdi/js'
export default {
...
data() {
return {
svgPath: mdiInformation
}
}
}
</script>

Eslint not defined issue with imports

I have an App.js file like this:
import './bootstrap';
if (document.getElementById('vue')) {
new Vue({
});
}
It imports a bootstrap javascript file which holds the Vue npm package(node module).
In my bootstrap file I import it like so:
import Vue from 'vue';
When I run eslint with this setup though I get told:
'Vue' is not defined.
If the eslinter only checks per file this seems really obvious since the actually Vue variable is defined in a file that is imported. Can this be fixed cleanly though or do I have to edit my .eslintrc.js for a case like this?
I believe ES6 imports only apply to the current file (which is the main benefit of a module system – to avoid global contamination). Importing a module without bindings won't also make that module's imports available; they remain scoped to that module only.
You have a few options:
You can explicitly import it everywhere you need it (the intended way with modules).
import Vue from 'vue';
You can export Vue (and anything else) from your bootstrap file and import everything:
In bootstrap.js:
import Vue from 'vue';
export { Vue };
In App.js:
import * as bootstrap from './bootstrap';
const Vue = bootstrap.Vue;
You can make Vue global from in your bootstrap file, but it defeats the benefit of modules:
window.Vue = Vue;
The import and export articles at MDN give a good overview of different possible ways of importing and exporting.
You can try few configuration of eslint in .eslintrc to get this working. This error is coming with es6-modules, you can try playing with following config:
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": 2
}
}

How to ignore raw loader for testing webpack

I have some components with svg's loaded inline using webpack raw loader e.g...
import React, { Component } from 'react'
import svg from '!raw!../assets/images/logo.svg'
export default class Logo extends Component {
render() {
return (<a href={this.props.url} dangerouslySetInnerHTML={{__html: svg}} />)
}
}
When trying to test these components server side using tape, they fall over. If I have css modules included, it is no problem, I can use css-modules-require-hook but svg's will not work. So I really need a raw loader require hook or something like that.
require('babel-register');
require('css-modules-require-hook/preset');
/* tests after this can import components with css includes */
I tried using isomorphic-ensure but this did not work.
require('babel-register');
require('css-modules-require-hook/preset');
require('isomorphic-ensure')({
loaders: {
raw: require('raw-loader'),
raw: require('react-svgdom-loader')
},
dirname: __dirname
})
I get the following error:
Cannot find module '!raw!../assets/images/
If you're not using webpack for your tests then you could use the ignore-styles module.
You may have to configure it if you plan to use it with css-modules-require-hook as it will also also ignore CSS files by default. e.g:
require('ignore-styles').register(['.svg'])

how to config a module bundler divide by folder with webpack?

I get the file structure like this
before build
I want to make it like this below with webpack
after build
BTW, I also want to use ES6 import and export for the module loader,
such as in nav.js
class Nav extends Component {
// react code here
}
export defalt Nav
and in header.js
import Nav from `nav/bundle`
// header react code
// .......
export defalt Header
also need the bundle the redux and react-route npm package within the node_module
is it possible for webpack to do this stuff? some suggestions?
Here's a rough idea you could try to adapt:
{
// generate these dynamically through JavaScript
entry: {
footer: <path to footer js>,
...
},
output: {
path: './demo',
filename: '[name]/bundle.js' // name maps to entry keys
},
...
}

Categories