DEV Community

Cover image for How I am create my first beautiful React Component as an NPM Package ๐Ÿ˜Ž with ๐Ÿ’–
Jackson Kasi
Jackson Kasi Subscriber

Posted on • Edited on

How I am create my first beautiful React Component as an NPM Package ๐Ÿ˜Ž with ๐Ÿ’–

What is NPM?

npm is a package manager for Node.js. Also an online database of more than one million JavaScript development tools(packages).

To download a package from npm, all you have to do is run command:

 npm install [ package name ]
Enter fullscreen mode Exit fullscreen mode

And the package will automatically be downloaded to the node_modules folder in your project.
You can use it right away. It saves so much time for developers.
As an open source library, you can also share your cool stuff by publishing it to npm.

Letโ€™s build up a simple and useful package, then publish it to npm.


Guys try my npm package first :)

multi-avatars
or

npm i multi-avatars
Enter fullscreen mode Exit fullscreen mode

First Create project

First we have to download npm. We can get it by installing Node.js. Letโ€™s download Node.js from its official site.

Node JS

Open your terminal and run :

npm -v

If version information shows up, it means you successfully installed it.

Then create a new folder, and initialize this folder.

multiavatars is my npm package name.

mkdir multiavatars
cd multiavatars
npm init
Enter fullscreen mode Exit fullscreen mode

Create a src folder and a lib folder under the root directory. We will place our react component under .src folder. And js file after compile will appear under .lib folder.

folder stucture


Edit package.json

After running npm init -y there will be a package.json file generated automatically. Usually this is enough for us to develop. But in order to publish this project to npm, there are some details to take care of. Just edit your package.json file as below :

{

"name": "multi-avatars",

"version": "1.0.0",

"main": "./lib/Avatars.js",

"scripts": {

"build": "webpack"

},

"description": "show the random avatars on your website",

"peerDependencies": {

"prop-types": "^15.6.0",

"react": "^16.0.0",

"react-dom": "^16.0.0"

},

"dependencies": {

"avataaars": "^2.0.0"

},

"author": "jackson kasi",

"keywords": [

"react",

"react js",

"avatar",

"multi avatars",

"avatars",

"animation",

"ui",

"node",

"component",

"avataaars",

"face",

],

"license": "MIT",

"devDependencies": {

"babel-core": "^6.21.0",

"babel-loader": "^7.1.4",

"babel-preset-env": "^1.6.1",

"babel-preset-react": "^6.16.0",

"babel-preset-stage-0": "^6.24.1",

"css-loader": "^3.5.1",

"path": "^0.12.7",

"prop-types": "^15.6.0",

"react": "^16.14.0",

"react-dom": "^16.0.0",

"style-loader": "^1.1.3",

"webpack": "^4.5.0",

"webpack-cli": "^4.9.2"

},

"repository": {

"type": "git",

"url": "git+https://github.com/jacksonkasi0/multi-avatars.git"

},

"homepage": "https://github.com/jacksonkasi0/multi-avatars#readme",

"bugs": {

"url": "https://github.com/jacksonkasi0/multi-avatars/issues"

 }
}
Enter fullscreen mode Exit fullscreen mode

You notice here ๐Ÿ‘€

I needed the npm package for dependencies (avataaars) in this, so I have included it here.
As well as adding only what you need to dependencies. (ex: mui, axios or any other )

Also I wrote "main": "./lib/Avatars.js" in the package json.
But when you look at it there is no such thing as a file (./lib/Avatars.js).
It only comes when it is compiled.

  • name : The name of this package. Package name canโ€™t be reused. So before you name the project, itโ€™s better to check on npm whether a same name package exists or not.
  • version : Packageโ€™s version. Remember to update the version every time you update this package.
  • description : It will become the subtitle of this package on the npm official site. The more accurate it is the bigger chance for people to find this package.
  • main : It is the entry point of this package. Make sure the path is correct.
  • repository : It is where the source code of this package placed. For example, if you place code on GitHub. Just put the URL of GitHub repository here.
  • keywords : Will be tags of this package on npm official site. Meant to help people find packages easier.
  • bugs : Should be a place users can report bugs. Usually, it would be the same place as the repository.
  • scripts : Scripts we used to run this project. For example, we use webpack to bundle this project, so we create a script โ€œbuildโ€ to run webpack.

After we finished editing package.json, letโ€™s install tools and libraries we are going to use. Like React, Webpack, Babel, and avataaars.

npm install webpack webpack-cli   
npm install react   
npm install babel-loader @babel/core     
npm install @babel/preset-env @babel/preset-react 
npm install @babel/preset-stage-0
npm install avataaars
Enter fullscreen mode Exit fullscreen mode

Create webpack.config.js

Next we are going to set up webpack config file. Create a webpack.config.js file. In this file, we deliver some important information to webpack such as entry of project and output form.

const  path = require('path');



module.exports = {

mode:  'production',

entry:  './src/Avatars.js',

output: {

path:  path.resolve('lib'),

filename:  'Avatars.js',

libraryTarget:  'commonjs2',

},

module: {

rules: [

{

test: /\.js?$/,

exclude: /(node_modules)/,

use:  'babel-loader',

},

{

test: /\.css$/,

use: [

'style-loader',

'css-loader'

]

}

],

},

resolve: {

alias: {

'react':  path.resolve(__dirname, './node_modules/react'),

'react-dom':  path.resolve(__dirname, './node_modules/react-dom'),

}

},

externals: {

// Don't bundle react or react-dom

react: {

commonjs:  "react",

commonjs2:  "react",

amd:  "React",

root:  "React"

},

"react-dom": {

commonjs:  "react-dom",

commonjs2:  "react-dom",

amd:  "ReactDOM",

root:  "ReactDOM"

}

}

};

Enter fullscreen mode Exit fullscreen mode
  • entry : Path of our React component file.
  • output : Itโ€™s an object. Path point out the place where javascript file will be after compile. In our project itโ€™s lib folder. And filename is its name.
  • rules : Itโ€™s an object. We set up rules here. Rules for using which tools to compile while facing different kind of files. In our project, we use babel-loader to compile files end with .js, use css-loader to compile files end with .css.
  • resolve : When people import our package to their own project, there will probably some packages used both side but in different versions. It happen to react and react-dom all the time. We should put them here to prevent the potential conflict.

These are some basic settings that can handle most of situations.


Create .babelrc

Using JSX with react is awesome. But the browser canโ€™t read JSX. This is why we use babel to compile JSX into JavaScript. Just place packages we are going to use in presets.

{

"presets": ["react", "env", "stage-0"]

}
Enter fullscreen mode Exit fullscreen mode

.npmignore, .gitignore and Readme.md

.npmignore is to filter out files we donโ€™t have to publish to npm. .gitignore is to filter out files we donโ€™t have to push to GitHub.

Readme.md is for introducing your package. It shows up both on npm and GitHub repository. Itโ€™s better to provide as much details you can here. Because most of people tend to download packages with complete information. If you create a super killer package but without Readme.md, no one going to use it.


Then look at the structure of your files:

structure of your files


Create react package

After we setting up everything, letโ€™s do the code. I am going to create a simple but useful package which is a scroll to top button. Itโ€™s going to be a button, click it and you will back to the top of web page no matter where you at.

You can create whatever you want here. It doesnโ€™t matter because our point is how to publish it.

So letโ€™s skip how to create this react component. Just check the code if you are curious.


Try it on localhost

After we done the react component, just run :

npm run build
Enter fullscreen mode Exit fullscreen mode

then look,
your package created

Ideally, we will receive a success message. Before we publish it, we should test is this package working or not. Run :

npm pack

package

Then a .tgz file will generated. Letโ€™s install it to another random react project and import it to a component.
Use the local path of this package to install it, like below :

npm install /Users/Jackson Kasi/your-path/xxxxxxxxxxx.tgz

enter image description here

some time you can see error like this,

error

so you can just use --force

npm install /Users/Jackson Kasi/your-path/xxxxxxxxxxx.tgz --force

then my package is installed in locally...
see

Ideally, this package is working! ๐Ÿค—

Publish to npm

Finding a name:
Sometimes you might try to publish a package and find that the name is either already taken or the name is almost identical to another package so its better to first search and see if the package name is already taken. So type the following command in the command line.

npm search [package name]
Enter fullscreen mode Exit fullscreen mode

enter image description here
if you find that nobody is using it them you can use the name.

Go to the npm website and create an account using your mail ID and password.
Make sure that you are in the current directory that is the components directory and type the following commands:

npm login 
# Use your username and password what you have created in the npm website
Enter fullscreen mode Exit fullscreen mode

enter image description here

After logged in successfully, we can publish it, run :

# Then run this command
npm publish
Enter fullscreen mode Exit fullscreen mode

We will receive a success message. Then wait for couple minutes, go to npm site and search for our package. When we see it on npm site, weโ€™re done!

Remember to check the version every time before publishing. If you forget to update the version, publish will fail.

In the end, letโ€™s import this package and see how it looks like :

enter image description here

This is it! Hope you enjoy this and publish some cool stuff on npm.

Also please post your comments ๐Ÿ˜๐Ÿ˜๐Ÿ˜

by - jackosn kasi

Top comments (0)