Hi Everyone,
It's me again π
So Fast forward 4 months from my first post
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 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
Open your favourite terminal and change directory into your projects directory
cd c:/projects
Now create a new project using vue cli
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...
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
import component from './SimpleAlert.vue'
Then, we're gonna register it into the vue instance if it exists
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
export default component
So the file entry.js finally looks like this after linting and formatting
// ./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.
// ./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
// 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
{
"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 π
Top comments (8)
Nicely written article, easy to follow. But, npm run build fails with ReferenceError: external is not defined. Does anyone know what could this be and if there is a simple solution for this? My money is on the broken rollup.config.js file.
Hi I also get the same error, is there any solution?
did you find anything about the "external is not defined".
Hi, I m trying to compile my plugin unsuccessfully
Hey, maybe I can help.
Can you provide some more context?
that is my package.json
when I run the command to build there are no errors, but on top of my dist/index.js, I got these lines
nice article straight forward, can you please help on how can i add Vuex on my package?
Great article