How to publish a Vue plugin correctly?

I wrote a very simple plugin for Voca.js by Typescript. You can find the source code here.

index.ts

import VueVoca from './vue-voca';
export {
    VueVoca
};

vue-voca.ts

import vue from 'vue';

export default {
  install(Vue: typeof vue) {
    Vue.prototype.$voca = require('voca');
  }
};

vue.d.ts

import Vue from 'vue';
import vc from 'voca';
declare module 'vue/types/vue' {
  export interface Vue {
    $voca: vc.VocaStatic;
  }
}

To create npm package I use this command

vue-cli-service build --name vue-voca --entry ./src/index.ts --target lib

and npm pack.

package.json

{
  "name": "vue-voca",
  "version": "1.0.0",
  "private": false,
  "scripts": {
    "serve": "vue-cli-service serve ./example/main.ts --open",
    "build": "vue-cli-service build --name vue-voca --entry ./src/index.ts --target lib",
    "prepublishOnly": "npm run build"
  },
  "dependencies": {
    "@types/voca": "^1.4.0",
    "voca": "^1.4.0",
    "vue": "^2.6.7"
  },
  "devDependencies": {
    "@vue/cli-plugin-typescript": "^3.4.1",
    "@vue/cli-service": "^3.4.1",
    "fibers": "^3.1.1",
    "sass": "^1.17.2",
    "sass-loader": "^7.1.0",
    "typescript": "^3.3.3333",
    "vue-cli-plugin-component": "^1.10.5",
    "vue-template-compiler": "^2.6.7"
  },
  "files": [
    "dist/*.css",
    "dist/*.map",
    "dist/*.js",
    "src/*"
  ],
  "keywords": [
    "vue",
    "component"
  ],
  "types": "src/vue.d.ts",
  "typings": "src/vue.d.ts",
  "main": "dist/vue-services.umd.js",
  "module": "dist/vue-services.common.js"
}

But after using the npm package I have a problem. VueVoca does not recognize :frowning:

webpack-internal:///./node_modules/vue/dist/vue.runtime.esm.js:620 [Vue warn]: Error in render: "TypeError: Cannot read property 'swapCase' of undefined"

found in

---> <HelloWorld> at src/components/HelloWorld.vue
       <App> at src/App.vue
         <Root>

Can anyone help me to write a correct plugin with a correct npm package?

I write a few NPM plugins. Once you get the hang of it they’re OK.

OK, looks like the problem here is a double-export of an object.

In index, try this:

import VueVoca from './vue-voca';
export VueVoca;

You also do not need to have an index.ts file if you don’t want to, you can just set the file directly from teh build script:

vue-cli-service build --name vue-voca --entry ./src/vue-voca.ts --target lib

Also, in your example, you should really be importing the compiled version of the plugin (as not everyone will be using TypeScript) from dist not src.

FYI, you can test packages locally using npm link. I generally do this before publishing to the repository so I can make sure it works, outside the project, before publishing.

Try that and see how you go.

FWIW, it seems like you can just set up Voca (as a Vue plugin) in a Vue project (as per your main file) with the following code:

Vue.prototype.$voca = require('voca');

Why write a plugin and go to all the hassle of typescript, compiling, testing, publishing, etc?

My problem is after publishing I created a new project and yarn add localpackage.
Unfortunately, your guidance does not work for me can you make PR for that?

As you know, Vue 3 will support Typescript fully so I want to have services with full Typescript intellisense. Your tip is right but enough for JS support for Typescript you need some efforts.

You’re saying that the purpose of this plugin is to incorporate Voca in such a way that intellisense will be able to pick up on the integration and show Voca suggestions in the class / template?

Well then the problem is not about publishing a libraray correctly in general, but about creating type declarations for the lib and publish them with it.

@davestewart
Yes

@LinusBorg
Maybe you right. Can you help me on this? It would be great if you make PR on my source if you have time. I dont know how to fix it.

I am a newbie in Vue and I want to work with Typescript beside it. This is my first attempt to get familiar with Vue.js plugin system. I found some tuts and followed them


https://www.mistergoodcat.com/post/vuejs-plugins-with-typescript

but still, have a problem.

Anyway, I want to achieve two things:

  1. Write fully Typescript plugin for Vue.js. (Pure JS is not my option)
  2. Provide an easy way for a user to use Voca.js with full intellisense.

I really like Vue, Community, and their ecosystems but most of Vue samples and tutorials are about pure js, not Typescript. I hope Vue 3 help us to go with TS more.

Finally, I fixed it.

Can you tell more how you fixed it?

Can you provide a sample how you solved it - would be cool. I think a lot of people are struggling with VUE-Components in TS (publishing them to NPM)