I'm struggling a lot with how to include Vuetify a default Vue.js project created using WebStorm. It's really to do with how the default Vue.js projects are set up in WebStorm rather than the editor itself as it seems to use an approach different to others I can find. I get errors of "Unknown custom element <v-alert>" (for example). I'm failing to find answers on how to do this because WebStorm's default set-up is different from all the how-tos I can find.
My App.vue file is as follows:
<template>
<div id="app">
<img alt="Vue logo" src="../../assets/logo.png">
<HelloWorld msg="Welcome to your Vue.js app"/>
<v-alert dismissible>Why does this show as an unknown custom element?</v-alert>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld,
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
My main.js file is as follows:
import Vue from 'vue'
import App from './App.vue'
// eslint-disable-next-line no-unused-vars
import Vuetify from "vuetify";
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
My package.json file is like so:
{
"name": "my-vue-app",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.4",
"deepmerge": "^4.2.2",
"sass": "^1.26.3",
"sass-loader": "^8.0.2",
"vue": "^2.6.11",
"vuetify": "^2.2.18"
},
"devDependencies": {
"#vue/cli-plugin-babel": "~4.2.0",
"#vue/cli-plugin-eslint": "~4.2.0",
"#vue/cli-service": "~4.2.0",
"babel-eslint": "^10.0.3",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.1.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
I ran npm install vuetify which seemed to proceed correctly and I get no errors when building or serving it. But I don't know how to get my Vue app to import the Vuetify components.
All the documentation I can find talks about either instantiating the Vue app directly, which I'm not doing, or else if it talks about single component .vue files the examples all have module.exports which again, I don't have in the project built by WebStorm.
I've tried adding Vuetify as one of the imports in the script section of the App.vue and I've also tried setting Vuetify and v-alert as components in the components section of the App.vue file but can't get either to work. Thanks for any help.
I'm struggling a lot with how to include Vuetify a default Vue.js project created using Webstorm
Just follow the instructions from https://vuetifyjs.com/en/getting-started/quick-start/:
create a new project by either running vue create in terminal or using New > Project > Vue.js in IDE (use the default project setup)
in terminal, run vue add vuetify
My main.js file is as follows:
you didn't register Vuetify (Vue.use(Vuetify); if you don't like to follow the standard way (i.e. use vue add), try the instructions from https://vuetifyjs.com/en/getting-started/quick-start/#webpack-install
Related
I've been reading on the internet, all foruns and communities that are some issues with Vite+VueJS3 at the .mount("#app") point.
I am facing this exactly problem and can't figure how to fix it!
Uncaught DOMException: String contains an invalid character pointing to app.mount('#app'); at app.js.
Let's see some code:
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '#vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/sass/app.scss',
'resources/js/app.js',
],
refresh: true,
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
resolve: {
alias: {
'vue': 'vue/dist/vue.esm-bundler.js',
},
},
});
app.js
import { createApp } from 'vue';
import Lead from './components/Lead.vue';
import Atendimento from './components/Atendimento.vue';
const app = createApp({
components: {
Lead,
Atendimento,
render: h => h(app)
}
});
app.component('atendimento', Atendimento);
app.component('lead', Lead);
app.mount('#app');
The app.blade.php witch all Blade extends has the <div id="app"> clearerly, so there is no problem (I guess) with disposition of the script.
You can see, at vite.config.js that there are a alias pointing to the dev compiler:
resolve: {
alias: {
'vue': 'vue/dist/vue.esm-bundler.js',
},
},
Right now I am pulling all my hair out of my head!
Can anyone help me?
Thanks in advance!
Since I couldn't solve this issue, I decided to migrate from Vite to Laravel-mix and used ChatGPT to help.
Check this out:
Here are the steps to migrate from ViteJS to Laravel-mix in a Laravel project:
Install Laravel-mix by running npm install laravel-mix.
Create a new file, webpack.mix.js at the root of your project.
Copy the following code into webpack.mix.js:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css');
In your package.json file, change the scripts section from:
"scripts": {
"dev": "vite",
"build": "vite build"
}
to:
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
}
Remove the vite.config.js file, since Laravel-mix uses the webpack.mix.js file to configure webpack
Remove the vite package by running `npm uninstall vite`
Test the migration by running npm run dev and verify that your JavaScript and CSS assets are being compiled as expected.
That's it! You have successfully migrated from ViteJS to Laravel-mix.
The problem for a production-build seems to be the place there the #vite is included.
Change your app.blade to this and it will work.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>How To Install Vue 3 in Laravel 9 with Vite</title>
</head>
<body>
<div id="app">
</div>
#vite(['resources/css/app.css', 'resources/js/app.js'])
</body>
</html>
As stated, the package #meforma/vue-toaster has a clear() function in the API here.
My vue and vite project setup:
main.js
import Toaster from '#meforma/vue-toaster'
app.use(Toaster, {
position: 'top',
useDefaultCss: false,
pauseOnHover: false
}).provide('toast', app.config.globalProperties.$toast)
Example.vue
<template>
<div class="view">
<div class="mt-10 flex gap-5">
<button class="btn btn-stealth" #click="showToast('default')">Default</button>
<button class="btn btn-primary" #click="showToast('primary')">Primary</button>
<button class="btn btn-success" #click="showToast('success')">Success</button>
<button class="btn btn-info" #click="showToast('info')">Info</button>
<button class="btn btn-warning" #click="showToast('warning')">Warning</button>
<button class="btn btn-danger" #click="showToast('error')">Error</button>
</div>
<div class="mt-10">
<button class="btn" #click="toast.clear">Clear Toasts</button>
<br><br>
<button class="btn" #click="clearToasts">Timeout Clear</button>
</div>
</div>
</template>
<script setup>
import { inject } from 'vue'
const toast = inject('toast')
// this works
function showToast (type) {
toast.show(`This is the ${type} type toast.`, {
type: type,
duration: false
})
}
// only works when vue-toaster is local in my projects src folder :S
function clearToasts () {
toast.clear()
}
</script>
package.json
{
"name": "test-project",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vite --open",
"build": "vite build --out-dir dist",
"lint": "eslint src"
},
"dependencies": {
"#meforma/vue-toaster": "^1.3.0",
"#vitejs/plugin-vue": "^2.2.4",
"animate.css": "^4.1.1",
"axios": "^0.26.0",
"axios-auth-refresh": "^3.2.2",
"core-js": "^3.21.1",
"microtip": "^0.2.2",
"pinia": "^2.0.13",
"pinia-plugin-persistedstate": "^1.5.1",
"sass": "^1.49.9",
"vue": "^3.2.31",
"vue-meta": "^3.0.0-alpha.10",
"vue-router": "^4.0.13"
},
"devDependencies": {
"#tailwindcss/aspect-ratio": "^0.4.0",
"#tailwindcss/forms": "^0.5.0",
"#tailwindcss/line-clamp": "^0.3.1",
"#tailwindcss/typography": "^0.5.2",
"#vue/compiler-sfc": "^3.2.31",
"#vue/eslint-config-standard": "^6.1.0",
"autoprefixer": "^10.4.2",
"eslint": "^8.12.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-standard": "^4.1.0",
"eslint-plugin-vue": "^8.6.0",
"postcss": "^8.4.7",
"tailwindcss": "^3.0.23",
"vite": "^2.8.6"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"#vue/standard"
],
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
But, when I pull the package into the local src folder and import it via there, the clear works perfectly. No code changes other than moving where the code lives.
I have absolutely no idea why this is the case, if anyone has ever seen anything similar, it would be greatly appreciated.
I looked through all the code of the project github and created an issue there.
I thought it might be something to do with the event bus, but then again, it works when pulled from node_modules so hence why this is such a head scratcher for me.
Thanks!
Edit 1:
Updated code example that you can run locally to experience the same issue: https://codesandbox.io/s/vue3-toaster-test-forked-m64htx?file=/src/components/HelloWorld.vue:854-868
Specifically in the main.js, swapping where the vue-toaster is pulled in from causes the clear function to stop/start working. Clearing works when vue-toaster is located within my project /src but fails to work when pulled in from node_modules.
Edit 2:
Here is a stackblitz showing the same issue (using vite too): https://stackblitz.com/edit/vitejs-vite-uqcdgd?file=src%2Fmain.js,src%2FApp.vue
So after forking #meforma/vue-toaster, rewriting the Toaster in the composition API and changing the event bus to use mitt, even went as far as to publish it to npmjs so I could replicate everything as close as possible to how I use the package originally.... it turns out that my re-written package was having the exact same issue with Vite.
Digging in further, I noticed in my /node_modules/ there was a folder: /node_modules/.vite/deps/ which had files like: #shanehoban_vue-toaster.js... so I started googling and found out that perhaps I should exclude the package from Vite optimizations... like so:
vite.config.js
export default defineConfig({
optimizeDeps: {
exclude: [
"#meforma/vue-toaster"
]
},
....
And now, the clear... is working.
The original answer is a misunderstanding. So I edited it to follow the point of the question.
Problem
The package does NOT work when using it from node_modules.
The package does work when folks it into the project and use it directly
Reason
Vite only caches JS files from the package. We can see it in node_modules/.vite/deps/#meforma_vue-toaster.js
// The .vue file is point to original file
// node_modules/#meforma/vue-toaster/src/index.js
import Toaster2 from "/Users/admin/Work/test-projects/vite-demo-vue-plugin/node_modules/#meforma/vue-toaster/src/Toaster.vue";
// node_modules/#meforma/vue-toaster/src/api.js
import Toaster from "/Users/admin/Work/test-projects/vite-demo-vue-plugin/node_modules/#meforma/vue-toaster/src/Toaster.vue";
// The js file is cached here so Singleton pattern will breaks
// node_modules/#meforma/vue-toaster/src/helpers/event-bus.js
var Event = class {
constructor() {
this.queue = {};
}
...
}
The event-bus.js is cached in the .vite folder but the Toaster.vue file is not. So when the Toaster.vue uses the EventBus, it will call the instance from node_modules/#meforma/vue-toaster/ instead of the one in the .vite cached folder. And it breaks the Singleton pattern of the original package.
This bug might happen to any package with uncachable files mixed with JS files.
Workaround
This bug can be fixed only from the Vite side. So before Vite fixes it we need to exclude the package from the Vite cache as shanehoban's answer points out:
// vite.config.js
export default defineConfig({
optimizeDeps: {
exclude: [
"#meforma/vue-toaster"
]
},
....
Github issue
I'm trying to add Vue-Splide to my Nuxt project, after following the Vue-Splide documentation to install the plugin, and registering it as a Nuxt plugin I get the error Cannot use import statement outside a module.
nuxt.config.js
buildDir: '../functions/nuxt',
build: {
publicPath: '/public/',
vendor: [''],
extractCSS: true,
babel: {
presets: [
'#babel/preset-env'
],
plugins: [
["#babel/plugin-transform-runtime"]
]
}
},
plugins: [
{ src: '~/plugins/splide.client.js', mode: "client" }
],
splide.client.js
import Vue from 'vue';
import VueSplide from '#splidejs/vue-splide';
import '#splidejs/splide/dist/css/themes/splide-default.min.css';
Vue.use(VueSplide);
template
<splide :options="{ rewind: true }" class="banner-container">
<splide-slide class="slide" v-for="slide in slides" :key="slide.id">
<img :src="slide.imagen" :alt="slide.tombre" />
</splide-slide>
</splide>
After transpiling Vue-Splide I now get the error window is not defined, and the stacktrace shows it's happening on node_modules\#splidejs\splide\dist\js\splide.js, I tried surrounding the splide tags with <client-only></client-only>, but that didn't seem to work.
What else am I missing here?
Updating to include my dependencies
"dependencies": {
"#nuxtjs/firebase": "^7.6.1",
"#splidejs/vue-splide": "^0.3.5",
"firebase": "^8.9.1",
"isomorphic-fetch": "^3.0.0",
"nuxt": "^2.0.0"
},
"devDependencies": {
"#babel/plugin-transform-runtime": "^7.15.0",
"#babel/preset-env": "^7.15.6",
"#babel/runtime": "^7.15.4",
"#nuxtjs/tailwindcss": "^4.2.1",
"autoprefixer": "^10.4.0",
"babel-eslint": "^10.0.1",
"babel-plugin-module-resolver": "^4.1.0",
"eslint": "^4.19.1",
"eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^4.0.2",
"eslint-plugin-vue": "^7.19.1",
"firebase-tools": "^9.22.0",
"node-sass": "^6.0.1",
"postcss": "^8.3.11",
"sass-loader": "^12.3.0",
"tailwindcss": "^2.2.19"
}
The documentation of the vue-splide integration is clearly talking about Vue3 composition API.
Checking in the github issues of vue-splide, I found this one which is referencing a solution that you've linked above. Meanwhile, when trying this, those are the warnings that I do have in my CLI.
Those are also related to Vue3 (which is not compatible with Nuxt2, only Nuxt3 supports Vue3). Looking at the date of all the posts, it looks like it was matching somewhat the time-frame when Vue3 was still in a beta-limbo and probably not adopted by everybody.
At some point, I guessed that the package maybe lost some retro-compatibility with Vue2 in the next months. I then tried to install the version 0.3.5 of #splidejs/vue-splide rather than the latest one and it's working perfectly fine with it!
Here is the whole setup to have it working with Nuxt2
nuxt.config.js
plugins: [{ src: '~/plugins/splide.js', mode: 'client' }],
PS: no need for a transpile because this is not the issue at all here
/plugins/splide.js
import Vue from 'vue'
import VueSplide from '#splidejs/vue-splide'
import '#splidejs/splide/dist/css/themes/splide-default.min.css'
Vue.use(VueSplide)
/pages/index.vue
<template>
<client-only>
<Splide :options="{ rewind: true }">
<SplideSlide>
<img
src="https://images.unsplash.com/photo-1638204958375-4824be216720?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=776&q=80"
alt="Sample 1"
/>
</SplideSlide>
<SplideSlide>
<img
src="https://images.unsplash.com/photo-1638176061592-d8475d970c19?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80"
alt="Sample 2"
/>
</SplideSlide>
</Splide>
</client-only>
</template>
It works perfectly fine
I've reported the issue in the github issue, if somebody wants to have more up-to date info or an official answer from the mantainer.
EDIT: we received a confirmation on the non retro-compatibility. Also, the usage of <client-only> is also required to prevent DOM mismatch.
Issue was caused by the configuration required for Firebase hosting if following Firebase's Server-Side Render Vue Apps with Nuxt.js video.
By removing the line buildDir: '../functions/nuxt' in the nuxt.config.js file the project runs fine locally, however, in order to deploy to Firebase you have to:
Replace publicPath: '/public/' with publicPath: '/', both in src/nuxt.config.js, and functions/index.js.
Run npm run build.
Copy the contents of src/.nuxt to functions/nuxt.
Copy the contents of src/.nuxt/dist/client and src/.nuxt/dist/server to public/.
For the moment I do not know if there's a way for vue-splide to work while building to the functions folder, as I already tried installing vue-splide on the functions project with no success.
In my project, I have two scss empty login component files.
If the component loads the CSS:
styleUrls: ["./login-common.css", "./login.css"]
when I run ns run ios the compiler would throw a CSS not found error.
If I change it to SCSS
styleUrls: ["./login-common.scss", "./login.scss"]
I don't have any errors but the login screen on the simulator is blank
If I comment the styleUrls line, the login screen would be rendered.
I think I should use the .css version, and probably add/remove some dependency and probably change some config files. Any idea?
My package.json :
"devDependencies": {
"#angular/compiler-cli": "~11.2.7",
"#nativescript/ios": "8.0.0",
"#nativescript/types": "~8.0.0",
"#nativescript/webpack": "beta",
"#ngtools/webpack": "~11.2.6",
"sass-loader": "^12.1.0",
"typescript": "~4.0.0",
"webpack": "^5.49.0"
},
My webpack.config.js:
const webpack = require("#nativescript/webpack");
module.exports = (env) => {
webpack.init(env);
webpack.chainWebpack(config => {
config.module
.rule('scss')
.use('sass-loader')
.options({ sassOptions: { indentedSyntax: false } })
})
return webpack.resolveConfig();
};
You need to run
npm i sass
That will install the sass interpreter.
And add a test to your webpack config
config.module
.rule('scss')
.test( /\.s[ac]ss$/i)
.use(
// Compiles Sass to CSS
"sass-loader"
)
I have deployed my application to aws and I see that the application renders fine, except that the syncfusion controls do not render correctly. Google chrome console does not show any errors.
The application renders correctly in my local machine.
To fix this, it was suggested I move the import '#syncfusion/**/styles/material.css' statements in the individual vue component to App.vue (as documented here). I however get a "Failed to resolve loader: sass-loader, You may need to install it" error(the application has node-sass, sass-loader installed already).
How should I include css files along with scss files, in my application?
Before: vocabulary.vue:
<script>
import '#syncfusion/ej2-base/styles/material.css';
import '#syncfusion/ej2-vue-inputs/styles/material.css';
package.json:
"devDependencies": {
"node-sass": "^4.12.0",
"sass-loader": "^7.1.0",
}
vue.config.js:
module.exports = {
publicPath: '/',
transpileDependencies: [
'vue-echarts',
'resize-detector'
],
configureWebpack: {
devtool: 'source-map',
optimization: {
splitChunks: {
chunks: 'all'
}
}
}
}
App.Vue:
<style>
#import "../node_modules/#syncfusion/ej2-base/styles/material.css";
#import "../node_modules/#syncfusion/ej2-vue-inputs/styles/material.css";
</style>
Deleting the npm packages and re-installing them again fixed the issue.