DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师。

官方网站:devui.design

Ng组件库:ng-devui(欢迎Star)

官方交流:添加DevUI小助手(devui-official)

DevUIHelper插件:DevUIHelper-LSP(欢迎Star)

前言

随着前端生态的繁荣,工具库几乎是高效开发的必需品,lodash/dayjs/numberal等实用的工具库相信大家都用过。

我近期在开发Calendar Graph Github提交日历组件时,发现有很多需要处理颜色的场景,比如判断一个字符串是否是一个有效的颜色值、hex颜色值和rgb颜色值的互转等,但没有找到一个能很好满足我全部需求的开源库,所以决定自己造一个轮子。

这就是做ktools工具库的原因,本文将介绍如何使用Rollup这个轻量的下一代模块打包器打造自己的TypeScript工具库。

通过阅读本文,你将学到:

  1. 如何初始化一个Rollup工程项目
  2. 如何配置Rollup和TypeScript
  3. 如何编写脚本,构建并发布自己的工具库到npm仓库

1 创建并初始化Github项目

做一个开源库的第一步是创建一个Github(或Gitlab等)代码仓库,并进行简单的初始化,主要包括:

  1. 创建Git提交忽略配置 .gitignore
  2. 创建开源协议声明 LICENSE
  3. 初始化package.json
  4. 配置TypeScript tsconfig.json
  5. 配置Rollup rollup.config.js

1.1 Git提交忽略配置

为了防止node_modules等自动生成的目录/文件提交到远程代码仓库,提交忽略是首先要考虑的事情,前期可以简单配置下即可。

先创建一个.gitignore文件

touch .gitignore

在新创建的.gitignore文件中增加以下内容:

# dependencies
/node_modules # compiled output
/dist

详细的配置可以参考Github官方文档:

https://docs.github.com/en/free-pro-team@latest/github/using-git/ignoring-files

1.2 创建开源协议声明 LICENSE

开源协议可以在创建Github仓库时选择,也可以创建仓库之后再加,一般选择MIT协议。

这里介绍一个创建仓库之后补加协议的小技巧。主要分成以下几个步骤:

  1. 在Github仓库增加一个文件
  2. 输入LICENSE(注意必须全部大写)
  3. 选择协议
  4. 提交

Step 1: 在Github仓库增加一个文件

在代码仓库的目录结构右上方,有一个Add file下拉框,选择其中的Create new file选项,进入创建新文件的页面。

Step 2: 输入"LICENSE"

在文件名中输入全大些的LICENSE,这时输入框右边会多出来一个按钮Choose a license template

Step 3: 选择协议

点击Choose a license template按钮,进入选择协议模板的页面。

我们在左侧目录选择MIT License,然后在右侧边栏输入年份和作者名字,可以看到中间的Copyright (c)后面的年份和作者会相应变化,点击Review and submit按钮,即可返回创建文件的页面,并自动用刚刚选择的协议内容填充到LICENSE文件中。

Step 4: 提交

点击创建文件页面下方的Commit new file即可提交LICENSE文件到代码仓库。

提交之后会自动跳转到LICENSE页面,效果如下:

1.3 初始化package.json

添加.gitignore/LICENSE这两个基本的文件之后,下一步就是初始化package.json文件,这是管理依赖包及其版本的包配置文件,前端项目必备。

我们可以使用以下命令创建一个默认的package.json:

npm init -y

增加-y参数是不想一直按Enter

创建好的package.json文件如下:

{
"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"
}

我们可以简单地修改和完善下。

nameversion分别是包名和版本号,均可后续发布时通过脚本动态修改,不用管。

description描述可以加下:

"description": "前端工具库"

main/scripts这些后续在构建部署脚本的章节会细讲。

keywords/author可以加下:

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

配置好package.json,后续安装依赖包时会自动更新该文件,可以非常方便地进行依赖管理。

1.4 配置TypeScript tsconfig.json

TypeScript这种强类型的语言,是对JavaScript很好的补充和增强,目前来看前景很好,必须用起来。

安装tsc

我们可以使用tsc命令行工具快速创建TypeScript默认配置文件。

先确认下是否安装tsc,输入命令:

tsc -v

出现以下命令说明未安装:

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

可以通过以下命令全局安装:

npm i -g typescript

成功安装之后,再查看下tsc版本:

$ tsc -v
Version 4.1.2

生成tsconfig.json配置文件

可以使用以下快速生成默认的tsconfig.json配置:

tsc --init

生成的tsconfig.json文件如下(已删除注释代码):

{
"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. */
}
}

默认的配置其实已经够用,我们不做修改,后续可以根据需要删减配置。

1.5 配置Rollup rollup.config.js

初始化工程的最后一步就是配置Rollup,先创建一个Rollup配置文件,没有Rollup CLI工具不支持初始化配置文件,只能手动创建:

touch rollup.config.js

然后在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', // 打包入口
output: { // 打包出口
file: pkg.browser, // 最终打包出来的文件路径和文件名,这里是在package.json的browser: 'dist/index.js'字段中配置的
format: 'umd', // umd是兼容amd/cjs/iife的通用打包格式,适合浏览器
},
plugins: [ // 打包插件
resolve(), // 查找和打包node_modules中的第三方模块
commonjs(), // 将 CommonJS 转换成 ES2015 模块供 Rollup 处理
typescript() // 解析TypeScript
]
};

package.json中配置browser字段:

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

安装Rollup和TypeScript相关依赖:

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

注意tslib这个依赖库也是必需的,因为rollup-plugin-typescript插件依赖了该库。

Rollup配置文件每个配置项的具体含义可以参考:https://www.rollupjs.com/guide/big-list-of-options

Rollup可用插件列表可以参考:https://github.com/rollup/plugins

2 编写工具库源码

有了以上的初始工程,就可以正式开始写工具方法源码。

2.1 走通流程

先写一个demo,跑通编写源码构建打包引入使用的流程。

编写源码

咱们的入口文件配置在了src/index.ts中,所以需要先创建该文件:

mkdir src
touch src/index.ts

然后在该文件中编写一些代码测试下打包是否正常:

console.log('hello ktools!');

构建打包

在命令行中输入以下命令对项目进行打包:

rollup -c

执行完之后会在dist目录生成打包文件index.js,内容如下:

(function (factory) {
typeof define === 'function' && define.amd ? define(factory) :
factory();
}((function () { 'use strict'; console.log('hello ktools!'); })));

引入使用

这时我们可以随便在一个Vue/React/Angular项目下引入这个空壳工具库,看下是否正常:

比如在 Vue CLI 工程的src/main.js中增加以下代码

import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store'; import ktools from '../index'; // 新增加的代码,将在浏览器控制台输出"hello ktools!" Vue.config.productionTip = false; new Vue({
router,
store,
render: h => h(App),
}).$mount('#app');

或者在 Angular CLI 工程中的src/main.ts文件中增加:

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); // 必须加这个才能输出"hello ktools!",因为没有导出任何东西,所以打印出来的ktools是一个空对象 if (environment.production) {
enableProdMode();
} platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));

2.2 编写工具方法

流程走通之后,就可以正式编写工具方法。

我们编写一个判断一个字符串是否是一个有效的hex十六进制颜色值的工具方法:isColor。

先创建src/is-color.ts文件:

touch src/is-color.ts

增加以下内容:

/**
* 判断字符串是否是十六进制的颜色值
* @param value
*/
const isColor = function(value: string): boolean {
return /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/.test(value);
} export default isColor;

然后在index.ts入口文件中增加引入is-color.ts文件的代码:

import isColor from './is-color';

export {
isColor,
};

重新执行rollup -c进行构建,生成的dist/index.js如下:

(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'; /**
* 判断字符串是否是十六进制的颜色值
* @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 }); })));

再到项目中引入:

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

一切正常!

3 增加构建发布脚本

到这里其实我们的工具库ktools已经完成了90%,还差最后一步,就是发布到npm仓库,可以手工发布。

3.1 手工发布

将package.json文件拷贝到dist目录,修改version为本次发布的版本号,比如0.0.1,然后进入该目录:

cd dist

执行以下命令即可将我们的ktools工具库发布到npm仓库:

npm publish

带着欢呼雀跃的心情等待发布成功,结果报错,以下是报错信息:

$ 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

看提示似乎是包名重复[捂脸][苦涩],提示里还很友好地建议先重命名包名为@kagol/ktools,然后再发布。

那我们就按照提示尝试下改个名字吧,加个scope:

"name": "ktools"

->

"name": "@kagol/ktools",

改完名字重新发布,成功啦!

$ 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

这时可以在项目中正式安装并引入使用。

先安装:

npm i @kagol/ktools

使用方式和之前的一样,只是需要把引入方式改了:

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 通过脚本发布

每次发布还要将文件拷贝来拷贝去,又要修改包名,又要改版本号,很麻烦,可以编写脚本将这个过程自动化。

主要分以下步骤:

  1. 拷贝文件
  2. 修改文件
  3. 发布

Step 1: 拷贝文件

在package.json的scripts中增加拷贝文件的脚本:

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

Step 2: 修改文件

新建scripts/publish.js文件,增加以下内容:

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; // 默认版本号
const defaultVersion = `${mainVersion}.${subVersion}.${+phaseVersion+1}`; let newVersion = defaultVersion; // 从命令行参数中取版本号
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); // 修改包名
shelljs.sed('-i', `"version": "${currentVersion}"`, `"version": "${newVersion}"`, targetFile); // 修改版本号
shelljs.cd('dist');
shelljs.exec('npm publish'); // 发布
} publish();

这里最核心的两步:

  1. 修改包名
  2. 获取正确的版本号并修改

其中修改文件使用shelljs库,获取版本号参数使用了TJ大神的commander工具。

需要提前安装这两个依赖库:

npm i -D shelljs commander

另外需要在package.json中增加构建的脚本命令:

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

Step 3: 发布

发布的步骤比较简单,已经放在publish.js脚本文件中。

每次发布只需要依次运行以下命令即可:

npm run build
npm run publish -- -v 0.0.2

后续可以考虑将其集成到流水线,实现完全的自动化部署,这里可以参考我之前写的一片文章:大厂是如何用DevCloud流水线实现自动化部署Web应用的?

4 小结

本文详细地介绍了使用Rollup+TypeScript打造一个开源工具库的流程和步骤,并介绍如何配置Rollup和TypeScript,如何编写部署脚本自动化发布工具库到npm仓库。希望大家喜欢,并欢迎给个Star鼓励,以下是ktools工具库的源码地址:

https://github.com/kagol/ktools

也欢迎点亮我们的DevUI组件库的星星

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

加入我们

我们是DevUI团队,欢迎来这里和我们一起打造优雅高效的人机设计/研发体系。招聘邮箱:muyang2@huawei.com。

文/DevUI Kagol

往期文章推荐

《前端有了这两样神器,再也不用追着后台要接口啦》

《使用Git,10件你可能需要“反悔”的事》

《手把手教你使用Vue/React/Angular三大框架开发Pagination分页组件》

手把手教你使用Rollup打包📦并发布自己的工具库🔧的更多相关文章

  1. C#:手把手教你用C#打包应用程序(安装程序卸载程序)

    摘要:本文介绍在C#中手把手教你用C#打包应用程序(安装程序卸载程序) 1:新建安装部署项目 打开VS,点击新建项目,选择:其他项目类型->安装与部署->安装向导(安装项目也一样),然后点 ...

  2. 手把手教你写vue插件并发布(二)

    前记:上一篇 https://www.cnblogs.com/adouwt/p/9211003.html, 说到了一个完整的vue插件开发.发布的流程,总结下来就讲了这么一个事,如何注入vue, 如果 ...

  3. 手把手教你写vue插件并发布(一)

    vue的插件开发 这篇文章较长,需要一定的阅读时间.这里有一份改善版本的插件笔记,在一个项目下完成开发.测试.发布的全过程.https://www.cnblogs.com/adouwt/p/96555 ...

  4. 手把手教你AndroidStudio多渠道打包

    最近不断有朋友向我咨询AndroidStudio多渠道的打包方法,今天整理一下之前积累的打包套路,写一篇文章,手把手的教给大家.        说到多渠道,这里不得不提一下友盟统计,友盟统计是大家日常 ...

  5. 使用Android Studio手把手教你将应用打包+代码混淆

    最近几天用Google的Design库写了个App,使用Android Studio将app打包时遇到的几个瓶颈,所以把详细步骤写入下来. AS中怎么获取应用签名 这和eclipse不同,eclips ...

  6. 手把手教你搭建自己的Angular组件库 - DevUI

    摘要:DevUI 是一款面向企业中后台产品的开源前端解决方案,它倡导沉浸.灵活.至简的设计价值观,提倡设计者为真实的需求服务,为多数人的设计,拒绝哗众取宠.取悦眼球的设计.如果你正在开发 ToB 的工 ...

  7. 学以致用:手把手教你撸一个工具库并打包发布,顺便解决JS浮点数计算精度问题

    本文讲解的是怎么实现一个工具库并打包发布到npm给大家使用.本文实现的工具是一个分数计算器,大家考虑如下情况: \[ \sqrt{(((\frac{1}{3}+3.5)*\frac{2}{9}-\fr ...

  8. 手把手教你如何使用Cocos2d Console 进行html5项目发布

    手把手教你如何使用Cocos2d Console 进行html5项目发布   1.首先需要先安装Cocos2d Console运行需要的工具. 详情参见 这篇文章 http://www.cocoach ...

  9. 手把手教你学Dapr - 6. 发布订阅

    上一篇:手把手教你学Dapr - 5. 状态管理 介绍 发布/订阅模式允许微服务使用消息相互通信.生产者或发布者在不知道哪个应用程序将接收它们的情况下向主题发送消息.这涉及将它们写入输入通道.同样,消 ...

随机推荐

  1. Redis中的一致性哈希问题

    在说redis中的哈希(准确来说是一致性哈希)问题之前,先来看一个问题:为什么在分布式集群中一致性哈希会得到大量应用? 在一个分布式系统中,要将数据存储到具体某个节点,或者将来自客户端的请求分配到某个 ...

  2. eclipse关于新建工程找不到二进制文件的解决方法

    eclipse新建工程后先构建项目 然后右键工程,选择属性,选择c/c++ Build,选择Tool chain editor.中间的Current Toolchain改为Mingw Gcc.然后选择 ...

  3. layui常用的公共属性

    这个是今天看官网是觉得应该很有用的东西,记录在此.位置位于官网页面元素下的HTML规范:常用公共属性中.解释如下: lay-skin=" " 定义相同元素的不同风格,如checkb ...

  4. TRUNCATE 有约束的表

    在有外键约束的情况下,truncate 表时,会报错, 我们可以设置外键检测为flase,执行完truncate命令后,再启用 SET foreign_key_checks = 0;TRUNCATE ...

  5. Jenkins - 部署在Tomcat容器里的Jenkins,提示“反向代理设置有误”

    提示"反向代理设置有误"的背景 将jenkins.war放在tomcat容器中运行 访问Jenkins-系统管理,会提示"反向代理设置有误" 如何解决 在tom ...

  6. 命名管道FIFO及其读写规则

    一.匿名管道的一个限制就是只能在具有共同祖先的进程间通信命名管道(FIFO):如果我们想在不相关的进程之间切换数据,可以使用FIFO文件来做这项工作注意:命名管道是一种特殊类型文件.利用命令:$ mk ...

  7. HttpClient4.3 连接池参数配置及源码解读

    目前所在公司使用HttpClient 4.3.3版本发送Rest请求,调用接口.最近出现了调用查询接口服务慢的生产问题,在排查整个调用链可能存在的问题时(从客户端发起Http请求->ESB-&g ...

  8. phpmyadmin反序列化漏洞(WooYun-2016-199433)

    简介 环境复现:https://github.com/vulhub/vulhub 线上平台:榆林学院内可使用协会内部的网络安全实验平台 phpMyAdmin是一套开源的.基于Web的MySQL数据库管 ...

  9. IntelliJ IDEA 2020.2.3永久破解激活教程 - 2020.10.27

    申明:本教程 IntelliJ IDEA 破解补丁.激活码均收集于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除 不花钱 的方式 IDEA 2020.2 激活到 2089 年 注意:教程适 ...

  10. ABBYY FineReader 15快速转换文档详解

    作为一款专业的"PDF编辑器",用户可通过使用ABBYY FineReader  15的"快速转换"功能,将各种格式的一个或多个文件合并PDF文档.Micros ...