DevUI是一支兼具設計視角和工程視角的團隊,服務於華爲雲DevCloud平臺和華爲內部數箇中後臺系統,服務於設計師和前端工程師。
官方網站:devui.design
Ng組件庫:ng-devui(歡迎Star)
官方交流:添加DevUI小助手(devui-official)
DevUIHelper插件:DevUIHelper-LSP(歡迎Star)html
隨着前端生態的繁榮,工具庫幾乎是高效開發的必需品,lodash/dayjs/numberal等實用的工具庫相信你們都用過。前端
我近期在開發Calendar Graph Github提交日曆組件時,發現有不少須要處理顏色的場景,好比判斷一個字符串是不是一個有效的顏色值、hex顏色值和rgb顏色值的互轉等,但沒有找到一個能很好知足我所有需求的開源庫,因此決定本身造一個輪子。vue
這就是作ktools工具庫的緣由,本文將介紹如何使用Rollup這個輕量的下一代模塊打包器打造本身的TypeScript工具庫。node
經過閱讀本文,你將學到:git
作一個開源庫的第一步是建立一個Github(或Gitlab等)代碼倉庫,並進行簡單的初始化,主要包括:github
爲了防止node_modules
等自動生成的目錄/文件提交到遠程代碼倉庫,提交忽略是首先要考慮的事情,前期能夠簡單配置下便可。typescript
先建立一個.gitignore文件shell
1 touch .gitignore
在新建立的.gitignore文件中增長如下內容:npm
1 # dependencies 2 /node_modules 3 4 # compiled output 5 /dist
詳細的配置能夠參考Github官方文檔: https://docs.github.com/en/free-pro-team@latest/github/using-git/ignoring-filesjson
開源協議能夠在建立Github倉庫時選擇,也能夠建立倉庫以後再加,通常選擇MIT協議。
這裏介紹一個建立倉庫以後補加協議的小技巧。主要分紅如下幾個步驟:
LICENSE
(注意必須所有大寫)在代碼倉庫的目錄結構右上方,有一個Add file
下拉框,選擇其中的Create new file
選項,進入建立新文件的頁面。
在文件名中輸入全大些的LICENSE
,這時輸入框右邊會多出來一個按鈕Choose a license template
。
點擊Choose a license template
按鈕,進入選擇協議模板的頁面。
咱們在左側目錄選擇MIT License
,而後在右側邊欄輸入年份和做者名字,能夠看到中間的Copyright (c)
後面的年份和做者會相應變化,點擊Review and submit
按鈕,便可返回建立文件的頁面,並自動用剛剛選擇的協議內容填充到LICENSE文件中。
點擊建立文件頁面下方的Commit new file
便可提交LICENSE文件到代碼倉庫。
提交以後會自動跳轉到LICENSE頁面,效果以下:
添加.gitignore
/LICENSE
這兩個基本的文件以後,下一步就是初始化package.json
文件,這是管理依賴包及其版本的包配置文件,前端項目必備。
咱們可使用如下命令建立一個默認的package.json:
1 npm init -y
增長-y
參數是不想一直按Enter😄
建立好的package.json文件以下:
1 { 2 "name": "ktools", 3 "version": "1.0.0", 4 "description": "", 5 "main": "index.js", 6 "scripts": { 7 "test": "echo \"Error: no test specified\" && exit 1" 8 }, 9 "repository": { 10 "type": "git", 11 "url": "git+https://github.com/kagol/ktools.git" 12 }, 13 "keywords": [], 14 "author": "", 15 "license": "MIT" 16 }
咱們能夠簡單地修改和完善下。
name
和version
分別是包名和版本號,都可後續發佈時經過腳本動態修改,不用管。
description
描述能夠加下:
1 "description": "前端工具庫"
main
/scripts
這些後續在構建部署腳本的章節會細講。
keywords
/author
能夠加下:
1 "keywords": [ 2 "toolkit", 3 "rollup", 4 "typescript" 5 ], 6 "author": "Kagol",
配置好package.json,後續安裝依賴包時會自動更新該文件,能夠很是方便地進行依賴管理。
TypeScript這種強類型的語言,是對JavaScript很好的補充和加強,目前來看前景很好,必須用起來。
咱們可使用tsc命令行工具快速建立TypeScript默認配置文件。
先確認下是否安裝tsc,輸入命令:
1 tsc -v
出現如下命令說明未安裝:
1 -bash: /usr/local/bin/tsc: No such file or directory
能夠經過如下命令全局安裝:
1 npm i -g typescript
成功安裝以後,再查看下tsc版本:
1 $ tsc -v 2 Version 4.1.2
可使用如下快速生成默認的tsconfig.json
配置:
1 tsc --init
生成的tsconfig.json
文件以下(已刪除註釋代碼):
1 { 2 "compilerOptions": { 3 /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 5 /* Basic Options */ 6 "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 7 "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 8 9 /* Strict Type-Checking Options */ 10 "strict": true, /* Enable all strict type-checking options. */ 11 12 /* Module Resolution Options */ 13 "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 14 15 /* Advanced Options */ 16 "skipLibCheck": true, /* Skip type checking of declaration files. */ 17 "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 18 } 19 }
默認的配置其實已經夠用,咱們不作修改,後續能夠根據須要刪減配置。
初始化工程的最後一步就是配置Rollup,先建立一個Rollup配置文件,沒有Rollup CLI工具不支持初始化配置文件,只能手動建立:
1 touch rollup.config.js
而後在rollup.config.js
中增長如下內容:
1 import resolve from 'rollup-plugin-node-resolve'; 2 import commonjs from 'rollup-plugin-commonjs'; 3 import typescript from 'rollup-plugin-typescript'; 4 import pkg from './package.json'; 5 6 export default { 7 input: 'src/index.ts', // 打包入口 8 output: { // 打包出口 9 file: pkg.browser, // 最終打包出來的文件路徑和文件名,這裏是在package.json的browser: 'dist/index.js'字段中配置的 10 format: 'umd', // umd是兼容amd/cjs/iife的通用打包格式,適合瀏覽器 11 }, 12 plugins: [ // 打包插件 13 resolve(), // 查找和打包node_modules中的第三方模塊 14 commonjs(), // 將 CommonJS 轉換成 ES2015 模塊供 Rollup 處理 15 typescript() // 解析TypeScript 16 ] 17 };
在package.json
中配置browser
字段:
1 "browser": "dist/index.ts",
安裝Rollup和TypeScript相關依賴:
1 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
有了以上的初始工程,就能夠正式開始寫工具方法源碼。
先寫一個demo,跑通編寫源碼
、構建打包
、引入使用
的流程。
我們的入口文件配置在了src/index.ts中,因此須要先建立該文件:
1 mkdir src 2 touch src/index.ts
而後在該文件中編寫一些代碼測試下打包是否正常:
1 console.log('hello ktools!');
在命令行中輸入如下命令對項目進行打包:
1 rollup -c
執行完以後會在dist目錄生成打包文件index.js,內容以下:
1 (function (factory) { 2 typeof define === 'function' && define.amd ? define(factory) : 3 factory(); 4 }((function () { 'use strict'; 5 6 console.log('hello ktools!'); 7 8 })));
這時咱們能夠隨便在一個Vue/React/Angular項目下引入這個空殼工具庫,看下是否正常:
好比在 Vue CLI 工程的src/main.js中增長如下代碼
1 import Vue from 'vue'; 2 import App from './App.vue'; 3 import router from './router'; 4 import store from './store'; 5 6 import ktools from '../index'; // 新增長的代碼,將在瀏覽器控制檯輸出"hello ktools!" 7 8 Vue.config.productionTip = false; 9 10 new Vue({ 11 router, 12 store, 13 render: h => h(App), 14 }).$mount('#app');
或者在 Angular CLI 工程中的src/main.ts文件中增長:
1 import { enableProdMode } from '@angular/core'; 2 import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 4 import { AppModule } from './app/app.module'; 5 import { environment } from './environments/environment'; 6 7 import ktools from '../index'; 8 console.log('ktools:', ktools); // 必須加這個才能輸出"hello ktools!",由於沒有導出任何東西,因此打印出來的ktools是一個空對象 9 10 if (environment.production) { 11 enableProdMode(); 12 } 13 14 platformBrowserDynamic().bootstrapModule(AppModule) 15 .catch(err => console.error(err));
流程走通以後,就能夠正式編寫工具方法。
咱們編寫一個判斷一個字符串是不是一個有效的hex十六進制顏色值的工具方法:isColor。
先建立src/is-color.ts文件:
1 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文件的代碼:
1 import isColor from './is-color'; 2 3 export { 4 isColor, 5 };
從新執行rollup -c
進行構建,生成的dist/index.js以下:
1 (function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : 3 typeof define === 'function' && define.amd ? define(['exports'], factory) : 4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ktools = {})); 5 }(this, (function (exports) { 'use strict'; 6 7 /** 8 * 判斷字符串是不是十六進制的顏色值 9 * @param value 10 */ 11 var isColor = function (value) { 12 return /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/.test(value); 13 }; 14 15 exports.isColor = isColor; 16 17 Object.defineProperty(exports, '__esModule', { value: true }); 18 19 })));
再到項目中引入:
1 import { isColor } from '../index'; 2 console.log('isColor #c6e48b:', isColor('#c6e48b')); // isColor #c6e48b: true 3 console.log('isColor #c6e48:', isColor('#c6e48')); // isColor #c6e48: false
一切正常!
到這裏其實咱們的工具庫ktools
已經完成了90%,還差最後一步,就是發佈到npm倉庫,能夠手工發佈。
將package.json文件拷貝到dist目錄,修改version爲本次發佈的版本號,好比0.0.1,而後進入該目錄:
1 cd dist
執行如下命令便可將咱們的ktools工具庫發佈到npm倉庫:
1 npm publish
帶着歡呼雀躍的心情等待發布成功,結果報錯,如下是報錯信息:
1 $ npm publish 2 npm notice 3 npm notice 📦 ktools@0.0.1 4 npm notice === Tarball Contents === 5 npm notice 315B index.html 6 npm notice 634B index.js 7 npm notice 691B package.json 8 npm notice === Tarball Details === 9 npm notice name: ktools 10 npm notice version: 0.0.1 11 npm notice package size: 1.1 kB 12 npm notice unpacked size: 1.6 kB 13 npm notice shasum: 35c3501906443ff46be51c2747c07e73136bf85c 14 npm notice integrity: sha512-SZTM0msux0+Pt[...]IWmV6Gx5Tz41w== 15 npm notice total files: 3 16 npm notice 17 npm ERR! code E403 18 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 19 npm ERR! 403 In most cases, you or one of your dependencies are requesting 20 npm ERR! 403 a package version that is forbidden by your security policy. 21 22 npm ERR! A complete log of this run can be found in: 23 npm ERR! /Users/kagol/.npm/_logs/2020-12-05T05_42_31_632Z-debug.log
看提示彷佛是包名重複[捂臉][苦澀],提示裏還很友好地建議先重命名包名爲@kagol/ktools
,而後再發布。
那咱們就按照提示嘗試下改個名字吧,加個scope:
1 "name": "ktools" 2 3 -> 4 5 "name": "@kagol/ktools",
改完名字從新發布,成功啦!
1 $ npm publish 2 npm notice 3 npm notice 📦 @kagol/ktools@0.0.1 4 npm notice === Tarball Contents === 5 npm notice 22.0kB index.js 6 npm notice 1.2kB package.json 7 npm notice 1.8kB README.md 8 npm notice === Tarball Details === 9 npm notice name: @kagol/ktools 10 npm notice version: 0.0.1 11 npm notice package size: 6.9 kB 12 npm notice unpacked size: 25.0 kB 13 npm notice shasum: d85994aecc86160862cef4f0033e5bfdaa136072 14 npm notice integrity: sha512-UEDEJEsMSXcMg[...]yY4KsXp4mXIBA== 15 npm notice total files: 3 16 npm notice 17 + @kagol/ktools@0.0.1
這時能夠在項目中正式安裝並引入使用。
先安裝:
1 npm i @kagol/ktools
使用方式和以前的同樣,只是須要把引入方式改了:
1 import { isColor } from '@kagol/ktools'; 2 console.log('isColor #c6e48b:', isColor('#c6e48b')); // isColor #c6e48b: true 3 console.log('isColor #c6e48:', isColor('#c6e48')); // isColor #c6e48: false
每次發佈還要將文件拷貝來拷貝去,又要修改包名,又要改版本號,很麻煩,能夠編寫腳本將這個過程自動化。
主要分如下步驟:
在package.json的scripts中增長拷貝文件的腳本:
1 "copy": "cp package.json README.md dist",
新建scripts/publish.js文件,增長如下內容:
1 const path = require('path'); 2 const shelljs = require('shelljs'); 3 const program = require('commander'); 4 5 const targetFile = path.resolve(__dirname, '../dist/package.json'); 6 const packagejson = require(targetFile); 7 const currentVersion = packagejson.version; 8 const versionArr = currentVersion.split('.'); 9 const [mainVersion, subVersion, phaseVersion] = versionArr; 10 11 // 默認版本號 12 const defaultVersion = `${mainVersion}.${subVersion}.${+phaseVersion+1}`; 13 14 let newVersion = defaultVersion; 15 16 // 從命令行參數中取版本號 17 program 18 .option('-v, --versions <type>', 'Add release version number', defaultVersion); 19 20 program.parse(process.argv); 21 22 if (program.versions) { 23 newVersion = program.versions; 24 } 25 26 function publish() { 27 shelljs.sed('-i', '"name": "ktools"', '"name": "@kagol/ktools"', targetFile); // 修改包名 28 shelljs.sed('-i', `"version": "${currentVersion}"`, `"version": "${newVersion}"`, targetFile); // 修改版本號 29 shelljs.cd('dist'); 30 shelljs.exec('npm publish'); // 發佈 31 } 32 33 publish();
這裏最核心的兩步:
其中修改文件使用shelljs庫,獲取版本號參數使用了TJ大神的commander工具。
須要提早安裝這兩個依賴庫:
1 npm i -D shelljs commander
另外須要在package.json中增長構建的腳本命令:
1 "build": "rollup -c && npm run copy",
發佈的步驟比較簡單,已經放在publish.js腳本文件中。
每次發佈只須要依次運行如下命令便可:
1 npm run build 2 npm run publish -- -v 0.0.2
後續能夠考慮將其集成到流水線,實現徹底的自動化部署,這裏能夠參考我以前寫的一片文章:大廠是如何用DevCloud流水線實現自動化部署Web應用的?
本文詳細地介紹了使用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
往期文章推薦