前言
前两天写项目的时候,有个需求要用到事件总线,就将以前封装的事件总线库copy过来了,诶?然后我就想,每次要用都要把以前的拿过来复制,我何不将他直接发布到npm上呢?于是说干就干,但是由于开发工具库这方面经验不多,踩坑N次,最终完美收官。
![](https://file.jishuzhan.net/article/1769654794663759874/014fb7aadf29943810e937b6d138a649.webp)
技术选型
首先来简单分析一下,既然是工具库,那肯定打包后体积要小,而且支持的打包格式要多,在这方面,Rollup
肯定是当仁不让了。在考虑到项目的可维护性和安全性肯定也是要上TypeScript
的,然后就是一些代码风格格式化,代码规范检查,es6 以上语法的转换,统一就列在下面了
- 打包工具
Rollup
- 编程语言
TypeScript
- 代码转换
Babel
- 代码检测
ESLint
- 代码风格
Prettier
EditorConfig
环境搭建
首先先创建文件夹,然后npm初始化一下;
shell
mkdir utils && npm init -y
然后我先放上项目的文件目录结构,后面我会陆续创建和配置这些文件。
txt
utils 项目文件夹
├─dist 打包目录
| ├─index.cjs.js
| ├─index.d.ts
| └index.esm.js
├─src 源码目录
| ├─index.ts 入口文件
| └types.ts 代码类型
├─test 测试目录
| └index.js 测试用例
├─README.md 描述文档
├─.babelrc.json babel 配置文件
├─.editorconfig editorconfig 配置文件
├─.eslintignore eslint 忽略文件
├─.eslintrc.json eslint 配置文件
├─.prettierignore prettier 忽略文件
├─.prettierrc.json prettier 配置文件
├─rollup.config.js rollup 配置文件
├─tsconfig.json typescript 配置文件
├─package.json 包管理文件
└---yarn.lock
Rollup
使用Rollup来打包源代码,tsconfig.json 输出文件模式这里只配置了commonjs和ES Module,具体配置参考:rollup 文档
安装依赖
- rollup
- rollup-plugin-dts ( 生成
.d.ts
文件 ) - rollup-plugin-typescript2 (
rollup
支持ts
编译 ) - @babel/core
- @rollup/plugin-babel (
rollup babel
插件 ) - @rollup/plugin-commonjs ( 识别
commonjs
格式依赖 ) - @rollup/plugin-json ( 将
json
文件转换为ES6模块
) - @rollup/plugin-node-resolve ( 解析第三方库依赖 )
- @rollup/plugin-terser ( 代码压缩 )
shell
yarn add rollup rollup-plugin-dts rollup-plugin-typescript2 @rollup/plugin-babel @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-node-resolve @rollup/plugin-terser --dev
配置文件
rollup.config.js
js
import dts from 'rollup-plugin-dts'
import resolve from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import typescript from 'rollup-plugin-typescript2'
import json from '@rollup/plugin-json'
import terser from '@rollup/plugin-terser'
import babel from '@rollup/plugin-babel'
import { DEFAULT_EXTENSIONS } from '@babel/core'
const entries = ['src/index.ts']
const plugins = [
resolve(),
commonjs(),
json(),
typescript(),
// babel extensions 默认不包含ts,所以需要提供 .ts
babel({
babelHelpers: 'bundled',
exclude: 'node_modules/**',
extensions: [...DEFAULT_EXTENSIONS, '.ts']
}),
terser()
]
const rollupConfig = [
...entries.map((input) => ({
input,
output: [
{
file: input.replace('src/', 'dist/').replace('.ts', '.esm.js'),
format: 'es'
},
{
file: input.replace('src/', 'dist/').replace('.ts', '.cjs.js'),
format: 'cjs'
}
],
plugins
})),
// 单独生成 .d.ts 文件
...entries.map((input) => ({
input,
output: [
{
file: input.replace('src/', 'dist/').replace('.ts', '.d.ts'),
format: 'esm'
}
],
plugins: [dts({ respectExternal: true })]
}))
]
export default rollupConfig
TypeScript
使用tsconfig.json
文件来指定编译这个项目编译选项,具体配置参考: TSConfig
安装依赖
- typescript
- tslib
配置文件
tsconfig.json
json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"lib": ["esnext", "DOM"],
"useDefineForClassFields": true,
"skipLibCheck": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"esModuleInterop": false,
"strict": true,
"strictNullChecks": true
},
"include": ["src/*.ts"]
}
Babel
Babel
可以将新版本 JavaScript 特性的代码转换为向后兼容的代码,确保能够在不同环境中平稳运行。 具体配置参考:Babel 文档
安装依赖
- @babel/preset-env ( babel 预设 )
- @babel/preset-typescript
配置文件
.babelrc.json
json
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"node": "current"
}
}
],
"@babel/preset-typescript"
]
}
ESLint
ESLint
用于发现并修复代码中的错误,通过配置规则、帮助开发者提高代码质量、减少错误。具体配置参考:ESLint 文档
安装依赖
- eslint
- @typescript-eslint/eslint-plugin ( eslint ts插件)
- @typescript-eslint/parser ( eslint ts解析器 )
配置文件
.eslintrc.json
json
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}
.eslintignore
bash
/node_modules
/dist
代码风格
安装依赖
- prettier
配置文件
.prettierrc.json
json
{
"useTabs": false,
"tabWidth": 2,
"printWidth": 80,
"singleQuote": true,
"trailingComma": "none",
"semi": false
}
.prettierignore
bash
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
.editorconfig
( vscode 需要下载 EditorConfig for VS Code 拓展 )
ini
# http://editorconfig.org
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false
package.json
下载完所有的依赖,将文件配置好后,还需要配置一下package.json
可以配置一下文件exports导出,以及types和模块规则
json
{
...options,
"type": "module",
"exports": {
".": {
"import": "./dist/index.esm.js",
"require": "./dist/index.cjs.js"
}
},
"main": "dist/index.esm.js",
"module": "dist/index.cjs.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
}
然后在scripts
中配置一些命令,新建测试文件,测试一下。
json
{
...options,
"scripts": {
"build": "rollup -c",
"dev": "yarn build --watch",
"test": "npx nodemon test/index.js",
"lint": "eslint src/**/*.{js,jsx,ts,tsx,json}",
"prettier": "prettier --config .prettierrc.json --write ./**/**/*.{js,jsx,ts,tsx,json}"
},
}
打包发布
首先发布之前先运行一下lint
和prettier
命令,检查一下代码,然后build
一下。
发布到npm需要有一个npm账号,没有的去注册一下。
![](https://file.jishuzhan.net/article/1769654794663759874/f901858e7751b35d7267dd0c78b91602.webp)
注册完账号之后,将npm源切换到https://registry.npmjs.org/
shell
npm config set registry https://registry.npm.taobao.org/
然后在终端执行npm login
登录npm
shell
npm login
出现如下信息,则表示登录成功
![](https://file.jishuzhan.net/article/1769654794663759874/f86843c131fdf43e487f12ec2bd06c30.webp)
最后在执行npm publish
命令,发不到npm上。
总结
最后如果本文对有想自己写一个工具库的小伙伴,有所帮助的话,可以麻烦给 Eenex 点一个小小的star
github 仓库地址:github.com/OpenKnights...
npm 包地址:www.npmjs.com/package/eve...
可以关注下我的微信公众号:"King3",一起交流技术!