Hi guys, first of all Im sorry I know this is common one but i just can't figure it out.
Im trying the basic example from the documentation on one input in a single file component.
I know it's a webpack related thing caused by two vue references (the full build imported by me and the runtime build from vee validate) clonflicting.
I tried to do the alias fix but Im still getting warnings.
Im using [email protected] and [email protected].
This is my laravel mix file with the alias.
const mix = require('laravel-mix');
let webpackConfig = {
resolve: {
alias: {
'vue$': path.resolve(__dirname ,'node_modules/vue/dist/vue.esm'),
}
}
};
mix.webpackConfig(webpackConfig)
.js('resources/js/vendor.js', 'public/js')
.js('resources/js/admin.js', 'public/js')
.sass('resources/sass/vendor.scss', 'public/css')
.sass('resources/sass/admin/admin.scss', 'public/css')
.version();
This is my vendor file where I import vue, lodash and buefy.
require('./bootstrap');
import Vue from 'vue';
window.Vue = Vue;
import _ from 'lodash';
Object.defineProperty(Vue.prototype, '_', { value: _ });
import Buefy from 'buefy';
Vue.use(Buefy,{
defaultIconPack: 'fa',
defaultDayNames: ["D", "L", "M", "M", "J", "V", "S"],
});
And this is my admin file where I do my component registration and my vue node.
Vue.component('create-event-form', require('./components/admin/event/CreateEventForm.vue').default);
Vue.component('show-event', require('./components/admin/event/ShowEvent.vue').default);
Vue.component('edit-event-form', require('./components/admin/event/EditEventForm.vue').default);
...
var root = new Vue({
el: '#admin-root',
});
As I said the alias seems to be working properly but Im still getting warnings, Im missing something? I need to import vue in an especial way? or do something extra when importing vee validate? and once again sorry for the issue when itâs not entirely related at all with the framework.
This is an issue while importing vue twice by mistake, you should alias the vue version in your web pack config.
Not a vee-validate issue
@logaretm I've been banging my head on this issue for a few hours now. I've seen you say multiple times this is not a vee-validate issue and say we have to use an alias.
First, I've not managed to set a Vue alias in a basic Vue project bootstrapped with vue-cli. I've tried everything I could find, the "readonly" errors remain. Can you update the documentation with a clear way to fix this issue please?
Second, I've found that this could be avoided if vee-validate was a plugin that would get its Vue instance from the one passed to the install method. Maybe that's something that could be considered in the future?
@logaretm I've been banging my head on this issue for a few hours now. I've seen you say multiple times this is not a vee-validate issue and say we have to use an alias.
First, I've not managed to set a Vue alias in a basic Vue project bootstrapped with vue-cli. I've tried everything I could find, the "readonly" errors remain. Can you update the documentation with a clear way to fix this issue please?
Second, I've found that this could be avoided if vee-validate was a plugin that would get its Vue instance from the one passed to the install method. Maybe that's something that could be considered in the future?
Hey @simonjodet! Maybe my journey through this issue may help.
Well first of all, this is totally a webpack thing, in my case this happened because I was importing (as in the docs example) vee validate directly in my single file component so at the moment of mixing the admin.js file where Im registering all my single file components, my main instance is on my vendor.js, so basiclly webpack imports vue again in the admin.js file because vue never âlivedâ on this file at the moment of the mix.
So whatâs the fix? Actually itâs super simple and a little bit embarrassing, I just moved that import from my single file component to the vendor.js file so I can register the validation provider and observer components globally in my vue instance.
You can read about this here.
This is how my vendor.js file ended.
require('./bootstrap');
import Vue from 'vue';
window.Vue = Vue;
import _ from 'lodash';
Object.defineProperty(Vue.prototype, '_', { value: _ });
import Buefy from 'buefy';
Vue.use(Buefy,{
defaultIconPack: 'fa',
defaultDayNames: ["D", "L", "M", "M", "J", "V", "S"],
});
// vee validate import and component registration moved here
import { ValidationObserver, ValidationProvider, extend } from 'vee-validate';
import { required } from 'vee-validate/dist/rules';
extend('required', {
...required,
message: 'Este campo es requerido.'
});
Vue.component('ValidationProvider', ValidationProvider);
Vue.component('ValidationObserver', ValidationObserver);
I hope this helps, just some notes, vee validate doesnât import vue when itâs imported, the alias thing itâs just to select what build itâs going to be used in that mix, actually I didnât even use it as using import âVueâ from âvueâ; imports the compiler + runtime build, this is what I need atm. Why using just the runtime? First of all this a HUGE part of vue and how it works on itâs core, you can find more info here, but basically the documentation stays that runtime builds are 30% lighter in size.
@josermzte I used the Vue.component syntax to register the ValidationProvider and the ValidationObserver before posting, this didn't solve my problem.
My use case is different from yours. I have library of form control components that I'm using in my main app.
When I work in my library project, I don't have any problem. But as soon as I build this library and use it in my main app, I get the readonly warnings because vee-validate is importing Vue instead of getting it as an injected dependency by exposing an install method as it seems to be the correct way to do.
My library is built with the correct target:
vue-cli-service build --target lib --name controls src/main-lib.js
That means according to the Vue documentation that Vue is not packaged in my library. But it seems Vue is still included in the package because of vee-validate. Also, I've removed the vee-validate dependency to check if it was the origin of my problems and it works without vee-validate included.
Basically, I can't find a way to tell webpack to ignore the Vue dependency imported by vee-validate.
This doesn't happen with other libraries like Buefy or vue-i18n because the use a plugin interface, the install method I was referring above: https://vuejs.org/v2/guide/plugins.html#Writing-a-Plugin
cc @logaretm
@simonjodet Since v3 no longer uses a global mixin/directive, it no longer needs access to the Vue instance with the Vue.use. Other libraries like i18n still inject global stuff and that's why they need access to the Vue prototype. I expect with Vue 3 most plugins will move away from this style.
While I do understand that the problem is being caused by vee-validate, it may as well be caused by any library that uses Vue.extend which is the only way to bundle Vue components with TypeScript without dependencies.
I think the solutions posted here don't work for you because you are bundling a library that depends on vee-validate which will be used in another library/project.
I haven't toyed around with the component build target with vue-cli but to my knowledge, you can chain webpack config in vue.config.js.
With that in mind you might want to check if, by adding vue as an external, it could solve your issue.
@logaretm First, thanks for the quick reply, much appreciated.
I tried both the external solution (even though it should be automatic with the lib target) using the chaining (as much as I understand this stuff) but couldn't make it work.
Due to business constraints, I unfortunately had to switch to another validation library even though vee-validate was definitely my favorite one.
Thanks again and I'll come back to it on another project. Cheers.