包结构
本文档描述 Turf.js 代码库中包的组织结构、它们之间的关系,以及它们如何形成一个连贯的地理空间功能生态系统。有关构成 Turf.js 基础的核心模块信息,请参阅核心模块。
Monorepo 架构
Turf.js 组织为使用 Lerna 管理的 pnpm 工作区的 monorepo,所有模块都位于 packages/ 目录中。Monorepo 配置在 lerna.json 中定义,工作区发现通过 pnpm-workspace.yaml 处理。
Monorepo 管理结构
包组织
Turf.js 生态系统由主聚合包 @turf/turf 和主包依赖中定义的确切 107 个独立功能特定包组成。每个包遵循命名约定 @turf/{function-name} 并提供专注的地理空间操作。
按类别分布的包
| 类别 | 数量 | 示例 |
|---|---|---|
| 布尔运算 | 12 | @turf/boolean-contains, @turf/boolean-intersects, @turf/boolean-parallel |
| 中心点计算 | 5 | @turf/center, @turf/center-mean, @turf/center-median, @turf/center-of-mass, @turf/centroid |
| 聚类 | 3 | @turf/clusters, @turf/clusters-dbscan, @turf/clusters-kmeans |
| 几何运算 | 8 | @turf/buffer, @turf/union, @turf/intersect, @turf/difference, @turf/dissolve |
| 网格生成 | 4 | @turf/hex-grid, @turf/square-grid, @turf/triangle-grid, @turf/point-grid |
| 线运算 | 11 | @turf/line-intersect, @turf/line-slice, @turf/line-chunk |
| 其他运算 | 58 | 测量、工具、分析函数 |
| 变换 | 6 | @turf/transform-rotate, @turf/transform-scale, @turf/transform-translate, @turf/simplify |
主包
@turf/turf 包作为伞形包,重新导出所有独立包的功能。它允许用户从单个包导入所有 Turf.js 功能,或选择性导入特定函数。
主包结构
@turf/turf 包提供通过 package.json 导出和构建脚本配置的多种输出格式。
主包构建流水线
Package.json 导出映射配置:
main:"dist/cjs/index.cjs"(CommonJS 默认)module:"dist/esm/index.js"(ES Module)types:"dist/esm/index.d.ts"(TypeScript 类型)browser:"turf.min.js"(UMD 打包)
主包依赖
主包使用 pnpm 工作区协议符号声明对所有独立模块的依赖:
"dependencies": {
"@turf/along": "workspace:*",
"@turf/angle": "workspace:*",
"@turf/area": "workspace:*",
"@turf/bbox": "workspace:*",
"@turf/bbox-clip": "workspace:*",
// ... 102 更多工作区依赖
"@types/geojson": "^7946.0.10",
"tslib": "^2.8.1"
}workspace:* 协议确保:
- 所有模块使用完全相同的版本 (7.2.0)
- 依赖项在开发期间解析为本地包
- 发布的版本在生态系统中保持一致性
独立包
每个独立包遵循为现代 JavaScript 环境设计的统一结构。
独立包结构
每个 @turf/* 包遵循标准化的文件结构和配置模式。
标准包文件结构
示例:@turf/concave 包结构
- 入口:函数
concave()作为默认导出 - 依赖:
@turf/clone、@turf/distance、@turf/helpers、@turf/invariant、@turf/meta、@turf/tin - 外部:
topojson-client、topojson-server - 测试套件:使用
tape框架和基于 fixture 的测试
包导出配置
所有独立包使用相同的导出配置以实现模块系统兼容性:
双包导出模式:
{
"type": "module",
"main": "dist/cjs/index.cjs",
"module": "dist/esm/index.js",
"types": "dist/esm/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
"types": "./dist/cjs/index.d.cts",
"default": "./dist/cjs/index.cjs"
}
}
},
"sideEffects": false
}关键配置详情:
"type": "module":包是 ESM 优先"sideEffects": false:启用 tree-shaking 优化- 条件导出支持具有适当 TypeScript 类型的
import和require - CommonJS (
.d.cts) 和 ESM (.d.ts) 的单独类型定义
依赖图
Turf.js 生态系统遵循分层依赖结构,核心工具位于基础层。
核心依赖层
按包类型的外部依赖:
- 几何运算:
@turf/jsts(Java Topology Suite)、polyclip-ts、d3-geo - 空间分析:
rbush(空间索引)、concaveman、topojson-* - 网格/插值:
marchingsquares(轮廓生成)
模块类别
Turf.js 包可以按其功能分类:
| 类别 | 描述 | 示例包 |
|---|---|---|
| 核心工具 | 用于创建、操作和验证 GeoJSON 的基础工具 | @turf/helpers, @turf/meta, @turf/invariant |
| 布尔运算 | 评估空间关系的函数 | @turf/boolean-contains, @turf/boolean-intersects |
| 几何运算 | 生成新几何体的函数 | @turf/buffer, @turf/union, @turf/intersect |
| 测量 | 计算空间测量的函数 | @turf/distance, @turf/area, @turf/bearing |
| 变换 | 变换几何体的函数 | @turf/transform-rotate, @turf/simplify |
| 线运算 | 专用于 LineString 的函数 | @turf/line-slice, @turf/line-intersect |
| 空间分析 | 高级分析操作 | @turf/clusters-kmeans, @turf/voronoi |
| 网格和插值 | 生成网格和插值的函数 | @turf/hex-grid, @turf/isolines |
构建系统
Turf.js 使用 TSUP 进行独立包构建、使用 Rollup 进行 UMD 打包的双构建系统。
构建工具配置
构建脚本模式:
标准包构建:
"scripts": {
"build": "tsup --config ../../tsup.config.ts",
"test": "npm-run-all --npm-path npm test:*",
"test:tape": "tsx test.ts"
}主包构建(额外 Rollup 步骤):
"scripts": {
"build": "tsup --config ../../tsup.config.ts && rollup -c rollup.config.js",
"last-checks": "npm-run-all last-checks:testjs last-checks:example"
}Rollup UMD 配置:
- 输入:
index.ts(聚合导出) - 输出:
turf.min.js,全局名称为turf - 插件:CommonJS、Node resolve、Babel、Terser (压缩)
构建配置
构建过程通过几个文件配置:
tsup.config.ts(跨包共享)rollup.config.js(用于主包中的 UMD 打包)nx.json(用于构建缓存和依赖)
每个包在其 package.json 中定义其构建脚本:
"scripts": {
"build": "tsup --config ../../tsup.config.ts",
"test": "npm-run-all --npm-path npm test:*",
"test:tape": "tsx test.ts"
}主包还包括用于生成 UMD 打包的 Rollup 配置:
"scripts": {
"build": "tsup --config ../../tsup.config.ts && rollup -c rollup.config.js"
}版本管理
所有 Turf.js 包共享相同的版本号,通过 Lerna 管理:
{
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"npmClient": "pnpm",
"version": "7.2.0",
"command": {
"publish": {
"registry": "https://registry.npmjs.org"
}
}
}这确保所有包以一致的版本一起发布。
包导入模式
用户可以在导入整个库或独立函数之间进行选择:
完整库导入
// 导入整个库 (UMD 构建)
import * as turf from '@turf/turf';
turf.distance(point1, point2);
// 或在 CommonJS 中
const turf = require('@turf/turf');
turf.distance(point1, point2);独立函数导入
// 导入特定函数 (更小的包大小)
import { point } from '@turf/helpers';
import distance from '@turf/distance';
// 或在 CommonJS 中
const distance = require('@turf/distance').default;
const { point } = require('@turf/helpers');总结
Turf.js 包结构遵循模块化设计模式,具有:
- 主包 (
@turf/turf),作为所有功能的聚合器 - 具有标准化结构和导出的独立功能特定包
- 提供基本功能的核心工具包
- 用于各种地理空间操作的专用包
- 使用现代 JavaScript 工具的共享构建配置
- 所有包之间的一致版本控制
此架构为用户提供了灵活性,可以在导入整个库或仅导入他们需要的特定函数之间进行选择,同时在项目中保持一致的开发体验。