Latest Update
Attention all Vue.js developers! Please be advised that with the recent release of vue-loader 15.x, the previous method outlined in this guide will no longer be applicable. For an updated approach, kindly refer to this resource:
If you're looking to create and publish your very own Vue.js library/component from the ground up, then you've come to the right place.
This comprehensive guide will walk you through each step and command necessary to successfully develop and deploy your custom Vue.js component on NPM.
Once published, like most libraries, installation can be done using a simple command:
npm install --save your-component
Followed by importing the component into your application:
import something from 'your-component'
To kickstart the process of creating our first component, start by creating a new folder named vuejs-hello-app
(or any other preferred name) and execute the following within it:
npm init
Proceed through the interactive setup by pressing 'Enter' until completion. This will generate a file named package.json
within the folder containing the provided code snippet.
(Note: The description and version have been altered for demonstration purposes)
{
"name": "vuejs-hello-app",
"version": "0.1.0",
"description": "vuejs library demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Following this, we'll proceed to install the required dependencies for our library.
These dependencies are classified into two categories: dependency
and devDependency
dependency
:
This pertains to external libraries essential for the operation of our component. When users install your component, npm ensures the existence or installation of these dependencies first. Given that we are developing a Vue component, it is crucial to have Vue as a requirement. Hence, install it using:
npm install --save vue
devDependency
:
Comprising libraries utilized solely for development purposes. These facilitate building and/or transpiling tasks.
The installation process for dev dependencies involves adding the suffix -dev
to --save
Let's now install the basic dev dependencies necessary for our component:
npm install --save-dev babel-core
npm install --save-dev babel-loader
npm install --save-dev babel-preset-env
npm install --save-dev cross-env
npm install --save-dev css-loader
npm install --save-dev file-loader
npm install --save-dev node-sass
npm install --save-dev sass-loader
npm install --save-dev vue-loader
npm install --save-dev vue-template-compiler
npm install --save-dev webpack
npm install --save-dev webpack-dev-server
With the libraries successfully installed, the package.json
file will be updated accordingly.
{
"name": "vuejs-hello-app",
"version": "0.1.0",
"description": "vuejs library demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"cross-env": "^5.1.1",
"css-loader": "^0.28.7",
"file-loader": "^1.1.5",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.6",
"vue-loader": "^13.5.0",
"vue-template-compiler": "^2.5.9",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.7"
},
"dependencies": {
"vue": "^2.5.9"
}
}
(note: To build our library with webpack, I included "build": "webpack -p"
)
As of now, the groundwork has been laid out, and preparations have been made. By creating a dist
folder within the root directory and configuring a webpack.config.js
file, progress is moving forward.
All files established are intended for configuration and organizational tasks. For end-users interacting with your app, two crucial files must reside within the src/
directory.
Include a main.js
and VuejsHelloApp.vue
at the following locations:
./src/main.js
and
./src/components/VuejsHelloApp.vue
A sample project structure might resemble:
dist
node_modules
src
main.js
components
VuejsHelloApp.vue
.babelrc
.eslintignore
.gitignore
.npmignore
.travis.yml
CONTRIBUTING
LICENSE
package.json
README.md
webpack.config.js
Evaluating the listed files, here's what each serves in its respective role:
/dist
houses a transpiled, minified, non-ES6 rendition of your code
node_modules
Self-explanatory, nothing noteworthy here
src/
marks the root directory of your library
.babelrc
stores your Babel options, where certain presets may need alteration
{
"presets": [
[
"env",
{
"modules": false
}
]
]
}
.eslintignore
Commands ESLint to ignore linting for specific files
build/*.js
.gitignore
Excludes designated files from Git tracking
.npmignore
Similar to .gitignore but applies to NPM repository
.travis.yml
Facilitates continuous integration setups via Travis CI
CONTRIBUTING
Optional contributor guidelines document
LICENSE
Includes pertinent licensing information
package.json
Vital project metadata file
README.md
Houses descriptive README content
webpack.config.js
Crucial configuration file for achieving browser compatibility
Given the context of your app, below is a simplified illustration of how the configuration might appear:
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
module: {
rules: [
{ test: /\.js$/, use: 'babel-loader' },
{ test: /\.vue$/, use: 'vue-loader' }
]
},
context: __dirname,
output: {
path: path.resolve(__dirname, './dist'),
filename: 'vuejs-hello-app.js'
}
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
Focusing especially on the directives entry
and output
, you can delve deeper into webpack documentation for further customization details.
We're almost set to conclude preparations, awaiting only the actual implementation. Within
/src/components/VuejsHelloApp.vue
, insert a simplistic app segment featuring a button that shifts positions upon hovering.
<template>
<div>
<button @mouseover='move($event)'> I'm alive </button>
</div>
</template>
<script>
export default {
data () {
return {}
},
methods: {
move (event) {
let pos = event.target.style.float;
if(pos === 'left'){
event.target.style.float = 'right'
}else{
event.target.style.float = 'left'
}
}
}
}
</script>
<style scoped>
</style>
Lastly, navigate to ./src/main.js
and export your app as follows:
import VuejsHelloApp from './components/VuejsHelloApp.vue'
export default VuejsHelloApp
In your package.json
file, update "main: "index.js",
to instead bear "main": "src/main.js",
To finalize, initiate the subsequent commands for building and publishing your app:
npm run build
git add .
git commit -m "initial commit"
git push -u origin master
npm login
npm publish
How to Import and Utilize the Library
If everything unfolds seamlessly, proceed to install your app as showcased below:
npm install --save vuejs-hello-app
Then incorporate it into your Vue structure similarly to this:
<template>
<div>
<VuejsHelloApp> </VuejsHelloApp>
</div>
</template>
<script>
import VuejsHelloApp from 'vuejs-hello-app'
export default {
name: 'HelloWorld',
components: { VuejsHelloApp }
}
</script>
A live working example developed throughout this tutorial can be accessed on GitHub at https://github.com/samayo/vuejs-hello-app. It provides additional clarity on the technicalities implemented within the code.