TypeError: Cannot read property 'rtl' of undefined

Viewed 3653

I'm trying to build a vuejs (that uses vuetify 2.1.4) component library and import it into another application locally via npm link but I keep on getting multiple errors saying either

TypeError: Cannot read property 'rtl' of undefined

or

TypeError: Cannot read property 'lang' of undefined

Note. The basic component for testing called Test works as it doesn't include anything from Vuetify.

Here's a screenshot

enter image description here

App1 (App that's being built)

index.js

import Agent from '@/components/Agent'
import Test from '@/components/Test'

const AgentLibrary = {
  install(Vue, options = {}) {
    Vue.component(Test.name, Test)
    Vue.component(Agent.name, Agent)
  }
}

export default AgentLibrary

Agent.vue

<template>
  <v-container>
    <!-- Header -->
    <v-row>
      <v-col md="5" class="col-center-content">
        <h2>Agent Information</h2>
      </v-col>

      <v-spacer></v-spacer>

      <v-col md="3">
        <v-btn text rounded>Cancle</v-btn>
        <v-btn rounded>Save</v-btn>
      </v-col>
    </v-row>

    <!-- Form -->
    <v-row>
      <v-col md="5">
        <AvatarUploader />
      </v-col>

      <v-col md="7">
        <v-row>
          <v-col md="6">
            <v-select rounded placeholder="Agent Type" outlined></v-select>
          </v-col>
          <v-col md="6">
            <v-select rounded placeholder="No. Parents" outlined></v-select>
          </v-col>
          <v-col md="12">
            <v-text-field rounded placeholder="Licensekey" outlined disabled></v-text-field>
          </v-col>
        </v-row>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
import AvatarUploader from "@/components/AvatarUploader";

export default {
  name: "Agent",
  components: {
    AvatarUploader
  }
};
</script>
<style lang="scss" scoped>
span {
  font-size: 20px;
  color: rgb(162 162 162);
}
.col-center-content {
  display: flex;
  justify-content: center;
}
</style>

test.vue

<template>
<div>
    <h1>HELLO WORLD!</h1>
</div>
</template>
<script>
export default {
    name: "Test",
    mounted() {
        console.log("HELLO WORLD!")
    }
}
</script>
<style lang="scss" scoped>

</style>

package.json

{
  "name": "AgentComponents",
  "main": "dist/AgentComponents.umd.js",
  "module": "dist/AgentComponents.esm.js",
  "unpkg": "dist/AgentComponents.min.js",
  "browser": {
    "./sfc": "src/components/Agent.vue"
  },
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "lint": "vue-cli-service lint",
    "build": "vue-cli-service build",
    "build:plugin": "cross-env NODE_ENV=production NODE_OPTIONS='--max-old-space-size=8192' vue-cli-service build --target lib --inline-vue --name AgentComponents src/index.js"
  },
  "dependencies": {
    "core-js": "^2.6.5",
    "moment": "^2.24.0",
    "rollup": "^1.24.0",
    "vue": "^2.6.10",
    "vue-router": "^3.0.3",
    "vuetify": "^2.1.4",
    "vuex": "^3.0.1"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.12.0",
    "@vue/cli-plugin-eslint": "^3.12.0",
    "@vue/cli-service": "^3.12.0",
    "cross-env": "^5.2.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "rollup-plugin-buble": "^0.19.8",
    "rollup-plugin-commonjs": "^10.1.0",
    "rollup-plugin-vue": "^5.0.1",
    "sass": "^1.17.4",
    "sass-loader": "^7.1.0",
    "vue-cli-plugin-vuetify": "^1.0.2",
    "vue-template-compiler": "^2.6.10",
    "vuetify-loader": "^1.2.2"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "postcss": {
    "plugins": {
      "autoprefixer": {}
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}

avataruploader.vue

<template>
  <v-row>
    <v-col md="12" class="col-center-content">
      <v-avatar size="230" color="rgb(232 239 244)">
        <v-img aspect-ratio="1" width="200px" src="@/assets/user-alt.png"></v-img>
      </v-avatar>
    </v-col>

    <v-col md="12">
      <v-file-input
        ref="file"
        accept="image/png, image/jpeg, image/bmp"
        placeholder="Pick a logo"
        label="Your photo or company logo"
      ></v-file-input>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "AvatarUploader"
};
</script>
<style lang="scss" scoped>
span {
  font-size: 20px;
  color: rgb(162 162 162);
}
.col-center-content {
  display: flex;
  justify-content: center;
}
</style>

App2 (App that is importing App1)

main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

import vuetify from './plugins/vuetify';

import "AgentComponents"

console.log(AgentComponents.default)

Vue.use(AgentComponents.default)

new Vue({
     vuetify,
  render: h => h(App)
}).$mount('#app')

app.vue

<template>
  <v-app>
      <Agent/>
  </v-app>
</template>

<script>

export default {
  name: 'App',
  components: {
  },
  data: () => ({
    //
  }),
};
</script>

plugins/vuetify.js

import Vue from 'vue';
import Vuetify from 'vuetify/lib';

Vue.use(Vuetify);

export default new Vuetify({
  icons: {
    iconfont: 'mdi',
  },
});

I expected to see my Agent component in App1 displayed and working as usual (running npm run serve) when built and imported into App2 without any errors.

Errors being displayed in my chrome browser can be seen bellow: I see multiple of the errors shown bellow in the Chrome console when running

TypeError: Cannot read property 'rtl' of undefined
    at VueComponent.labelPosition (AgentComponents.umd.js?7204:17243)
    at Watcher.get (AgentComponents.umd.js?7204:5517)
    at Watcher.evaluate (AgentComponents.umd.js?7204:5626)
    at VueComponent.computedGetter [as labelPosition] (AgentComponents.umd.js?7204:5791)
    at VueComponent.genLabel (AgentComponents.umd.js?7204:17422)
    at VueComponent.genTextFieldSlot (AgentComponents.umd.js?7204:17541)
    at VueComponent.genDefaultSlot (AgentComponents.umd.js?7204:17422)
    at VueComponent.genInputSlot (AgentComponents.umd.js?7204:16327)
    at VueComponent.genInputSlot (AgentComponents.umd.js?7204:17422)
    at VueComponent.genControl (AgentComponents.umd.js?7204:16290)
TypeError: Cannot read property 'lang' of undefined
    at VueComponent.listData (AgentComponents.umd.js?7204:22317)
    at Watcher.get (AgentComponents.umd.js?7204:5517)
    at Watcher.evaluate (AgentComponents.umd.js?7204:5626)
    at VueComponent.computedGetter [as listData] (AgentComponents.umd.js?7204:5791)
    at VueComponent.staticList (AgentComponents.umd.js?7204:22317)
    at Watcher.get (AgentComponents.umd.js?7204:5517)
    at Watcher.evaluate (AgentComponents.umd.js?7204:5626)
    at VueComponent.computedGetter [as staticList] (AgentComponents.umd.js?7204:5791)
    at VueComponent.genList (AgentComponents.umd.js?7204:22596)
    at VueComponent.genMenu (AgentComponents.umd.js?7204:22624)
1 Answers

This is happening because of the --inline-vue flag. It tells Vue to create its own instance and bundle it inside your library (see here for a detailed description).

When you instantiate Vue in your code, you do something like this:

new Vue({
    vuetify,
    ...
});

However, when Vue does this for you, it doesn't pass the vuetify plugin as an option to the Vue constructor.

One solution is removing the --inline-vue flag. But, I'm not sure this is relevant in your case.

I opened a Github issue/question on the Vuetify repo, https://github.com/vuetifyjs/vuetify/issues/10198, asking if they're planning on supporting this flag.

Related