vuejs / composition-api

Composition API plugin for Vue 2
https://composition-api.vuejs.org/
MIT License
4.19k stars 342 forks source link

How to properly setup a npm package using Composition API? #340

Closed JiProchazka closed 4 years ago

JiProchazka commented 4 years ago

I have a npm package using components which are calling inject:

<template>
    <MessageItem
      :type="m.type"
      v-for="(m, index) in messages"
      :key="`message-${index}`"
      :message="m.message"
      :tooltip="m.description"
    />
  </div>
</template>
<script>
import { computed, inject } from "@vue/composition-api";
import MessageItem from "@/components/common/MessageItem";
export default {
  name: "messages",
  components: { MessageItem },
  setup() {
    const hub = inject("HUB");
    const messages = computed(() => {
      if (hub.data && hub.data.messages) {
        return hub.data.messages;
      }
      return [];
    });

    return { messages };
  }
};
</script>

In lib package.json I have set @vue/composition-api as a peer dependency.

In my main project (not library), I'm registering Composition API and using provide like this:

import Vue from "vue";
import VueCompositionApi from "@vue/composition-api";
Vue.use(VueCompositionApi);
import App from "./App.vue";

import { hub } from "../lib/hub";
import { provide } from "@vue/composition-api";

Vue.config.productionTip = false;

new Vue({
  setup() {
    provide("HUB", hub.data);
  },
  render: h => h(App)
}).$mount("#app");

But I'm getting Error in data(): "Error: [vue-composition-api] "inject" get called outside of "setup()""

Is it ok I'm calling Vue.use(VueCompositionApi); in the main project and anywhere in the library?

BTW: should I use Vue and Vuex as a peer dependencies as well in the library?

posva commented 4 years ago

You only need to call the Vue.use once. Are you linking one of the libraries using @vue/composition-api? Because it looks like that's the problem like at https://github.com/vuejs/composition-api/issues/228#issuecomment-574084313

JiProchazka commented 4 years ago

I'm not linking library from disc, but have it installed from npm - if it makes difference. I have my main project where I'm using Composition API and linking one components library (my own), which is using also Composition API (in this library I have Composition API as a peer dependedncy), but I'm not calling Vue.use(VueCompositionApi); anywhere in the library - only in the main project. No other libs using Composition API are used.

In other words - basically I have a project working I'm trying to extract the components to it's own lib. Those components are using inject, and this lib has a Composition API as a peer dependency. And I'm calling Vue.use(VueCompositionApi); in the main.js of the main project.

posva commented 4 years ago

I'm using Composition API and linking one components library

That's what I meant. Take a look at the issue above, it's the same problem, there are a few workarounds 🙂

JiProchazka commented 4 years ago

Well, I know #228 of course. I have read it through, but still didn't get it working. I have prepared a simpliest demo possible - a lib with one Test.vue component using inject and a main project trying to use it. Lib project has composition api as a dev and peer dependency.

Still getting the same Error in data(): "Error: [vue-composition-api] "inject" get called outside of "setup()""