Creating a React library using Rollup & Gulp

Gilad lev-ari
3 min readNov 13, 2018

Before I’ll start with how to create your own React library, I’d like to say I hate writing my own bundler config, task manager etc. I don’t mind using Create React App or any other well written boiler plate.

That been said, Let start with writing our own Rollup and gulp configs.

I guess that you are familiar with yarn / npm.

Init the project

Start by creating a new folder to hold our library. Inside that folder, init your project by using yarn int

Adding our devDependencies

Babel is a JavaScript compiler mainly used to convert ECMAScript 2015+ code into a backwards compatible version of Javascript. In our case it is also used to convert React’s JSX components to JavaScript

yarn add -D "@babel/core" "@babel/plugin-external-helpers" "@babel/preset-env" "@babel/preset-react" "@svgr/rollup" "babel-eslint"

ESLint is a linter tool for JavaScript

yarn add -D eslint eslint-plugin-react

Gulp is a task manager automation tool

yarn add -D gulp gulp-shell gulp-watch

Rollup is a module bundler and compiler for JavaScript

yarn add -D rollup rollup-plugin-babel rollup-plugin-commonjs rollup-plugin-node-resolve rollup-plugin-postcss rollup-plugin-ur

I save the best ones for last, our React dependencies

yarn add -D prop-types react react-dom

Now copy and paste those three packages, to your peerDependencies. We’d like to keep them extended from our bundle / compiled version.

Creating our ESLint config

Create a file name “.eslint” and add the following json.

{
"parser": "babel-eslint",
"plugins": ["react"],
"extends": ["eslint:recommended", "plugin:react/recommended"]
}

Here we set our linter to use babel as its parser to support extended JavaScript options as well as React

Create a file name “.eslintignore” and add the following lines.

gulpfile.js
node_modules
rollup.config.js

Here we just add some file we want the linter to ignore

Setting Babel configurations

Create a file name “.babelrc” and add the following json.

{
"presets": [
[
"@babel/env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"modules": false
}
],
"@babel/react"
]
}

Here we set the way we’d like Babel to parse our JavaScript and React JSX.

Setting our Rollup bundler

Create a file name “rollup.config.js” and add the following configuration code.

import babel from 'rollup-plugin-babel'
import commonjs from 'rollup-plugin-commonjs'
import postcss from 'rollup-plugin-postcss'
import resolve from 'rollup-plugin-node-resolve'
import url from 'rollup-plugin-url'
import svgr from '@svgr/rollup'
export default {
plugins: [
external(),
postcss({
modules: true
}),
url(),
svgr(),
babel({
exclude: 'node_modules/**',
}),
resolve(),
commonjs()
]
}

You might notice that our rollup.config.js file is missing the entry and output files configuration. This is because we are going to set them, using our Gulp file.

The Gulp file default task, is to run our Rollup bundler, through every component in our library and parse it to ES5 Javascript with CJS module specifiers. This is to enable us to import our component using non ESM supporting systems such as node.js

Setting Gulp tasks

Create a file name “gulpfile.js” and add the following code.

const gulp = require('gulp');
const shell = require('gulp-shell');
const watch = require('gulp-watch');
const globs = ['src/**/*.js', '!src/**/*.test.js'];
const shellCmd = ["rollup <%= file.path %> --file <%= file.path.replace('src','lib') %> -f cjs -c -m"];
gulp.task('build', () => {
return gulp
.src(globs, { read: false })
.pipe(shell(shellCmd));
});
gulp.task('watch', ['build'], () => {
return gulp.src(globs)
.pipe(watch(globs))
.pipe(shell(shellCmd));
});
gulp.task('default', ['build']);

We have two main tasks

  • ‘build’ to run over all the components and parse them.
  • ‘watch’ to parse only changed files.

Now you could add a demo app, to test your library. For this is I use the ‘create-react-app’ (As said before, I don’t like to write my own configs 😄)

Link your project

In the library: yarn link
In the app: yarn link 'your library package name'

Notice that link doesn’t add the library to your app’s package.json. so remember to do that yourself relative to your app (Thanks ShayCes).

Last thing to do, publish your library to NPM npm publish

Finally, I’d like to thank my two awesome friends, Shay Cojocaru and Yury Michurin for looking at my code and telling me, where I messed up (And I did)

You can check my demo project on Github.

I hope this was helpful to you.

--

--

Gilad lev-ari

Full stack web engineer with over a decate of experience and true passion for front end development and JavaScript 💪