从零开始:构建并发布你的 npm 工具库及文档网站
在日常的前端开发中,经常会遇到文本处理,日期处理,文本转换等需求。通常是将它写到一个utils
文件中。问题来了,每个项目都要处理,那么文件就要重复的复制,我是个懒人。想着用rollup
将它打包成一个 npm 插件,然后直接安装,之后局部引入来。这样就方便了,同时也只需要我需要的插件。这样一来随着工具函数的扩展,势必会带来一个问题,如何维护函数的使用呢?那么就需要一个文档了,文档的便于管理也是个问题,这里采用vitepess
来作为工具函数的文档官网。
npm 插件包构建
这里我根据个人需求采用的是rollup
作为插件的打包工具。
说一下我选择它的原因:
- 我的插件是纯工具函数,所以不需要 html 的渲染,那么
vite
就不在我的考虑,vite 主要还是应用在界面插件的开发上,会比较好一点, rollup
使用了 ES6 修订版JavaScript
中包含的代码模块的新标准化格式,而不是以前的特定解决方案,如CommonJS
和AMD
。这意味着可以自由无缝地组合你最喜欢的库中最有用的单个函数。实现局部加载的功能。Tree-Shaking
会静态分析您导入的代码,并排除任何未实际使用的内容**。**
步骤 1: 初始化项目
-
创建项目目录
mkdir my-rollup-package cd my-rollup-package
-
初始化项目
初始化一个新的 npm 项目,这将会生成一个package.json
文件:pnpm init -y
-
安装开发依赖
安装 Rollup 和所需的插件:pnpm install --save-dev rollup rollup-plugin-typescript2 @rollup/plugin-commonjs @rollup/plugin-babel @rollup/plugin-node-resolve rollup-plugin-node-globals rollup-plugin-node-builtins @rollup/plugin-terser @rollup/plugin-json rollup-plugin-dts rollup-plugin-import-export typescript @types/node
- rollup:核心打包工具。
- rollup-plugin-typescript2:处理 TypeScript 文件。
- @rollup/plugin-commonjs:将 CommonJS 转换为 ES6。
- @rollup/plugin-babel:使用 Babel 转译代码。
- @rollup/plugin-node-resolve:解析模块。
- rollup-plugin-node-globals:处理 Node.js 的全局变量。
- rollup-plugin-node-builtins:处理 Node.js 的内置模块。
- @rollup/plugin-terser:压缩代码。
- @rollup/plugin-json:导入 JSON 文件。
- rollup-plugin-dts:生成 TypeScript 声明文件。
- typescript:安装 TypeScript。
- @types/node: types 声明文件
-
配置 TypeScript
添加tsconfig.json
来配置 TypeScript:{ "compilerOptions": { "allowJs": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "node", "noEmit": true, "resolveJsonModule": true, "forceConsistentCasingInFileNames": true, "sourceMap": true, "strict": true, "target": "esnext", "isolatedModules": true, "useDefineForClassFields": true, "jsx": "preserve", "lib": ["esnext", "dom"], "baseUrl": ".", "paths": { "@/*": ["src/*"] } }, "exclude": ["dist", "node_modules"] }
步骤 2: 项目结构
创建项目文件夹和文件结构:
my-rollup-package/
└── src/
│ └── modules/ (工具函数文件)
│ │ └── hello.ts
│ └── index.ts (入口文件改成全体导出)
│ └── iem.d.ts (这个文件是方便导入)
└── dist/ (将会生成)
└── package.json
└── rollup.config.js
└── tsconfig.json
- src/index.ts 是你的主文件,它将包含你的主要代码。
步骤 3: 编写代码
在 src/modules/hello.ts
中添加一些简单的代码,例如一个简单的工具函数
export function greet(name: string): string {
return `Hello, ${name}!`;
}
在 src/iem.d.ts
中导人所有的函数
declare module "iem:./modules/*" {
export {};
}
- 告诉 TypeScript,所有匹配
"iem:./modules/*"
模式的导入都是有效的模块。 - 使用空的导出 (
export {}
) 来表示这些模块不导出任何内容。 - 主要目的是让 TypeScript 理解那些通过自定义加载器或者特殊路径的模块,以确保项目正常编译,特别是在集成非标准模块加载或路径时。
在 src/index.ts
导出所有的工具函数
export * from "iem:./modules/**/*";
步骤 4: 配置 Rollup
创建一个名为 rollup.config.js
的文件,并粘贴给出的配置代码:
import { defineConfig } from "rollup"; // 从 rollup 导入 defineConfig 函数,用于定义配置
import ts from "rollup-plugin-typescript2"; // 导入 TypeScript 插件,用于编译 TypeScript 文件
import commonjs from "@rollup/plugin-commonjs"; // 导入 CommonJS 插件,将 CommonJS 模块转换为 ES6
import babelPlugin from "@rollup/plugin-babel"; // 导入 Babel 插件,用于转译代码
import resolve from "@rollup/plugin-node-resolve"; // 导入 Node.js 解析插件,用于解析模块
import globals from "rollup-plugin-node-globals"; // 导入插件以处理 Node.js 全局变量
import builtins from "rollup-plugin-node-builtins"; // 导入插件以处理 Node.js 内置模块
import terser from "@rollup/plugin-terser"; // 导入 Terser 插件,用于压缩 JavaScript 代码
import json from "@rollup/plugin-json"; // 导入 JSON 插件,用于导入 JSON 文件
import dts from "rollup-plugin-dts"; // 导入 DTS 插件,用于生成 TypeScript 声明文件
import { importExportPlugin } from "rollup-plugin-import-export"; // 导入自定义插件,用于处理导入和导出
// 定义 Rollup 配置
const config = defineConfig([
{
input: ["src/index.ts"], // 输入文件为 src/index.ts
output: [
{
dir: "dist/esm", // 输出目录为 dist/esm
format: "esm", // 输出格式为 ES Module
preserveModules: true, // 保持模块结构
},
{
dir: "dist/cjs", // 输出目录为 dist/cjs
format: "cjs", // 输出格式为 CommonJS
preserveModules: true, // 保持模块结构
},
],
plugins: [
importExportPlugin(), // 使用自定义导入导出插件
ts(), // 添加 TypeScript 插件
babelPlugin({ exclude: "**/node_modules/**" }), // 添加 Babel 插件,排除 node_modules
json(), // 添加 JSON 插件
commonjs(), // 添加 CommonJS 插件
],
},
{
input: "src/index.ts", // 再次使用 src/index.ts 作为输入
output: [
{
file: "dist/umd/index.js", // 输出文件为 dist/umd/index.js
format: "umd", // 输出格式为 UMD
name: "utils", // UMD 格式时的全局变量名
},
],
plugins: [
importExportPlugin(), // 使用自定义导入导出插件
ts(), // 添加 TypeScript 插件
babelPlugin({ exclude: "**/node_modules/**" }), // 添加 Babel 插件,排除 node_modules
json(), // 添加 JSON 插件
commonjs(), // 添加 CommonJS 插件
resolve({ preferBuiltins: true, mainFields: ["browser"] }), // 添加解析插件,优先使用内置模块
globals(), // 添加全局变量插件
builtins(), // 添加内置模块插件
terser(), // 添加压缩插件
],
},
{
input: "src/index.ts", // 输入文件为 src/index.ts
output: {
dir: "dist/types", // 输出目录为 dist/types
format: "esm", // 输出格式为 ES Module
preserveModules: true, // 保持模块结构
},
plugins: [importExportPlugin(), dts()], // 使用自定义插件和 DTS 插件生成声明文件
},
]);
export default config; // 导出配置
步骤 5: 添加打包脚本
打开 package.json
,并添加 scripts
部分来配置打包命令:
json
复制代码
"scripts": {
"build": "rollup -c",
"build:watch": "rollup -c -w"
}
- build:执行打包。
- build:watch:监视文件变化并实时打包。
步骤 6: 打包项目
运行以下命令以打包你的项目:
pnpm run build
这将会生成以下文件和目录:
- dist/esm:包含 ES Module 格式的代码。
- dist/cjs:包含 CommonJS 格式的代码。
- dist/umd/index.js:包含 UMD 格式的代码,可以用于浏览器和 Node.js。
- dist/types:包含 TypeScript 的声明文件(
.d.ts
文件)。
步骤 7: 测试生成的 npm 包
你可以创建一个 test
目录来测试生成的包:
- 创建测试目录
mkdir test cd test
- 编写测试代码
在test
目录中创建一个 JavaScript 或 TypeScript 文件来测试该包,例如hello.test.ts
:import { describe, it, expect } from "vitest"; import { greet } from "../src/modules/hello"; describe("hello", () => { it("greet", () => { expect(greet("david")).toMatchInlineSnapshot(`"Hello, david!"`); }); });
- 添加测试脚本
在 package.json 文件中添加如下内容...... "scripts": { "test": "vitest", }, ......
运行测试
pnpm run test
添加 Vitepess 文档插件
使用官网的单独安装指令
pnpm add -D vitepress
由于 vitepess
和 rollup
其实是分开的,无所谓先后安装的顺序,你也可以使用vitepess
官网的向导安装指令
-
在文件中建立如下目录
my-rollup-package/ ├─ docs │ ├─ .vitepress │ │ └─ config.js (配置文件主题之类的设置) │ ├─ api-examples.md │ ├─ markdown-examples.md │ └─ index.md └─ package.json
-
启动并运行
将以下 npm 脚本注入到package.json
中:{ ... "scripts": { "docs:dev": "vitepress dev docs", "docs:build": "vitepress build docs", "docs:preview": "vitepress preview docs" }, ... }
docs:dev
脚本将启动具有即时热更新的本地开发服务器。使用以下命令运行它:pnpm run docs:dev
基本配置到这里就结束了,更多关于 vitepress 的用法关注官网