Let's assume that you created a React component AwesomeComponent.js
while working in one of your projects:
jsximport React, { useState } from 'react'; const AwesomeComponent = () => { const [name, setName] = useState('The world'); return ( <div>{name} needs this awesome component.</div> ); } export default AwesomeComponent;
Now you want to publish in npm.
package.json
Create a new and empty folder and rename it like your component. This will be the component's main directory.
Open the Terminal, go to the main directory and run:
shellnpm init -y
You have created a package.json
describing the component:
jsx{ "name": "AwesomeComponent", "version": "1.0.0", "description": "The best component ever", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": { "name": "Erik Martín Jordán", "url": "https://erikmartinjordan.com/" }, "license": "MIT" }
You'll need to rename the fields name
, author
and description
.
At this point you can create a src
folder to include the source code of your component.
The main directory will have a tree like:
shell|____package-lock.json |____package.json |____src | |____AwesomeComponent.js
The next step is to install Webpack:
shellnpm install --save-dev webpack webpack-dev-server webpack-cli
Your awesome component has only one script, but in most cases you will have several additional files. Webpack will pack all the scripts in one single file.
After installing Webpack, you need to create a webpack.config.js
. Go to the main directory and run:
shelltouch webpack.config.js
The webpack.config.js
should have this config:
jsxmodule.exports = { entry: [ './src/AwesomeComponent.js' ], module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: ['babel-loader'] }, { test: /(\.css$)/, loaders: ['style-loader', 'css-loader'] } ] }, externals: { react: { root: 'React', commonjs2: 'react', commonjs: 'react', amd: 'react' }, 'react-dom': { root: 'ReactDOM', commonjs2: 'react-dom', commonjs: 'react-dom', amd: 'react-dom' } }, resolve: { extensions: ['*', '.js', '.jsx'] }, output: { path: __dirname + '/build', publicPath: '/', filename: 'index.js', libraryTarget: 'commonjs2' }, devServer: { contentBase: './build' } };
Modify only the entry
field.
Notice that the output
field indicates that the output will be generated in a folder build
(you don't need to create it manually) and the filename will be index.js
.
Babel translates ES6 and modern syntax into compatible JavaScript between browsers.
shellnpm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader style-loader css-loader
Create .babelrc
:
shelltouch .babelrc
Add this configuration to .babelrc
:
shell{ "presets": [ "@babel/preset-env", "@babel/preset-react" ] }
After all these steps, package.json
will look like this:
jsx{ "name": "AwesomeComponent", "version": "1.0.0", "description": "The best component ever", "main": "./build/index.js", "author": { "name": "Erik Martín Jordán", "url": "https://erikmartinjordan.com/" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack" }, "keywords": [], "license": "MIT", "devDependencies": { "@babel/core": "^7.11.0", "@babel/preset-env": "^7.11.0", "@babel/preset-react": "^7.10.4", "babel-loader": "^8.1.0", "css-loader": "^4.2.0", "style-loader": "^1.2.1", "webpack": "^4.44.1", "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.0" }, "peerDependencies": { "react": "^16.13.1" } }
Important: Notice that you should add React as a peer dependency, because otherwise, you'll have two React modules after downloading the package from npm and this will generate an error.
The file tree will look like:
shell|____package-lock.json |____package.json |____webpack.config.js |____.babelrc |____src | |____AwesomeComponent.js
At this point you can build the component:
shellnpm run build
A index.js
will be generated and it's ready to publish in npm.
Terminal|____package-lock.json |____package.json |____webpack.config.js |____.babelrc |____src | |____AwesomeComponent.js |____build | |____index.js
From the root, open the Terminal and run:
shellnpm publish
Ready!
It's recommended to create a new React project to test the component locally before to publish the component:
Terminalnpx create-react-app Test
terminal# From the component folder cd AwesomeComponent npm link # From the new React project folder cd Test npm link AwesomeComponent
terminalnpm run start
Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.