Publish Your First NPM Package (Vue) - PART 1
Tags: vue, npm, vscode
Published: 2019-06-09 11:23:42

Hi Everyone,

It's me again 😊

So Fast forward 4 months from my first [post](https://dev.to/amroessam/vgauge---created-my-first-npm-package-first-post-446o)

I've realised my article wasn't the most helpful🤦🏽‍♂️, as I didn't get into details on how I created my first NPM package.

In this post, I'm planning on doing so😁, I'll also try to cover how to get intelliSense working for a vue component in vscode.

For simplicity's sake, we're making a very minimal reusable alert component
We'll be using [rollup](https://rollupjs.org/guide/en/) to build 

Let's get started 😎🙌

### 1. Creating the component


We'll be using vue cli in this tutorial, so if you're unfamiliar with it, a  great place to start would be vue's cli [documentation](https://cli.vuejs.org/guide/)

Open your favourite terminal and change directory into your projects directory

```shell
cd c:/projects
```
Now create a new project using vue cli

```shell
vue create simplealertcomponent
```

Select the default preset, wait till vue-cli creates all the necessary boilerplate files for you.

Change directory to the new folder that's made and launch your editor, I'm using vscode so...

```shell
cd simplealertcomponent && code .
```

This is the file structure you should have

```
.
├───public
│     favicon.ico
│     index.html
└───src
    │ App.vue
    │ main.js
    ├───assets
    │ logo.png
    └───components
      HelloWorld.vue
```
Delete everything inside the src folder so it's empty, also delete the public folder because we won't be needing it.

Now create entry.js file in the src folder, this will be the entry point to our application.

first we import our component, we'll be creating it later

```js
import component from './SimpleAlert.vue'
```

Then, we're gonna register it into the vue instance if it exists

```js
function install(Vue) {
  if (install.installed) return
  install.installed = true
  Vue.component('SimpleAlert', component)
}

const plugin = {
  install
}

let GlobalVue = null
if (typeof window !== 'undefined') {
  GlobalVue = window.Vue
} else if (typeof global !== 'undefined') {
  GlobalVue = global.vue
}

if (GlobalVue) {
  GlobalVue.use(plugin)
}

component.install = install
```


Then export the component as follows

```js
export default component
```

So the file entry.js finally looks like this after linting and formatting

```js
// ./src/entry.js

import component from "./SimpleAlert.vue";

function install(Vue) {
  if (install.installed) return;
  install.installed = true;
  Vue.component("SimpleAlert", component);
}

const plugin = {
  install
};

let GlobalVue = null;
if (typeof window !== "undefined") {
  GlobalVue = window.Vue;
} else if (typeof global !== "undefined") {
  GlobalVue = global.vue;
}

if (GlobalVue) {
  GlobalVue.use(plugin);
}

component.install = install;

export default component;
```

Now, let's create the vue component.
Create a new file called SimpleAlert.vue

And add the following code inside it.

```js
// ./src/SimpleAlert.vue

<script>
import { setTimeout } from "timers";
export default {
  name: "SimpleAlert",
  props: {
    message: {
      type: String,
      default: "Hello Dev.to"
    },
    timeout: {
      type: Number,
      default: 0
    }
  },
  mounted() {
    setTimeout(() => {
      alert(this.message);
    }, this.timeout);
  }
};
</script>
```

Notice how I didn't use a template or a script tag, it's because this component doesn't show any html, it just alerts.

Now create a new folder called build, it should be next to the src folder in the root directory, and add rollup.config.js inside it

So the project structure is as follows

```
.
│
├───build
│     rollup.config.js
└───src
      entry.js
      SimpleAlert.vue
```

In rollup.config.js paste the following code

```js
// rollup.config.js

import vue from "rollup-plugin-vue";
import buble from "rollup-plugin-buble";
import commonjs from "rollup-plugin-commonjs";
import replace from "rollup-plugin-replace";
import uglify from "rollup-plugin-uglify-es";
import minimist from "minimist";

const argv = minimist(process.argv.slice(2));

const config = {
  input: "src/entry.js",
  output: {
    name: "SimpleAlert",
    exports: "named"
  },
  plugins: [
    external,
    replace({
      "process.env.NODE_ENV": JSON.stringify("production")
    }),
    commonjs(),
    vue({
      css: true,
      compileTemplate: true,
      template: {
        isProduction: true
      }
    }),
    buble()
  ]
};

// Only minify browser (iife) version
if (argv.format === "iife") {
  config.plugins.push(uglify());
}

export default config;

```

Now that we have everything in place, let's try to build it, we'll need to edit our package.json to include the build command.

Open your package.json and replace everything you have in there with the following

```json
{
  "name": "simplealertcomponent",
  "version": "0.1.0",
  "main": "dist/simplealertcomponent.umd.js",
  "module": "dist/simplealertcomponent.esm.js",
  "unpkg": "dist/simplealertcomponent.min.js",
  "browser": {
    "./sfc": "src/simplealertcomponent.vue"
  },
  "files": [
    "dist/*",
    "src/*",
    "attributes.json",
    "tags.json"
  ],
  "vetur": {
    "tags": "tags.json",
    "attributes": "attributes.json"
  },
  "scripts": {
    "build": "npm run build:unpkg & npm run build:es & npm run build:umd",
    "build:umd": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format umd --file dist/simplealertcomponent.umd.js",
    "build:es": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format es --file dist/simplealertcomponent.esm.js",
    "build:unpkg": "cross-env NODE_ENV=production rollup --config build/rollup.config.js --format iife --file dist/simplealertcomponent.min.js"
  },
  "devDependencies": {
    "cross-env": "^5.2.0",
    "minimist": "^1.2.0",
    "rollup": "^1.14.4",
    "rollup-plugin-buble": "^0.19.6",
    "rollup-plugin-commonjs": "^9.3.4",
    "rollup-plugin-replace": "^2.2.0",
    "rollup-plugin-uglify-es": "0.0.1",
    "rollup-plugin-vue": "^4.7.2",
    "vue": "^2.6.10",
    "vue-template-compiler": "^2.6.10"
  }
}
```

Now open a terminal and type `npm i` to install all the dev dependencies.
Once that's done, type `npm run build`, that will create a new folder called `dist` with all the files we need to push to NPM in order for other users to consume our component.


This is the end of part 1 🎉🎉, the rest is coming soon 😊