
date-fns FP 子模块与 Lodash FP 组合使用指南柯里化日期管线的构建与体积优化【免费下载链接】date-fns⏳ Modern JavaScript date utility library ⌛️项目地址: https://gitcode.com/gh_mirrors/da/date-fns本指南以仓库中pkgs/core/examples/lodash-fp示例工程为核心讲解如何将 date-fns 的函数式编程FP子模块与 lodash 的lodash/fp组合子配合使用通过柯里化与反向参数约定搭建可复用的日期处理管线并介绍基于 esbuild 的构建流程与 gzip 体积检查方法。读完本文你将掌握 date-fns FP 模块的导入方式、convertToFP的柯里化原理以及如何验证最小化构建产物的体积。示例工程定位官方提供的 lodash-fp 组合示例date-fns 在 pkgs/core/examples 下维护了一批独立示例工程其中 lodash-fp 目录 专门演示「date-fns 的 FP 子模块」与「Lodash FP」两个函数式工具库的组合用法。该工程的 README即 pkgs/core/examples/lodash-fp/README.md篇幅虽短但覆盖了三条关键信息完整可运行的源码示例见 example.js构建与 CLI 用法见 package.json仓库中还配套了 mise.toml 任务定义如何用gzip-size测量最小化构建产物的大小。依赖声明见 package.json也揭示了该示例的技术栈dependencies: { date-fns: ../../dist/date-fns, esbuild: ^0.19.2, gzip-size-cli: ^1.0.0, lodash: ^4.17.4 }其中date-fns指向仓库本地构建产物../../dist/date-fns说明该示例运行的前提是先完成 date-fns 本身的构建产出dist目录esbuild负责将示例打包为单文件gzip-size-cli用于输出 gzip 压缩后的体积lodash则同时提供lodash/fp组合函数与lodash/isEqual断言工具。逐行拆解示例代码一条完整的日期格式化管线示例核心代码位于 pkgs/core/examples/lodash-fp/example.js全文只有 25 行却完整演示了「解析 ISO 日期 → 加 5 年 → 按指定 locale 与格式输出 → 转大写」的纯函数管线。下面分段展开。从 date-fns/fp 子路径导入柯里化函数const { addYears } require(date-fns/fp/addYears); const { formatWithOptions } require(date-fns/fp/formatWithOptions); const { parseISO } require(date-fns/fp/parseISO); const { eo } require(date-fns/locale/eo);date-fns 的包导出见 pkgs/core/package.json 的exports配置为每个函数提供了独立子路径date-fns/fp/addYears、date-fns/fp/formatWithOptions、date-fns/fp/parseISO分别对应 src/fp/addYears/index.ts、src/fp/formatWithOptions/index.ts、src/fp/parseISO/index.ts。此外还从date-fns/locale/eo导入了世界语Esperantolocale用于让格式化输出使用该语言的月份名。预绑定参数构造可复用函数const addFiveYears addYears(5); const dateToString formatWithOptions({ locale: eo }, d MMMM yyyy);这是 FP 模块与普通模块最直观的差异普通 API 是addYears(date, amount)、format(date, formatStr, options)参数按「数据在前、配置在后」排列而 FP 版本全部柯里化且参数顺序反转——先传配置/增量再传日期数据。addYears(5)返回一个等待日期参数的新函数等价于把「增加 5 年」这一变换固化下来formatWithOptions({ locale: eo }, d MMMM yyyy)同理把「用世界语、按d MMMM yyyy格式」的输出规则预先绑定。用 lodash/fp 的 compose 组装管线const compose require(lodash/fp/compose); const toUpper require(lodash/fp/toUpper); const isEqual require(lodash/isEqual); const dates [2017-01-01, 2017-02-11, 2017-07-02]; const formattedDates dates.map( compose(toUpper, dateToString, addFiveYears, parseISO), );lodash/fp/compose按从右到左的顺序组合函数每个日期字符串先经过parseISO解析为 Date 对象再交给addFiveYears加 5 年接着由dateToString格式化最后经toUpper转大写。由于 date-fns/fp 的函数均以「数据作为最后一个参数」的柯里化形态存在它们与 lodash/fp 的compose、map等工具天然兼容无需任何适配层。验证结果console.log( isEqual(formattedDates, [ 1 JANUARO 2022, 11 FEBRUARO 2022, 2 JULIO 2022, ]), );程序使用lodash/isEqual非 FP 版用于值比较断言输出与期望一致。2017-01-01加 5 年得到 2022 年世界语月份januaro一月、februaro二月、julio七月经toUpper后即为JANUARO、FEBRUARO、JULIO。脚本的 stdout 为true仓库测试任务正是基于这一点做断言的。深入原理FP 模块由 convertToFP 统一生成观察任一 FP 模块源码会发现文件头部统一标注「This file is generated automatically byscripts/build/fp.ts」例如 src/fp/addYears/index.tsimport { addYears as fn } from ../../addYears/index.ts; import { convertToFP } from ../_lib/convertToFP/index.ts; export const addYears convertToFP(fn, 2);即所有 FP 版本都由底层辅助函数convertToFP(fn, arity)自动转换而来arity为原函数的参数个数addYears(date, amount)为 2format(date, formatStr, options)为 3parseISO(argument)为 1。其实现位于 src/fp/_lib/convertToFP/index.tsexport function convertToFPFn extends FPFnInput, Arity extends FPArity( fn: Fn, arity: Arity, curriedArgs: unknown[] [], ): FPFnFn, Arity { return ( curriedArgs.length arity ? fn(...curriedArgs.slice(0, arity).reverse()) : (...args: unknown[]) convertToFP(fn, arity, curriedArgs.concat(args)) ) as FPFnFn, Arity; }该实现揭示了 FP 模块的两大约定柯里化当已收集的参数数curriedArgs.length小于arity时返回一个新函数继续收集参数curriedArgs.concat(args)直到凑齐为止参数反序凑齐后调用fn(...curriedArgs.slice(0, arity).reverse())把「先传入的配置参数」反转回原函数期望的「数据在前」顺序。这正是formatWithOptions({ locale: eo }, d MMMM yyyy)中 options 在前、日期留到最后的原因。对应测试位于 src/fp/_lib/convertToFP/test.ts可用于进一步确认柯里化与反序行为。需要说明的是scripts/build/fp.ts仅为生成脚本的注释声明本文未逐一核对生成器本体但从产物文件形态可以推断全部 FP 入口均为该机制的统一输出。构建示例工程从安装到产出 distREADME 给出的构建方式是最简明的两步npm install npm run build产物输出到./dist目录。而在当前仓库中该示例还通过 mise.toml 定义了等价的任务其中 build 任务实际执行的命令为[tasks.build] depends install run pnpm exec esbuild example.js --outdirdist [tasks.test] depends build run test $(env TZUTC node ./dist/example.js) true [tasks.stats/size] depends build run pnpm exec gzip-size dist/example.min.js三点值得注意install任务依赖根工作区的安装任务//pkgs/core/examples:install且package.json中date-fns依赖指向../../dist/date-fns因此实际动手前需先构建 date-fns 本体产出 dist 目录test任务在TZUTC环境下执行node ./dist/example.js并用 shell 的test断言其输出等于true与 example.js 末尾的console.log(isEqual(...))相呼应——这个设计将「示例是否可运行」直接变成了可自动化的验证stats/size任务即 README 中体积统计的工程化封装。最小构建体积用 gzip-size 量化打包产物README 的「Minimal Build Size」小节给出了统计命令gzip-size dist/example.min.js | pretty-bytes # 23.4 kB其含义是对 esbuild 输出的最小化脚本example.min.js做 gzip 压缩后体积约为 23.4 kB该数值为 README 中给出的参考输出。gzip-size由gzip-size-cli提供pretty-bytes则把字节数转成易读单位。需要说明的是当前仓库 mise.toml 的 build 任务默认未开启 esbuild 的--minify压缩若想复现 23.4 kB 这一量级的数字需在打包时启用压缩并针对example.min.js执行上述命令在未压缩的dist/example.js上统计会得到更大数值。这个「单文件 gzip 体积」的检查思路对评估函数式封装在真实打包场景中的开销很有参考价值由于 pkgs/core/package.json 声明了type: module与sideEffects: falsedate-fns 天然支持 tree-shaking示例仅从子路径引入三个函数与一个 locale最终体积因此可以保持在小规模范围内。进一步探索把组合思路迁移到更多场景本示例展示的是 FP 模块与 lodash/fp 组合的最小范式仓库中还有更多相关资源可以延伸全部 FP 入口集中在 src/fp 下每个函数都提供普通版与WithOptions版如formatWithOptions、parseISOWithOptions凡是有 options 参数的函数FP 版本都把 options 放在参数序列最前面包级导出见 pkgs/core/package.json同时支持date-fns/fp聚合入口与date-fns/fp/fn单函数子路径后者配合打包工具更利于按需引入若希望对比不同打包器下的体积表现可参考同目录下的 rollup 示例 与 webpack 示例若需要在 Node 环境直接跑通 ES Module 导入可参考 node-esm 示例 与 esm 示例。掌握了「date-fns/fp 子路径导入 预绑定参数 lodash/fp compose 组装」这套组合拳后你可以把任意「解析 → 变换 → 格式化」的日期处理逻辑声明式地组织成可复用的纯函数管线并用本文介绍的构建与体积统计手段验证其在生产打包中的实际开销。【免费下载链接】date-fns⏳ Modern JavaScript date utility library ⌛️项目地址: https://gitcode.com/gh_mirrors/da/date-fns创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考