工具库:RollupTsUtils 指南
概览
本文将引导您从零开始构建一个高效、现代的 JavaScript 工具库——RollupTsUtils。这个库将集成 TypeScript 的类型安全、Rollup 的模块打包能力,以及多种工具以确保代码质量、自动化测试和文档生成。
特性概览
- TypeScript 支持:利用 TypeScript 提供的静态类型检查,提升代码质量和开发体验。
- 模块化设计:通过 Rollup 支持多种模块格式,包括 CommonJS、ES modules 和 UMD。
- 跨平台兼容性:使用 Babel 确保代码在不同环境中的兼容性。
- 代码质量保障:集成 ESLint 和 Prettier,统一代码风格和质量标准。
- 自动化测试:采用 Jest 进行单元测试,确保功能的正确性和稳定性。
- 版本控制工作流:通过 Commitlint 和 Husky 规范提交信息和自动化代码检查。
- 文档自动生成:使用 VitePress 生成清晰、易于维护的文档。
- 持续集成/持续部署(CI/CD):配置自动化的构建和发布流程。
- 高效的包管理:使用 pnpm 作为包管理器,提高依赖安装效率和磁盘空间利用率。
项目初始化
项目初始化是成功构建项目的基础。本节将介绍如何创建项目结构、初始化包管理器和设置版本控制。
创建项目目录
首先,创建一个新的目录来存放项目:
mkdir RollupTsUtils
cd RollupTsUtils
初始化 pnpm 项目
选择 pnpm 作为包管理器,因其安装速度快且磁盘空间利用率高:
pnpm init
编辑生成的 package.json
文件,添加必要的信息:
{
"name": "rollup-ts-utils",
"version": "0.1.0",
"description": "A modern JavaScript utility library built with Rollup and TypeScript",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": ["utils", "typescript", "rollup"],
"author": "Your Name",
"license": "MIT"
}
设置 .gitignore 文件
创建 .gitignore
文件以指定 Git 忽略的文件和目录:
touch .gitignore
编辑 .gitignore
文件,添加以下内容:
# Dependencies
node_modules/
# Build output
dist/
# IDE and editor files
.vscode/
.idea/
*.swp
*.swo
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Operating System Files
.DS_Store
Thumbs.db
# Test coverage
coverage/
# Temporary files
*.tmp
*.temp
# Environment variables
.env
.env.local
.env.*.local
初始化 Git 仓库
初始化 Git 仓库并创建第一个提交:
git init
git add .
git commit -m "Initial commit: Project setup"
创建基本目录结构
为项目创建基本的目录结构:
mkdir src tests docs
src
:存放源代码tests
:存放测试文件docs
:存放文档
创建初始源文件
在 src
目录中创建一个初始的入口文件:
echo "// RollupTsUtils main entry point" > src/index.ts
安装基本开发依赖
安装 TypeScript 和类型定义作为开发依赖:
pnpm add -D typescript @types/node
至此,我们已经完成了 RollupTsUtils 项目的基本初始化,为后续开发奠定了基础。
在接下来的部分中,我们将深入探讨如何配置 TypeScript,以利用其静态类型检查的优势,提高代码质量和开发效率。
配置 TypeScript
TypeScript 为 JavaScript 添加了可选的静态类型和基于类的面向对象编程特性,显著提升代码质量和可维护性。本节将介绍如何为 RollupTsUtils 项目设置 TypeScript。
安装 TypeScript
确保安装了 TypeScript:
pnpm add -D typescript @types/node
创建 TypeScript 配置文件
创建 tsconfig.json
文件以配置 TypeScript 编译器选项:
npx tsc --init
根据项目需求修改生成的 tsconfig.json
文件:
{
"compilerOptions": {
"target": "ES2018",
"module": "esnext",
"lib": ["DOM", "ES2018", "ESNext"],
"outDir": "./dist",
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationDir": "./dist",
"sourceMap": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"removeComments": false,
"preserveConstEnums": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist",
"**/*.test.ts"
]
}
这些配置选项的意义如下:
target
:指定 ECMAScript 目标版本。module
:指定生成的模块系统代码类型。lib
:指定需要包含的库文件。outDir
:指定输出目录。strict
:启用所有严格类型检查选项。moduleResolution
:决定如何处理模块。esModuleInterop
:启用 CommonJS 和 ES 模块之间的互操作性。declaration
:生成相应的.d.ts
文件。sourceMap
:生成相应的.map
文件。noUnusedLocals
和noUnusedParameters
:报告未使用的局部变量和参数。include
和exclude
:指定哪些文件应被 TypeScript 编译器处理或忽略。
更新 package.json
在 package.json
文件中添加 TypeScript 相关脚本:
"scripts": {
"type-check": "tsc --noEmit",
}
这些脚本将用于:
- 运行类型检查而不生成文件。
- 只生成类型声明文件。
- 使用 Rollup 构建 JavaScript 文件(后续步骤中配置)。
创建示例 TypeScript 文件
在 src
目录中创建 math.ts
:
export function add(a: number, b: number): number {
return a + b;
}
export function subtract(a: number, b: number): number {
return a - b;
}
export function multiply(a: number, b: number): number {
return a * b;
}
export function divide(a: number, b: number): number {
return a / b;
}
修改 src/index.ts
以导出:
export * from './math';
运行类型检查
运行类型检查以确保一切正常:
pnpm run type-check
如果没有错误,说明 TypeScript 配置正确。
接下来,我们将设置 Rollup 来处理项目的构建过程,这将使我们能够将 TypeScript 代码编译成各种模块格式的 JavaScript。
配置 Rollup
Rollup 是一个高效的 JavaScript 模块打包器,特别适合库和工具的构建。本节将介绍如何为 RollupTsUtils 配置 Rollup。
安装 Rollup 及相关插件
首先,安装 Rollup 和相关插件:
pnpm add -D rollup @rollup/plugin-typescript tslib @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-json @rollup/plugin-terser rollup-plugin-dts
这些插件的作用如下:
@rollup/plugin-typescript
:使 Rollup 能够处理 TypeScript 文件。@rollup/plugin-node-resolve
:允许 Rollup 查找外部模块。@rollup/plugin-commonjs
:将 CommonJS 模块转换为 ES6。@rollup/plugin-json
:允许 Rollup 导入 JSON 文件。@rollup/plugin-terser
:压缩输出的 JavaScript。rollup-plugin-dts
:生成 TypeScript 声明文件(.d.ts)。
创建 Rollup 配置文件
创建 rollup.config.base.mjs
:
import typescript from '@rollup/plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import dts from 'rollup-plugin-dts';
import replace from '@rollup/plugin-replace';
const isProduction = !process.env.ROLLUP_WATCH;
export const baseConfig = {
input: 'src/index.ts',
plugins: [
resolve(),
commonjs(),
typescript({
declaration: false,
}),
json(),
replace({
'process.env.NODE_ENV': JSON.stringify(isProduction ? 'production' : 'development'),
preventAssignment: true,
}),
],
};
export const dtsConfig = {
input: 'src/index.ts',
output: [{ file: 'dist/index.d.ts', format: 'es' }],
plugins: [dts()],
};
创建 rollup.config.prod.mjs
:
import terser from '@rollup/plugin-terser';
import { baseConfig, dtsConfig } from './rollup.config.base.mjs';
const packageName = 'rollupTsUtils';
const productionConfig = {
...baseConfig,
output: [
{
file: 'dist/index.js',
format: 'cjs',
},
{
file: 'dist/index.esm.js',
format: 'es',
},
{
file: 'dist/index.umd.js',
format: 'umd',
sourcemap: true,
name: packageName,
globals: {
// 如果你的库依赖其他全局变量,在这里定义它们
'@babel/runtime-corejs3/regenerator': 'regeneratorRuntime',
'@babel/runtime-corejs3/helpers/asyncToGenerator': 'asyncToGenerator',
'@babel/runtime-corejs3/core-js-stable/promise': 'Promise',
},
},
],
plugins: [...baseConfig.plugins, terser()],
};
export default [productionConfig, dtsConfig];
配置构建脚本
在 package.json
文件中添加以下脚本:
"scripts": {
"build": "npm run clean && rollup -c rollup.config.prod.mjs",
"clean": "rm -rf dist",
"type-check": "tsc --noEmit",
"prepublishOnly": "pnpm run build"
}
完善开发环境
为了提供更好的开发体验,我们将进一步完善开发环境的设置。
新增 rollup.config.dev.mjs
import serve from 'rollup-plugin-serve';
import livereload from 'rollup-plugin-livereload';
import { baseConfig } from './rollup.config.base.mjs';
const packageName = 'rollupTsUtils';
const devConfig = {
input: baseConfig.input,
output: {
file: 'dev/bundle.js',
format: 'iife',
name: packageName,
sourcemap: true,
},
plugins: [
...baseConfig.plugins,
serve({
contentBase: ['dev'],
open: true,
port: 3000,
}),
livereload({
watch: ['dev'],
}),
],
};
export default devConfig;
在开发环境中:
- 添加了
@rollup/plugin-replace
插件,用于在构建时替换环境变量。 - 添加了
rollup-plugin-serve
和rollup-plugin-livereload
插件。 - 为开发构建创建了单独的
devConfig
对象。
创建开发环境入口文件
在 dev
目录中创建一个更完善的 index.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>RollupTsUtils Dev</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
padding: 20px;
}
h1 {
color: #333;
}
#output {
background-color: #f4f4f4;
padding: 10px;
border-radius: 5px;
}
</style>
</head>
<body>
<h1>RollupTsUtils Development</h1>
<div id="output"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.12.1/polyfill.min.js"></script>
<script src="bundle.js"></script>
<script>
// 示例:使用库中的函数
document.addEventListener("DOMContentLoaded", () => {
const outputDiv = document.getElementById("output");
if (window.rollupTsUtils) {
outputDiv.textContent = "1 + 2 = " + window.rollupTsUtils.add(1, 2);
console.log(window.rollupTsUtils.asyncFunction());
}
});
</script>
</body>
</html>
更新 package.json 中的开发脚本
"scripts": {
"dev": "rollup -c rollup.config.dev.mjs",
}
现在,您可以使用以下命令启动开发环境:
pnpm run dev
这将启动 Rollup 的监视模式和开发服务器。您可以在浏览器中打开 http://localhost:3000
来查看结果。
接下来,我们将配置 Babel,这是现代 JavaScript 开发中非常重要的一部分。Babel 允许我们使用最新的 JavaScript 特性,同时确保代码能在各种环境中运行。
完善 Babel 配置
安装 Babel 及相关预设
首先,安装 Babel 和相关的预设及插件:
pnpm add -D @babel/core @babel/preset-env @babel/preset-typescript @babel/plugin-transform-runtime
pnpm add @babel/runtime
这些包的作用如下:
@babel/core
:Babel 的核心功能。@babel/preset-env
:智能预设,根据目标环境自动确定需要的 Babel 插件和 polyfills。@babel/preset-typescript
:用于转换 TypeScript 代码。@babel/plugin-transform-runtime
:用于优化 Babel 辅助代码,减少代码体积。@babel/runtime
:包含 Babel 模块化运行时助手,是@babel/plugin-transform-runtime
的依赖。
创建并解释 babel.config.js
在项目根目录创建 babel.config.js
文件:
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: '12',
browsers: ['>0.25%, last 2 versions'],
},
useBuiltIns: 'usage',
corejs: 3,
},
],
'@babel/preset-typescript',
],
plugins: [
[
'@babel/plugin-transform-runtime',
{
corejs: 3,
},
],
],
env: {
test: {
presets: [
[
'@babel/preset-env',
{
targets: { node: 'current' },
},
],
],
},
},
};
这个配置的详细解释如下:
-
presets
:@babel/preset-env
:targets
:指定目标环境。这里我们设置了 Node.js 12+ 和覆盖全球超过 0.25% 使用率的浏览器。modules: false
:保留 ES 模块语法,让 Rollup 来处理模块。useBuiltIns: 'usage'
:根据实际代码使用情况和目标环境自动添加 polyfills。corejs: 3
:使用 core-js 3 版本来提供 polyfills。
@babel/preset-typescript
:用于处理 TypeScript 代码。
-
plugins
:@babel/plugin-transform-runtime
:- 提取 Babel 辅助函数,避免重复注入,减小打包体积。
corejs: 3
:使用 core-js 3 版本的运行时助手。
-
env
:test
:为测试环境提供特定配置,使用当前 Node.js 版本作为目标,这对于使用 Jest 等测试框架很有用。
更新 rollup.config.base.mjs
确保 Rollup 配置正确使用 Babel。更新 rollup.config.mjs
中的 Babel 插件配置:
// 在 import 语句部分
import { babel } from '@rollup/plugin-babel';
// 在 plugins 数组中
babel({
babelHelpers: 'runtime',
exclude: 'node_modules/**',
extensions: ['.js', '.ts'],
}),
这里的 babelHelpers: 'runtime'
选项与我们使用的 @babel/plugin-transform-runtime
插件配合使用。
接下来,我们将设置代码质量工具,包括 ESLint 和 Prettier,以确保代码风格和质量的一致性。
代码质量工具
设置 ESLint
ESLint 是一个强大的静态代码分析工具,用于识别和报告 JavaScript/TypeScript 代码中的模式。
安装 ESLint 及相关插件
运行以下命令安装 ESLint 及其相关插件:
bash
pnpm add -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-import eslint-config-airbnb-base eslint-config-airbnb-typescript
创建 ESLint 配置文件
在项目根目录创建 .eslintrc.js
文件:
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
],
plugins: ['@typescript-eslint', 'prettier'],
env: {
node: true,
es6: true,
},
parserOptions: {
ecmaVersion: 2018,
sourceType: 'module',
},
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
'no-console': 'warn',
},
};
这个配置:
- 使用
@typescript-eslint/parser
解析 TypeScript 代码。 - 采用 Airbnb 的基础规则集。
- 启用 TypeScript 特定的推荐规则。
- 自定义了一些规则,如关闭默认导出的强制要求。
添加 .eslintignore
文件:
node_modules
dist
dev
docs
设置 Prettier
Prettier 是一个代码格式化工具,可以确保团队中的所有代码遵循一致的样式。
安装 Prettier 及相关插件
运行以下命令:
pnpm add -D prettier eslint-config-prettier eslint-plugin-prettier
创建 Prettier 配置文件
在项目根目录创建 .prettierrc.js
文件:
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 100,
tabWidth: 2,
};
更新 ESLint 配置
更新 .eslintrc.js
文件以集成 Prettier:
module.exports = {
// ... 之前的配置
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier', // 添加这行
'plugin:prettier/recommended', // 添加这行
],
// ... 其余配置保持不变
};
配置 lint-staged 进行预提交检查
lint-staged 允许我们在 git 暂存区的文件上运行脚本,配合 husky 可以在提交前自动运行 linter。
安装 lint-staged 和 husky
pnpm add -D lint-staged husky
配置 husky
初始化 husky:
npx husky install
添加 pre-commit 钩子:
npx husky add .husky/pre-commit "npx lint-staged"
如果失败,执行:
echo "npx lint-staged" > .husky/pre-commit
配置 lint-staged
在 package.json
中添加 lint-staged 配置:
{
"lint-staged": {
"*.{js,ts}": [
"eslint --fix",
"prettier --write"
],
"*.{json,md}": [
"prettier --write"
]
}
}
更新 package.json 脚本
添加以下脚本到 package.json
:
{
"scripts": {
// ... 其他脚本
"lint": "eslint 'src/**/*.{js,ts}'",
"lint:fix": "eslint 'src/**/*.{js,ts}' --fix",
"format": "prettier --write 'src/**/*.{js,ts,json,md}'",
"prepare": "husky install"
}
}
集成到开发流程
- 运行
pnpm run lint
来检查代码风格。 - 运行
pnpm run lint:fix
来自动修复可以自动修复的问题。 - 运行
pnpm run format
来格式化代码。 - Git commit 前会自动运行 lint-staged,检查并格式化暂存的文件。
通过这些设置,我们实现了:
- 使用 ESLint 进行代码质量检查。
- 使用 Prettier 确保一致的代码格式。
- 通过 lint-staged 和 husky 在提交前自动运行检查和格式化。
这些工具共同工作,可以显著提高代码质量,减少因格式或常见错误导致的问题。在团队协作中,这些工具尤其重要,可以确保所有贡献者遵循相同的代码标准。
接下来,我们将设置版本控制工作流,包括 Commitlint 来规范化提交信息。
版本控制工作流
设置 Commitlint
Commitlint 用于检查提交信息是否符合预定义的格式,这有助于保持提交历史的清晰和一致。
安装 Commitlint
运行以下命令安装 Commitlint 及其配置:
pnpm add -D @commitlint/cli @commitlint/config-conventional
创建 Commitlint 配置文件
在项目根目录创建 commitlint.config.mjs
文件:
export default { extends: ['@commitlint/config-conventional'] };
这个配置使用了 conventional commit 规范,它定义了以下提交类型:
feat
:新功能。fix
:错误修复。docs
:文档更改。style
:不影响代码含义的更改(空白、格式化、缺少分号等)。refactor
:既不修复错误也不添加功能的代码更改。perf
:改进性能的代码更改。test
:添加缺失的测试或更正现有的测试。build
:影响构建系统或外部依赖项的更改。ci
:对 CI 配置文件和脚本的更改。chore
:其他不修改 src 或测试文件的更改。revert
:恢复之前的提交。
配置 Husky 钩子
我们已经在前面的步骤中安装了 Husky,现在我们将添加更多的 Git 钩子来集成 Commitlint。
添加 commit-msg 钩子
运行以下命令来添加 commit-msg 钩子:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
如果失败,执行:
echo 'npx --no -- commitlint --edit ${1}' > .husky/commit-msg
这将在提交消息创建后但提交完成之前运行 Commitlint。
配置 Conventional Commits 工具(可选)
为了更容易地创建符合规范的提交信息,我们可以使用 Conventional Commits 工具。
安装 commitizen
pnpm add -D commitizen cz-conventional-changelog
配置 commitizen
在 package.json
中添加以下配置:
{
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}
添加 npm 脚本
在 package.json
的 scripts
部分添加:
{
"scripts": {
// ... 其他脚本
"commit": "cz"
}
}
现在,开发者可以使用 pnpm run commit
来创建规范化的提交信息。
使用工作流
- 进行代码更改。
- 暂存更改:
git add .
- 提交更改:
- 使用
git commit -m "your message"
并遵循 conventional commit 格式。 - 或使用
pnpm run commit
通过交互式提示创建提交信息。
- 使用
- 如果提交消息不符合规范,Commitlint 将阻止提交并显示错误信息。
通过这些设置,我们实现了:
- 使用 Commitlint 强制执行一致的提交消息格式。
- 利用 Husky 在适当的 Git 钩子中运行必要的检查。
- (可选)使用 Commitizen 帮助创建规范的提交信息。
接下来,我们可以继续设置单元测试,确保代码的稳定性和可靠性。
单元测试
安装 Jest 和 ts-jest
首先,我们需要安装 Jest、ts-jest 以及相关的类型定义:
pnpm add -D jest @types/jest ts-jest
配置 Jest
创建一个 jest.config.js
文件在项目根目录下:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
collectCoverage: true,
coverageDirectory: 'coverage',
coveragePathIgnorePatterns: ['/node_modules/'],
};
这个配置的详细解释如下:
preset: 'ts-jest'
:使用 ts-jest 预设,允许 Jest 直接运行 TypeScript 测试文件。testEnvironment: 'node'
:指定测试环境为 Node.js。moduleFileExtensions
:指定 Jest 应该识别的文件扩展名。collectCoverage: true
:启用代码覆盖率收集。coverageDirectory: 'coverage'
:指定存放覆盖率报告的目录。coveragePathIgnorePatterns
:指定在收集覆盖率时要忽略的路径模式。
更新 package.json
在 package.json
中添加测试脚本:
"scripts": {
"test": "jest"
}
这样,您就可以通过运行 pnpm test
来执行测试了。
编写示例测试用例
在 tests
目录下创建一个 math.test.ts
文件:
// tests/math.test.ts
import { add, subtract } from '../src/math';
describe('Math functions', () => {
test('adds 1 + 2 to equal 3', () => {
expect(add(1, 2)).toBe(3);
});
test('subtracts 5 - 3 to equal 2', () => {
expect(subtract(5, 3)).toBe(2);
});
test('adds negative numbers', () => {
expect(add(-1, -2)).toBe(-3);
});
test('subtracts with negative result', () => {
expect(subtract(2, 5)).toBe(-3);
});
});
运行测试
现在,您可以运行 pnpm test
来执行测试。Jest 将运行所有测试文件并显示结果,包括通过/失败的测试数量和代码覆盖率报告。
通过这些设置,我们确保了代码的稳定性和可靠性,同时自动化测试流程也提高了开发效率。
接下来,我们将探讨如何生成文档,这对于维护和使用库至关重要。
文档生成
安装 VitePress
首先,我们需要安装 VitePress 作为开发依赖:
pnpm add -D vitepress
初始化 VitePress
在项目根目录下创建一个 docs
文件夹,这将是我们存放文档的地方:
npx vitepress init docs
这样就初始化了 VitePress 项目。
运行文档开发服务器
现在您可以通过以下命令启动文档开发服务器:
pnpm docs:dev
这将启动一个本地服务器,您可以在浏览器中预览文档。
构建文档
要构建生产版本的文档,运行:
pnpm docs:build
这将在 docs/.vitepress/dist
目录下生成静态 HTML 文件。
预览构建后的文档
要预览构建后的文档,运行:
pnpm docs:preview
部署文档
您可以将构建后的文档部署到静态网站托管服务,如 GitHub Pages、Netlify 或 Vercel。具体的部署步骤会根据您选择的平台而有所不同。
通过这些步骤,我们成功地为 RollupTsUtils 项目配置了文档生成和预览,这对于项目的维护和使用非常有帮助。
最后,我们将设置持续集成/持续部署(CI/CD),以自动化测试、构建和发布流程。
持续集成/持续部署(CI/CD)
创建 GitHub Actions 工作流文件
在您的项目根目录下创建 .github/workflows
目录,然后在其中创建一个名为 ci.yml
的文件:
mkdir -p .github/workflows
touch .github/workflows/ci.yml
配置 CI 工作流
编辑 ci.yml
文件,添加以下内容:
name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8.x
- name: Install dependencies
run: pnpm install
- name: Run linter
run: pnpm run lint
- name: Run tests
run: pnpm test
- name: Build
run: pnpm run build
publish:
needs: build
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- uses: actions/checkout@v3
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16.x'
registry-url: 'https://registry.npmjs.org'
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 6.0.2
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Publish to npm
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
这个工作流做了以下几件事:
- 在每次推送到
master
分支和创建 Pull Request 时触发。 - 在不同版本的 Node.js (18.x, 20.x) 上运行测试。
- 使用 pnpm 安装依赖。
- 运行 linter 检查代码质量。
- 运行测试。
- 构建项目。
- 如果所有检查都通过,并且是推送到
master
分支的事件,则发布到 npm。
设置 Secrets
为了能够发布到 npm,您需要在 GitHub 仓库中设置一个 secret:
- 去到您的 GitHub 仓库页面。
- 点击 "Settings" 标签。
- 在左侧菜单中选择 "Secrets and variables" 然后选择 "Actions"。
- 点击 "New repository secret"。
- 名称设为
NPM_TOKEN
,值设为您的 npm 访问令牌。
配置 npm 访问令牌
如果您还没有 npm 访问令牌,请按以下步骤创建:
- 登录到您的 npm 账户。
- 点击右上角的头像,选择 "Access Tokens"。
- 点击 "Generate New Token",选择 "Publish" 类型的令牌。
- 复制生成的令牌,将其作为
NPM_TOKEN
secret 的值。
文档自动部署(可选)
如果您想自动部署文档到 GitHub Pages,可以添加一个单独的工作流文件 docs.yml
:
# 构建 VitePress 站点并将其部署到 GitHub Pages 的示例工作流程
#
name: Deploy VitePress site to Pages
on:
# 在针对 `main` 分支的推送上运行。如果你
# 使用 `master` 分支作为默认分支,请将其更改为 `master`
push:
branches: [master]
paths:
- 'docs/**' # 只有当 docs 目录下的文件发生变化时才触发
- '.github/workflows/docs.yml' # 当 .github/workflows/docs.yml 文件发生变化时也触发
# 允许你从 Actions 选项卡手动运行此工作流程
workflow_dispatch:
# 设置 GITHUB_TOKEN 的权限,以允许部署到 GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# 只允许同时进行一次部署,跳过正在运行和最新队列之间的运行队列
# 但是,不要取消正在进行的运行,因为我们希望允许这些生产部署完成
concurrency:
group: pages
cancel-in-progress: false
jobs:
# 构建工作
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0 # 如果未启用 lastUpdated,则不需要
- name: Install pnpm
uses: pnpm/action-setup@v3
with:
version: 8.x # 明确指定版本
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm # 或 pnpm / yarn
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Install dependencies
run: pnpm install # 或 pnpm install / yarn install / bun install
- name: Build with VitePress
run: pnpm docs:build # 或 pnpm docs:build / yarn docs:build / bun run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/.vitepress/dist
# 部署工作
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Deploy
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
这个工作流会在每次推送到 master
分支时自动构建并部署文档到 GitHub Pages。
启用 GitHub Pages
要使用 GitHub Pages 托管您的文档:
- 去到您的 GitHub 仓库页面。
- 点击 "Settings" 标签。
- 滚动到 "Pages" 部分。
- 在 "Source" 下拉菜单中选择 "gh-pages" 分支。
- 点击 "Save"。
现在,每次您推送到 master
分支时,GitHub Actions 将自动运行测试、构建您的项目,如果一切正常,它将发布新版本到 npm 并更新您的文档。
这个设置提供了一个强大的 CI/CD 管道,确保您的代码质量,并自动化发布过程。
发布配置
更新 package.json
中的发布相关字段:
{
"name": "rollup-ts-utils",
"version": "1.0.1",
"description": "A modern JavaScript tooling library built with TypeScript and Rollup",
"main": "dist/index.js",
"module": "dist/index.esm.js",
"types": "dist/index.d.ts",
"unpkg": "dist/index.umd.js",
"jsdelivr": "dist/index.umd.js",
"exports": {
".": {
"import": "./dist/index.esm.js",
"require": "./dist/index.js",
"types": "./dist/index.d.ts",
"umd": "./dist/index.umd.js"
}
},
"scripts": {
"build": "npm run lint && npm run clean && rollup -c rollup.config.prod.mjs",
"lint": "eslint 'src/**/*.{js,ts}'",
"lint:fix": "eslint 'src/**/*.{js,ts}' --fix",
"format": "prettier --write 'src/**/*.{js,ts,json,md}'",
"dev": "rollup -c rollup.config.dev.mjs",
"test": "jest",
"commit": "cz",
"clean": "rm -rf dist",
"type-check": "tsc --noEmit",
"prepublishOnly": "pnpm run build",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs",
"version": "npm run build && git add -A dist",
"postversion": "git push && git push --tags",
"release": "npm run test && npm run build && npm publish"
},
}
添加发布相关的 npm 脚本
您的 package.json
已经包含了许多有用的脚本。让我们回顾并解释一些关键脚本:
"scripts": {
"build": "npm run lint && npm run clean && rollup -c rollup.config.prod.mjs",
"lint": "eslint 'src/**/*.{js,ts}'",
"lint:fix": "eslint 'src/**/*.{js,ts}' --fix",
"format": "prettier --write 'src/**/*.{js,ts,json,md}'",
"dev": "rollup -c rollup.config.dev.mjs",
"test": "jest",
"commit": "cz",
"clean": "rm -rf dist",
"type-check": "tsc --noEmit",
"prepublishOnly": "pnpm run build",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs",
"version": "npm run build && git add -A dist",
"postversion": "git push && git push --tags",
"release": "npm run test && npm run build && npm publish"
}
这些脚本涵盖了开发、测试、构建和文档生成等方面。特别注意:
prepublishOnly
:这个脚本会在包发布之前自动运行,确保发布的是最新构建的版本。
为了更好地支持发布流程,我们可以添加以下脚本:
"scripts": {
"version": "npm run build && git add -A dist",
"postversion": "git push && git push --tags",
"release": "npm run test && npm run build && npm publish"
}
解释新添加的脚本:
version
:在版本更新时自动构建并将 dist 目录添加到 git。postversion
:在版本更新后推送代码和标签到远程仓库。release
:运行测试、构建,然后发布到 npm。
发布前的检查清单
在发布之前,请确保:
- 所有测试都通过(运行
npm test
)。 - 文档是最新的,包括 README.md 和 API 文档。
- CHANGELOG.md 已更新(如果您维护更改日志)。
- 版本号已正确更新。
- 在
files
字段中包含了所有需要发布的文件和目录。
发布步骤
-
更新版本号:
npm version patch # 或 minor 或 major
-
发布到 npm:
npm run release
如果是首次发布带 scope 的包,使用:
npm publish --access public
-
推送代码和标签到 GitHub:
git push && git push --tags
通过这些配置和脚本,您已经为发布做好了准备。这个设置允许您轻松地更新版本、运行测试、构建项目并发布到 npm,同时确保代码和标签被推送到 GitHub。