打包一个工具类

FXUtils 项目超详细配置说明

本项目是一个 TypeScript 工具库,采用 Rollup 打包,支持 npm、浏览器等多种使用场景,内置 Babel + core-js polyfill,兼容老环境。本文档面向新手,逐项详细解释每个配置文件和打包流程。


目录结构简述

bash 复制代码
├── dist/                # 打包输出目录
│   ├── index.cjs.js     # CommonJS 产物
│   ├── index.esm.js     # ESModule 产物
│   ├── index.umd.js     # UMD 产物(浏览器/Node 通用)
│   └── types/           # 类型声明文件
├── src/                 # 源码目录
│   ├── index.ts         # 主入口
│   └── utils/           # 工具函数目录
├── package.json         # npm 配置
├── tsconfig.json        # TypeScript 配置
├── .babelrc             # Babel 配置
├── rollup.config.js     # 打包配置
├── .gitignore           # 忽略文件
├── index.html           # 浏览器 demo
└── 文档.txt             # 常用命令

1. package.json 详细说明

json 复制代码
{
  "name": "@fuxing666/fxutils",         // 包名,npm 发布和引用时用
  "version": "2.1.0",                   // 版本号
  "main": "dist/index.cjs.js",          // CommonJS 入口(Node.js require 时用)
  "module": "dist/index.esm.js",        // ESModule 入口(现代打包工具/浏览器用)
  "types": "dist/types/index.d.ts",     // TypeScript 类型声明入口
  "scripts": {
    "build": "rimraf dist && rollup -c" // build 命令,先删 dist 再 rollup 打包
  },
  "devDependencies": {                   // 只在开发/打包时需要的依赖
    "@babel/core": "^7.28.0",           // Babel 主程序
    "@babel/preset-env": "^7.28.0",     // Babel 预设,转译新 JS 语法
    "@babel/preset-typescript": "^7.27.1", // Babel 支持 TypeScript
    "@rollup/plugin-babel": "^6.0.4",   // Rollup Babel 插件
    "@rollup/plugin-commonjs": "^28.0.6", // Rollup CommonJS 插件
    "@rollup/plugin-node-resolve": "^16.0.1", // Rollup 解析 node_modules
    "@rollup/plugin-typescript": "^12.1.4", // Rollup TypeScript 插件
    "rimraf": "^6.0.1",                 // 跨平台删除 dist
    "rollup": "^2.79.2",                // 打包工具
    "rollup-plugin-terser": "^7.0.2",   // 代码压缩插件
    "typescript": "^5.8.3"              // TypeScript 编译器
  },
  "dependencies": {                      // 产物运行时需要的依赖
    "core-js": "^3.43.0",               // polyfill 运行时,Babel 注入新语法补丁
    "regenerator-runtime": "^0.14.1",   // async/await、generator 支持
    "tslib": "^2.8.1"                   // TypeScript 辅助库,importHelpers:true 时用
  }
}

重点说明:

  • devDependencies 只在开发/打包时用,用户用你的包时不需要。
  • dependencies 是产物运行时必须的,用户用你的包时会自动安装。
  • core-jsregenerator-runtimetslib 必须放 dependencies,否则用户运行时会缺包。

2. .babelrc 详细说明

json 复制代码
{
  "presets": [
    [
      "@babel/preset-env",              // Babel 预设,转译新 JS 语法
      {
        "modules": false,               // 不转译模块语法,交给 Rollup 处理
        "useBuiltIns": "usage",         // 按需注入 polyfill(只补你用到的特性)
        "corejs": 3,                     // 使用 core-js v3 作为 polyfill 源
        "targets": {                     // 指定要兼容的目标环境
          "browsers": ["> 1%", "last 2 versions", "not dead"], // 主流现代浏览器
          "node": "12"                  // Node.js 12 及以上
        }
      }
    ],
    "@babel/preset-typescript"           // 支持 TypeScript 语法
  ]
}

重点说明:

  • Babel 会自动分析源码用到了哪些新语法,只注入需要的 polyfill,产物更小。
  • modules: false 让 Rollup 负责模块打包,避免重复处理。
  • corejs: 3 指定 polyfill 版本,和 package.json 里的 core-js 保持一致。
  • targets 字段决定 Babel 会把代码降级到什么标准,本配置兼容主流现代浏览器和 Node.js 12+ ,可根据实际需求调整。
    • 目标环境越新,Babel 注入的降级代码(polyfill 和语法转换)就越少,产物体积更小,运行效率更高。
    • 目标环境越老,兼容代码越多,产物体积会变大,但兼容性更好。
    • 推荐根据你的实际用户环境合理设置 targets,既保证兼容性又优化产物体积。

3. tsconfig.json 详细说明

json 复制代码
{
  "compilerOptions": {
    "target": "ESNext",                 // 输出 JS 目标版本,交给 Babel/Rollup 再降级
    "module": "ESNext",                 // 输出模块格式,交给 Rollup 处理
    "declaration": true,                 // 生成 .d.ts 类型声明文件
    "declarationDir": "dist/types",     // 类型声明输出目录
    "outDir": "dist",                   // 编译后 JS 输出目录
    "rootDir": "src",                   // 源码根目录
    "strict": true,                      // 开启所有严格类型检查
    "esModuleInterop": true,             // 允许默认导入非 esModule 的模块
    "moduleResolution": "node",         // 按 node 方式解析模块
    "forceConsistentCasingInFileNames": true, // 文件名大小写一致性检查
    "skipLibCheck": true,                // 跳过依赖库类型检查,加快编译
    "importHelpers": true,                // 辅助函数用 tslib 引入,产物更小
    "resolveJsonModule": true             // 允许直接 import JSON 文件(如 package.json)
  },
  "include": ["src"],                   // 只编译 src 目录
  "exclude": ["node_modules", "dist"]  // 排除 node_modules 和 dist
}

重点说明:

  • importHelpers: true 让 TypeScript 产物更小,需配合 dependencies 里的 tslib。
  • resolveJsonModule: true 让 TypeScript 支持 import { version } from '../package.json' 这种写法,常用于在代码中读取版本号等信息。
  • 其它配置保证类型安全、兼容性和产物结构清晰。

4. rollup.config.js 详细说明

js 复制代码
import typescript from '@rollup/plugin-typescript';      // 支持 TS 编译
import { terser } from 'rollup-plugin-terser';           // 产物压缩
import babel from '@rollup/plugin-babel';                // Babel 转译
import resolve from '@rollup/plugin-node-resolve';       // 解析 node_modules
import commonjs from '@rollup/plugin-commonjs';          // 支持 CommonJS 依赖
import json from '@rollup/plugin-json';                  // 支持 import JSON 文件

export default [
  {
    input: 'src/index.ts',                               // 入口文件
    output: [
      {
        file: 'dist/index.cjs.js',                      // CommonJS 产物
        format: 'cjs',
        sourcemap: true,                                 // 生成 sourcemap 方便调试
        exports: 'named',
      },
      {
        file: 'dist/index.esm.js',                      // ESModule 产物
        format: 'esm',
        sourcemap: true,
      },
      {
        file: 'dist/index.umd.js',                      // UMD 产物,浏览器/Node 通用
        format: 'umd',
        name: 'FXUtils',                                 // 浏览器全局变量名 window.FXUtils
        sourcemap: true,
        exports: 'named',
      },
    ],
    plugins: [
      json(),                                               // 必须放在最前面,确保 JSON 能被正确处理
      resolve(),                                        // 先解析 node_modules
      commonjs(),                                       // 再转 CommonJS
      typescript({
        tsconfig: './tsconfig.json',
        declaration: true,
        declarationDir: 'dist/types',
        rootDir: 'src',
      }),
      babel({
        babelHelpers: 'bundled',                        // Babel 辅助函数打包进产物
        extensions: ['.js', '.ts'],
        include: ['src/**/*'],
      }),
      terser(),                                         // 压缩产物
    ],
    external: undefined,                                // 不 external 任何依赖,全部打包进产物
  },
];

重点说明:

  • 插件顺序很重要:先 json,再 resolve,再 commonjs,再 typescript,再 babel,最后 terser。
  • external: undefined,确保所有依赖都被打包进产物,浏览器可直接用。
  • 输出三种格式,兼容 Node、现代打包工具和浏览器。
  • @rollup/plugin-json 插件让你可以在源码中 import JSON 文件(如 package.json),并在打包时自动内联到产物中。
  • 常用于库/工具包自动读取自身版本号等信息。

5. 打包流程详细说明

  1. 清理 dist 目录
    • 通过 rimraf 删除 dist,保证每次打包都是全新产物。
  2. TypeScript 编译
    • @rollup/plugin-typescript 读取 tsconfig.json,把 src 里的 TS 源码编译成 JS,并生成类型声明(.d.ts)。
    • 如果用到 TS 辅助函数(如 __extends),会 import 'tslib'。
  3. Babel 转译和 polyfill 注入
    • @rollup/plugin-babel 读取 .babelrc,把 JS 代码降级为兼容老环境的 JS,并按需注入 core-js polyfill。
    • 只补充你实际用到的新语法,产物更小。
  4. 依赖解析与 CommonJS 转换
    • @rollup/plugin-node-resolve 让 Rollup 能找到 node_modules 里的依赖。
    • @rollup/plugin-commonjs 把 core-js 等 CommonJS 依赖转成 ESModule,方便 Rollup 合并。
  5. 产物压缩
    • rollup-plugin-terser 压缩最终 JS 文件,减小体积。
  6. 输出多格式产物
    • 输出 CJS(Node)、ESM(现代打包工具)、UMD(浏览器/Node 通用)三种格式,满足各种使用场景。
  7. 类型声明输出
    • 所有导出函数的类型声明会输出到 dist/types 目录,方便 TS 用户获得类型提示。

6. 总结

  • 本项目配置适合新手学习和实际生产使用。
  • 每个配置项都为产物兼容性、体积、类型安全和易用性服务。
  • 如需扩展工具函数,直接在 src/utils/ 下添加并在 index.ts 导出即可。
  • 有任何配置相关问题,欢迎随时提问!

主要工具函数说明

add(a: number, b: number): number

加法工具,返回 a + b。

div(a: number, b: number): number

减法工具,返回 a - b。

log(args: Log): void

打印对象,参数类型:

ts 复制代码
export interface Log {
  a: number;
  b: string;
  c: boolean;
}

sortPlusUtil(arr, fieldConfigs, _sortConfig)

多字段智能排序工具,支持数字、中文、英文、日期、区间、版本号等多类型混排。

  • arr: 需要排序的对象数组
  • fieldConfigs: 字段及排序方式配置
  • _sortConfig: 可选,权重与正则自定义

类型声明

  • 所有工具函数均有完整类型声明,位于 dist/types/ 目录。
  • 例如 sortPlusUtil 类型:
ts 复制代码
declare function sortPlusUtil(arr?: AnyObject[], fieldConfigs?: FieldConfig[], _sortConfig?: Partial<SortConfig>): void;

浏览器使用

  • 直接在 html 中引入 UMD 产物:
html 复制代码
<script src="dist/index.umd.js"></script>
<script>
  const { add, log, div, sortPlusUtil } = FXUtils;
  log({ a: 1, b: 'test', c: true });
  console.log(add(1, 2));
</script>

常用命令

  • yarn buildnpm run build:打包产物到 dist/
  • npm publish:发布到 npm
  • 其它 npm 相关命令见 文档.txt

其它说明

  • 支持 polyfill,兼容老浏览器和 Node 环境。
  • 产物自包含,无 require 依赖,浏览器可直接用。
  • 如需扩展工具函数,直接在 src/utils/ 下添加并在 index.ts 导出即可。

主要类型导出与使用说明

如何在其他项目中导入 OrderProp 类型?

本库已将 OrderProp 类型通过 export 导出,并在主入口 re-export,方便外部项目直接导入类型。

1. 类型声明与 re-export 实现

src/utils/sortPlusUtil.ts 中:

ts 复制代码
export type OrderProp = 'asc' | 'desc';

src/index.ts 主入口中:

ts 复制代码
export type { OrderProp } from './utils/sortPlusUtil';
2. 用户在其他项目中的用法
ts 复制代码
import type { OrderProp } from '@fuxing666/fxutils';

这样即可获得类型提示和类型安全。

===================

src/index.ts 代码

js 复制代码
import add from "./utils/add";
import div from "./utils/div";
import log from "./utils/log";
import sortPlusUtil from "./utils/sortPlusUtil";

// // Polyfill 测试代码
// const arr = [1, 2, 3];
// console.log('includes:', arr.includes(2)); // 需要 polyfill

// Promise.resolve(1).finally(() => {
//   console.log('Promise finally polyfill test');
// });

export { add, log, div,sortPlusUtil };
 

export default {
  add,
  log,
  div,
  sortPlusUtil
};

export type { OrderProp } from './utils/sortPlusUtil';

===================

package.json 代码

js 复制代码
{
  "name": "@fuxing666/fxutils",
  "version": "2.1.2",
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "types": "dist/types/index.d.ts",
  "scripts": {
    "build": "rimraf dist && rollup -c"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "@babel/core": "^7.28.0",
    "@babel/preset-env": "^7.28.0",
    "@babel/preset-typescript": "^7.27.1",
    "@rollup/plugin-babel": "^6.0.4",
    "@rollup/plugin-commonjs": "^28.0.6",
    "@rollup/plugin-json": "^6.1.0",
    "@rollup/plugin-node-resolve": "^16.0.1",
    "@rollup/plugin-typescript": "^12.1.4",
    "rimraf": "^6.0.1",
    "rollup": "^2.79.2",
    "rollup-plugin-terser": "^7.0.2",
    "typescript": "^5.8.3"
  },
  "dependencies": {
    "core-js": "^3.43.0",
    "regenerator-runtime": "^0.14.1",
    "tslib": "^2.8.1"
  }
}

===================

rollup.config.js 代码

js 复制代码
import typescript from '@rollup/plugin-typescript';
import { terser } from 'rollup-plugin-terser';
import babel from '@rollup/plugin-babel';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';

export default [
  {
    input: 'src/index.ts',
    output: [
      {
        file: 'dist/index.cjs.js',
        format: 'cjs',
        sourcemap: true,
        exports: 'named',
      },
      {
        file: 'dist/index.esm.js',
        format: 'esm',
        sourcemap: true,
      },
      {
        file: 'dist/index.umd.js',
        format: 'umd',
        name: 'FXUtils',
        sourcemap: true,
        exports: 'named',
      },
    ],
    plugins: [
      json(),
      resolve(),
      commonjs(),
      typescript({
        tsconfig: './tsconfig.json',
        declaration: true,
        declarationDir: 'dist/types',
        rootDir: 'src',
      }),
      babel({
        babelHelpers: 'bundled',
        extensions: ['.js', '.ts'],
        include: ['src/**/*'],
      }),
      terser(),
    ],
    external: undefined, // 不 external 任何依赖,全部打包进产物
  },
]; 

===================

tsconfig.json 代码

js 复制代码
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "ESNext",
    "declaration": true,
    "declarationDir": "dist/types",
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true,
    "moduleResolution": "node",
    "forceConsistentCasingInFileNames": true,
    "skipLibCheck": true,
    "importHelpers": true,
    "resolveJsonModule": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
} 

===================

.babelrc 代码

js 复制代码
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "useBuiltIns": "usage",
        "corejs": 3,
        "targets": {
          "browsers": ["> 1%", "last 2 versions", "not dead"],
          "node": "12"
        }
      }
    ],
    "@babel/preset-typescript"
  ]
} 
相关推荐
半点寒12W24 分钟前
微信小程序实现路由拦截的方法
前端
某公司摸鱼前端1 小时前
uniapp socket 封装 (可拿去直接用)
前端·javascript·websocket·uni-app
要加油哦~1 小时前
vue | 插件 | 移动文件的插件 —— move-file-cli 插件 的安装与使用
前端·javascript·vue.js
小林学习编程1 小时前
Springboot + vue + uni-app小程序web端全套家具商场
前端·vue.js·spring boot
柳鲲鹏1 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
weixin-a153003083162 小时前
【playwright篇】教程(十七)[html元素知识]
java·前端·html
ai小鬼头3 小时前
AIStarter最新版怎么卸载AI项目?一键删除操作指南(附路径设置技巧)
前端·后端·github
一只叫煤球的猫4 小时前
普通程序员,从开发到管理岗,为什么我越升职越痛苦?
前端·后端·全栈
vvilkim4 小时前
Electron 自动更新机制详解:实现无缝应用升级
前端·javascript·electron
vvilkim4 小时前
Electron 应用中的内容安全策略 (CSP) 全面指南
前端·javascript·electron