Teach you how to use Rollup to package πŸ“¦ and publish your own tool library πŸ”§

DevUI is a team with both a design perspective and an engineering perspective, serving HUAWEI CLOUD DevCloud The platform and several mid- and back-end systems within Huawei serve designers and front-end engineers.
Official website: devui.design
Ng component library: ng-devui (Welcome to Star)
Official Communication: Add DevUI Assistant (devui-official)
DevUIHelper Plugin: DevUIHelper-LSP (Welcome to Star)

foreword

With the prosperity of the front-end ecosystem, tool libraries are almost a necessity for efficient development. lodash/dayjs/numberal I believe everyone has used the useful tool library.

I'm currently developing Calendar Graph When Github submitted the calendar component, I found that there are many scenarios that need to deal with colors, such as judging whether a string is a valid color value, the mutual conversion of hex color value and rgb color value, etc., but I have not found one that can satisfy all of my needs. I need an open source library, so I decided to build a wheel myself.

this is to do ktools The reason for the tool library, this article will describe how to use Rollup This lightweight next-generation module bundler builds its own TypeScript tooling library.

By reading this article, you will learn:

  1. How to initialize a Rollup project
  2. How to configure Rollup and TypeScript
  3. How to script, build and publish your own repository to npm repository

1 Create and initialize a Github project

The first step in making an open source library is to create a Github (or Gitlab, etc.) code repository and perform a simple initialization, which mainly includes:

  1. Create a Git commit ignore configuration .gitignore
  2. Create Open Source License Statement LICENSE
  3. Initialize package.json
  4. Configure TypeScript tsconfig.json
  5. Configure Rollup rollup.config.js

1.1 Git commit ignore configuration

In order to prevent automatically generated directories/files such as node_modules from being submitted to the remote code repository, committing ignoring is the first thing to consider, and it can be simply configured in the early stage.

First create a .gitignore file

touch .gitignore 

Add the following to the newly created .gitignore file:

# dependencies
/node_modules

# compiled output
/dist 

For detailed configuration, please refer to the official Github documentation: https://docs.github.com/en/free-pro-team@latest/github/using-git/ignoring-files

1.2 Create an open source agreement statement LICENSE

The open source protocol can be selected when creating the Github repository, or it can be added after the repository is created. Generally, the MIT protocol is selected.

Here is a little trick for adding protocols after creating a repository. Mainly divided into the following steps:

  1. Add a file to the Github repository
  2. Type LICENSE (note that it must be all uppercase)
  3. Choose an agreement
  4. submit

Step 1: Add a file to the Github repository

At the top right of the directory structure of the code repository, there is an Add file drop-down box, select the Create new file option in it, and enter the page for creating a new file.

Step 2: Enter "LICENSE"

Enter the full-size LICENSE in the file name, and a button Choose a license template will appear on the right side of the input box.

Step 3: Choose a protocol

Click the Choose a license template button to enter the page for choosing a license template.

We select MIT License in the left directory, and then enter the year and author's name in the right sidebar. You can see that the year and author after the Copyright (c) in the middle will change accordingly. Click the Review and submit button to return to the creation of the file. page, and automatically populate the LICENSE file with the content of the protocol you just selected.

Step 4: Submit

Click Commit new file at the bottom of the file creation page to submit the LICENSE file to the code repository.

After submitting, it will automatically jump to the LICENSE page, the effect is as follows:

1.3 Initialize package.json

After adding the two basic files .gitignore/LICENSE, the next step is to initialize the package.json file, which is the package configuration file for managing dependent packages and their versions, and is necessary for front-end projects.

We can create a default package.json with the following command:

npm init -y 

Adding the -y parameter is not wanting to keep pressing EnterπŸ˜„

The created package.json file is as follows:

{
  "name": "ktools",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/kagol/ktools.git"
  },
  "keywords": [],
  "author": "",
  "license": "MIT"
} 

We can simply modify and improve it.

name and version are the package name and version number respectively, which can be dynamically modified through scripts during subsequent releases, regardless.

description can be added as follows:

"description": "Front-end tool library" 

main/scripts These will be discussed in detail in the chapter on building and deploying scripts later.

keywords/author can be added:

"keywords": [
  "toolkit",
  "rollup",
  "typescript"
],
"author": "Kagol", 

After configuring package.json, the file will be automatically updated when the dependency package is installed later, which can be very convenient for dependency management.

1.4 Configure TypeScript tsconfig.json

TypeScript, a strongly typed language, is a good complement and enhancement to JavaScript. At present, the prospects are very good, and it must be used.

install tsc

We can quickly create a TypeScript default configuration file using the tsc command line tool.

First confirm whether tsc is installed, enter the command:

tsc -v 

The following command appears indicating that it is not installed:

-bash: /usr/local/bin/tsc: No such file or directory 

It can be installed globally with the following command:

npm i -g typescript 

After successful installation, check the tsc version again:

$ tsc -v
Version 4.1.2 

Generate tsconfig.json configuration file

A default tsconfig.json configuration can be quickly generated using:

tsc --init 

The resulting tsconfig.json file is as follows (commented code removed):

{
  "compilerOptions": {
    /* Visit https://aka.ms/tsconfig.json to read more about this file */

    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */

    /* Module Resolution Options */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */

    /* Advanced Options */
    "skipLibCheck": true,                     /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  }
} 

The default configuration is actually enough, we do not modify it, and the configuration can be deleted later as needed.

1.5 Configure Rollup rollup.config.js

The last step in the initialization project is to configure Rollup. First, create a Rollup configuration file. Without the Rollup CLI tool, the initialization configuration file is not supported. It can only be created manually:

touch rollup.config.js 

Then add the following to rollup.config.js:

import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import typescript from 'rollup-plugin-typescript';
import pkg from './package.json';

export default {
  input: 'src/index.ts', // Packing entrance
  output: { // packaged for export
    file: pkg.browser, // The final packaged file path and file name are configured in the browser: 'dist/index.js' field of package.json
    format: 'umd', // umd is a universal packaging format compatible with amd/cjs/iife, suitable for browsers
  },
  plugins: [ // Packaging plugins
    resolve(), // Find and package third-party modules in node_modules
    commonjs(), // Convert CommonJS to ES2015 modules for Rollup to process
    typescript() // Parse TypeScript
  ]
}; 

Configure the browser field in package.json:

"browser": "dist/index.ts", 

Install Rollup and TypeScript related dependencies:

npm i -D rollup typescript tslib rollup-plugin-node-resolve rollup-plugin-commonjs rollup-plugin-typescript 

Note that the tslib library is also required because the rollup-plugin-typescript plugin depends on this library.

For the specific meaning of each configuration item in the Rollup configuration file, please refer to: https://www.rollupjs.com/guide/big-list-of-options

For the list of available plugins for Rollup, please refer to: https://github.com/rollup/plugins

2 Write the source code of the tool library

With the above initial project, you can officially start writing the source code of the tool method.

2.1 Go through process

First write a demo, run through the process of writing source code, building and packaging, and introducing and using it.

write source code

Our entry file is configured in src/index.ts, so we need to create this file first:

mkdir src
touch src/index.ts 

Then write some code in this file to test whether the packaging is normal:

console.log('hello ktools!'); 

build package

Enter the following command on the command line to package the project:

rollup -c 

After execution, the packaged file index.js will be generated in the dist directory, with the following contents:

(function (factory) {
    typeof define === 'function' && define.amd ? define(factory) :
    factory();
}((function () { 'use strict';

    console.log('hello ktools!');

}))); 

Introduce to use

At this time, we can casually introduce this empty shell tool library under a Vue/React/Angular project to see if it is normal:

For example, add the following code to the src/main.js of the Vue CLI project

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';

import ktools from '../index'; // The newly added code will output "hello ktools!" in the browser console

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app'); 

Or add to the src/main.ts file in the Angular CLI project:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

import ktools from '../index';
console.log('ktools:', ktools); // This must be added to output "hello ktools!", since nothing is exported, ktools is printed as an empty object

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err)); 

2.2 Writing tool methods

After the process goes through, the tool method can be formally written.

Let's write a utility method that determines whether a string is a valid hex color value: isColor.

First create the src/is-color.ts file:

touch src/is-color.ts 

Add the following:

/**
 * Determine if a string is a color value in hexadecimal
 * @param value 
 */
const isColor = function(value: string): boolean {
  return /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/.test(value);
}

export default isColor; 

Then add the code that introduces the is-color.ts file to the index.ts entry file:

import isColor from './is-color';

export {
  isColor,
}; 

Re-execute rollup -c to build, and the generated dist/index.js is as follows:

(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ktools = {}));
}(this, (function (exports) { 'use strict';

  /**
   * Determine if a string is a color value in hexadecimal
   * @param value
   */
  var isColor = function (value) {
      return /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/.test(value);
  };

  exports.isColor = isColor;

  Object.defineProperty(exports, '__esModule', { value: true });

}))); 

Then import into the project:

import { isColor } from '../index';
console.log('isColor #c6e48b:', isColor('#c6e48b')); // isColor #c6e48b: true
console.log('isColor #c6e48:', isColor('#c6e48')); // isColor #c6e48: false 

everything is normal!

3 Add build release script

At this point, our tool library ktools has been completed 90%, and the last step is to publish it to the npm repository, which can be manually published.

3.1 Manual release

Copy the package.json file to the dist directory, modify the version to the version number released this time, such as 0.0.1, and then enter the directory:

cd dist 

Execute the following command to publish our ktools tool library to the npm repository:

npm publish 

Waiting for the successful release with cheers, the result is an error, the following is the error message:

$ npm publish
npm notice
npm notice πŸ“¦  ktools@0.0.1
npm notice === Tarball Contents ===
npm notice 315B index.html
npm notice 634B index.js
npm notice 691B package.json
npm notice === Tarball Details ===
npm notice name:          ktools
npm notice version:       0.0.1
npm notice package size:  1.1 kB
npm notice unpacked size: 1.6 kB
npm notice shasum:        35c3501906443ff46be51c2747c07e73136bf85c
npm notice integrity:     sha512-SZTM0msux0+Pt[...]IWmV6Gx5Tz41w==
npm notice total files:   3
npm notice
npm ERR! code E403
npm ERR! 403 403 Forbidden - PUT http://registry.npmjs.org/ktools - Package name too similar to existing packages; try renaming your package to '@kagol/ktools' and publishing with 'npm publish --access=public' instead
npm ERR! 403 In most cases, you or one of your dependencies are requesting
npm ERR! 403 a package version that is forbidden by your security policy.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/kagol/.npm/_logs/2020-12-05T05_42_31_632Z-debug.log 

Looking at the prompt, it seems that the package name is repeated, and the prompt also kindly suggests renaming the package to @kagol/ktools before publishing it.

Then let's follow the prompts and try to change the name and add a scope:

"name": "ktools"

->

"name": "@kagol/ktools", 

After changing the name and republishing it, it was successful!

$ npm publish
npm notice
npm notice πŸ“¦  @kagol/ktools@0.0.1
npm notice === Tarball Contents ===
npm notice 22.0kB index.js
npm notice 1.2kB  package.json
npm notice 1.8kB  README.md
npm notice === Tarball Details ===
npm notice name:          @kagol/ktools
npm notice version:       0.0.1
npm notice package size:  6.9 kB
npm notice unpacked size: 25.0 kB
npm notice shasum:        d85994aecc86160862cef4f0033e5bfdaa136072
npm notice integrity:     sha512-UEDEJEsMSXcMg[...]yY4KsXp4mXIBA==
npm notice total files:   3
npm notice
+ @kagol/ktools@0.0.1 

At this time, it can be formally installed and introduced into the project.

Install first:

npm i @kagol/ktools 

The usage is the same as before, but the import method needs to be changed:

import { isColor } from '@kagol/ktools';
console.log('isColor #c6e48b:', isColor('#c6e48b')); // isColor #c6e48b: true
console.log('isColor #c6e48:', isColor('#c6e48')); // isColor #c6e48: false 

3.2 Publishing via script

Every time you publish, you have to copy the files, modify the package name, and change the version number, which is very troublesome. You can write a script to automate this process.

Mainly divided into the following steps:

  1. copy file
  2. Modify the file
  3. release

Step 1: Copy the file

Add a script for copying files to scripts in package.json:

"copy": "cp package.json README.md dist", 

Step 2: Modify the file

Create a new scripts/publish.js file and add the following content:

const path = require('path');
const shelljs = require('shelljs');
const program = require('commander');

const targetFile = path.resolve(__dirname, '../dist/package.json');
const packagejson = require(targetFile);
const currentVersion = packagejson.version;
const versionArr = currentVersion.split('.');
const [mainVersion, subVersion, phaseVersion] = versionArr;

// Default version number
const defaultVersion = `${mainVersion}.${subVersion}.${+phaseVersion+1}`;

let newVersion = defaultVersion;

// Take the version number from the command line argument
program
  .option('-v, --versions <type>', 'Add release version number', defaultVersion);

program.parse(process.argv);

if (program.versions) {
  newVersion = program.versions;
}

function publish() {
  shelljs.sed('-i', '"name": "ktools"', '"name": "@kagol/ktools"', targetFile); // Modify package name
  shelljs.sed('-i', `"version": "${currentVersion}"`, `"version": "${newVersion}"`, targetFile); // Modify version number
  shelljs.cd('dist');
  shelljs.exec('npm publish'); // release
}

publish(); 

The two most important steps here:

  1. Modify package name
  2. Get the correct version number and modify

The modified file uses the shelljs library, and the version number parameter is used TJ Great God commander tool.

These two dependent libraries need to be installed in advance:

npm i -D shelljs commander 

In addition, you need to add the build script command to package.json:

"build": "rollup -c && npm run copy", 

Step 3: Publish

The publishing steps are relatively simple and have been placed in the publish.js script file.

Each release just needs to run the following commands in sequence:

npm run build
npm run publish -- -v 0.0.2 

In the future, you can consider integrating it into the pipeline to achieve fully automated deployment. Here you can refer to an article I wrote earlier: How does the big factory use the DevCloud pipeline to automate the deployment of Web applications?

4 Summary

This article introduces in detail the process and steps of using Rollup+TypeScript to create an open source tool library, and introduces how to configure Rollup and TypeScript, and how to write deployment scripts to automatically publish the tool library to the npm repository. I hope you like it, and welcome to give a Star🌟 encouragement. The following is the source code address of the ktools tool library:

https://github.com/kagol/ktools

Also welcome to light up the stars of our DevUI component library 🌟

https://github.com/DevCloudFE/ng-devui

join us

We are the DevUI team, welcome to come here to create an elegant and efficient human-machine design/R&D system with us. Recruitment email: muyang2@huawei.com.

Text/DevUI Kagol

Recommended articles in the past

How does the big factory use the DevCloud pipeline to automate the deployment of Web applications? >

"Teach you how to build your own Angular component library"

"Web Interface Dark Mode and Theming Development"

Tags: Front-end TypeScript rollup

Posted by nkyoung1 on Tue, 03 May 2022 14:40:56 +0300