This guide documents the steps to package, publish, and version a Vue component using vue-cli 3
on NPM and unpkg (to use directly in the browser).
Note: this guide was written after publishing my first (simple) component. It may not suit more complicated cases, or you may find a better guide. I found other guides skimping on versioning & Github integration or not making full use vue-cli. I intend to expand on this guide in the future to cater for more advanced cases.
Step 0 — Your Vue project
This step deals with the basic project setup. Feel free to skip ahead for packaging-specific steps.
Create an empty repository on Github.com and install the Vue CLI and initiate your project.
npm install -g @vue/cli
vue create my-project
# use default options
cd my-project
git remote add origin https://github.com/username/my-project.git
git push -u origin master
npm run serve
Go about creating your component as you otherwise would. You may want to add a LICENSE file and we will assume the following file structure.
package.json
readme.md
LICENSE
src/
App.vue
MyComponent.vue
main.js
dist/
.gitignore
Step 1 — Configure the package.json file
Publishing a library is closer to bookkeeping than to rocket science. It pays to properly set up and document your library. What’s the point if others cannot find it or cannot make sense of it? Or if you don’t fix bugs because the overhead of updating the package is too great?
Edit your package.json
to resemble:
{
"name": "my-component",
"version": "0.1.0",
"description": "Describes my component",
"author": {
"name": "My Name",
"email": "optional@email.com"
},
"repository": "https://github.com/username/project",
"bugs": "https://github.com/username/vproject/issues",
"keywords": ["words", "go", "here"],
"license": "MIT",
"private": false,
"files": ["dist"],
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"build:npm": "vue-cli-service build --target lib --name myComponent src/MyComponent.vue",
},
"main": "dist/myComponent.umd.js",
"unpkg": "dist/myComponent.umd.min.js",...}
A quick run through the properties:
- name — Name for the package that will appear in NPM.
- version — Semantic version. We will get to that in step 3.
- description, author, repository, bugs, keywords, license — Additional info for use in NPM.
- private —
true
orfalse
. NPM will try to publish publicly, and that will fail if you have the package set to private. - files — Determines what files and folders will be published by NPM. If this option is not set, it will look at the
.gitignore
(or.npmignore
, but we have none) file for inspiration. That will cause your source code and not the built bundles to be published. Exactly the opposite of what we want. - scripts.build:npm — This is the build script for the package, powered by vue-cli-service:
--target lib
sets the build target to a library and--name myComponent
sets the basic filename.
No harm in trying, so let’s run:
npm run build:npm # Building for production as library (commonjs,umd,umd-min)...
The dist
folder should now have the following files inside:
myComponent.common.js
myComponent.common.js.map
myComponent.umd.js
myComponent.umd.js.map
myComponent.umd.min.js
myComponent.umd.min.js.map
You could publish this to NPM and move on to the next challenge in your life. We need a few more steps to do this properly though.
References for step 1:
Step 2 — Add a proper readme
A proper readme
is very important. Research shows that 65% of potential users will base their view of a library on the readme and 90% will leave frustrated if they cannot find instructions on how to install and use it [I completely made this up].
The readme will be published with your package on npmjs.com and your Github page and should, for a library, answer at least the following questions:
- Can you tell me what problem it solves in two sentences?
- How do I install it?
- How do I use / interact with it?
- Which license is applied?
And optionally:
- Can you show me examples of the thing at work?
- How does it work under the hood?
- Project status: builds / tests?
- How can I contribute?
- Which technologies have been used?
Do not get too fancy with lots of content or illustrations. There is value in having a “scannable” document and anything beyond a brief readme is probably better served in actual documentation.
Step 3 — Versioning
This is one I kept postponing for my own projects, but turn out to be really convenient and easy. NPM even automatically integrates with Git tags, so you do not have to duplicate efforts or even run the risk of your version numbers getting out of sync.
# Make sure the working directory is clean
git add -A
git commit -m "Changes"# Increment semantic version with npm
npm version patch -m "Bump the version number"
The npm version
command stealthily performs two actions:
- Bump
version
in package.json according to the rules of semantic versioning. - Create an annotated tag in Git.
Use the following command to confirm that the tag was created and to push all commits, including the annotated tags to your repository.
git tag
# v0.1.1
git push --follow-tags
Step 4 — Publish and use
To publish on npmjs.com, you need a free npm account. Create it from the command line:
npm adduser
Login and verify your email to get set up
npm login
Publishing is now easy:
npm run build:npm
npm publish
It should be there (almost instantly), for the whole world to use: npmjs.com/package/<my-component>
The search on npmjs.com should also pick it up immediately.
What’s more, it is available on a CDN so that it can be included in websites. This should be the basic url: unpkg.com/<my-component>
. That will redirect you to a more specific location complete with version number. The wildcard latest
will give you the most recent version.
Now all you have to do is either:
npm install my-component
or in the browser:
<script src=”https://unpkg.com/my-component@latest/dist/myComponent.umd.min.js"></script>
Remark: please no source code in libraries
I have seen libraries that send all the source code, demo files, etc to NPM. Please don’t do that, you are giving NPM a bad name.
- Libraries are for compiled code that is optimized for production
- Version control systems (such as Github) are for the underlying source code.
Things will go right for you if you have configured “files”: [“dist”]
in package.json
. Things go wrong with a poorly configured .npmignore
or with .gitignore
.
But having access to the source code is a good thing, right? Yes it is, but there are are better ways, such as setting your "repository"
in package.json
. The link will be there on npmjs.com and you can see it on your own system:
npm show vue repository
Change vue
to any other package you want to inspect. Provided they did their bookkeeping, you will find all the repositories.
Remark: things that bit me in the browser
Property names with capitals
Self closing tags