{"id":14991410,"url":"https://github.com/konghayao/cn-font-split","last_synced_at":"2025-05-14T05:02:34.351Z","repository":{"id":119745361,"uuid":"529238370","full_name":"KonghaYao/cn-font-split","owner":"KonghaYao","description":"划时代的字体切割工具，CJK与任何字符！支持 otf、ttf、woff2 字体多线程切割，完美地细颗粒度地进行包大小控制。A revolutionary font subetter that supports CJK and any characters! It enables multi-threaded subset of otf, ttf, and woff2 fonts, allowing for precise control over package size.   ","archived":false,"fork":false,"pushed_at":"2024-10-29T01:03:07.000Z","size":13079,"stargazers_count":492,"open_issues_count":6,"forks_count":16,"subscribers_count":6,"default_branch":"main","last_synced_at":"2024-10-29T15:23:38.769Z","etag":null,"topics":["browser","bun","cjk","cjk-font","converter","deno","font","font-subset","font-subsetter","multithreading","nodejs","opentype-fonts","otf","performance","ttf","wasm","webworker","woff2"],"latest_commit_sha":null,"homepage":"https://chinese-font.netlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KonghaYao.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-26T11:54:41.000Z","updated_at":"2024-10-29T12:14:39.000Z","dependencies_parsed_at":"2023-09-24T05:45:34.806Z","dependency_job_id":"4fd38254-1899-4e77-a6d9-18b1fb3884f5","html_url":"https://github.com/KonghaYao/cn-font-split","commit_stats":{"total_commits":524,"total_committers":8,"mean_commits":65.5,"dds":0.08969465648854957,"last_synced_commit":"d1192db5e4ea36328b7a6e2e4aa5b9401cc3f505"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KonghaYao%2Fcn-font-split","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KonghaYao%2Fcn-font-split/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KonghaYao%2Fcn-font-split/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KonghaYao%2Fcn-font-split/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KonghaYao","download_url":"https://codeload.github.com/KonghaYao/cn-font-split/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248420168,"owners_count":21100324,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","bun","cjk","cjk-font","converter","deno","font","font-subset","font-subsetter","multithreading","nodejs","opentype-fonts","otf","performance","ttf","wasm","webworker","woff2"],"created_at":"2024-09-24T14:27:46.210Z","updated_at":"2025-04-11T14:41:19.633Z","avatar_url":"https://github.com/KonghaYao.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 中文 Web Font 切割工具 5.0\n\n![中文网字计划](/assets/chinese-fonts.png)\n\n![updateTime](https://img.shields.io/badge/更新时间-2024/07/16-green)\n![author](https://img.shields.io/badge/author-江夏尧-green)\n![npmVersion](https://img.shields.io/badge/LTS_version-5.1.0-green)\n[![](https://data.jsdelivr.com/v1/package/npm/cn-font-split/badge)](https://www.jsdelivr.com/package/npm/cn-font-split)\n\n![NPM License](https://img.shields.io/npm/l/%40konghayao%2Fcn-font-split)\n\n| [中文网字计划](https://chinese-font.netlify.app/) | [Github](https://github.com/KonghaYao/cn-font-split) | [在线使用](https://chinese-font.netlify.app/online-split/) |\n| ------------------------------------------------- | ---------------------------------------------------- | ---------------------------------------------------------- |\n\n## 简介\n\n`cn-font-split` 是 **[中文网字计划](https://chinese-font.netlify.app/)** 所使用的字体分包工具，通过高性能的各种技术将庞大的字体包拆分为适合网络分发的版本。经过四个版本的字体研究与代码迭代，这项技术在我们的网站中得到了充分的应用，实现了中文字体在 Web 领域的加载速度与效率的双飞跃。\n\n`cn-font-split` 不仅支持中文，针对于 CJK 皆有优化，可以根据实际字体包内字符进行分包。\n\n-   🚀 `自研多线程`+ (`WebAssembly`｜`Native`) 分包速度极快；\n-   💻 坚持 Web 平台为基底，兼容性极强，浏览器、Node、Deno、CICD 环境，统统可以运行。\n-   🔧 功能齐全完备，支持生成文字图片预览，支持完整全字符，支持复杂字形！\n-   ⛰️ 自研 Harfbuzz 文本 SVG 引擎，独立渲染文本图像。\n-   🚄 **我们有编译器插件啦! —— [vite-plugin-font](https://npmjs.com/package/vite-plugin-font), 支持 Vite、Nuxt、Next、Webpack、Rspack，快速嵌入你的前端工具链。**\n\n\u003e [Opentype Feature 支持情况](/packages/test/SUPPORT_FEATURE.md) 支持 95 ｜ 部分支持 9｜ 等待测试 20\n\n[详见兼容性章节](#兼容性提醒)。\n\n| [Nodejs](#nodejs)    | [Deno](#deno) | [Chrome](#browser) | [FireFox](#browser) | [Safari](#browser) | [Bun](#bun) |\n| -------------------- | ------------- | ------------------ | ------------------- | ------------------ | ----------- |\n| ✅^18.0.0 ⏺️ ^14.0.0 | ✅^1.30.0     | ✅^102             | ✅^114              | ✅^15              | ⏺️ ^1.0.4   |\n\n### 新版本功能\n\n1. ✅ 🔒 完备测试与版本发布流程！\n2. ✅ 🚀 多线程压缩，核心越多，速度越快！（1310ms -\u003e 760ms）\n3. ✅ 🚀 使用 WASM 和原生工具解析与分包，提升打包速度。\n4. ✅ 🔒 依赖检查与重构，安全版本。\n5. ✅ 📦 更加可控的分包方式，支持细颗粒度的字符拆分。\n6. ✅ 🔔 支持 OTF 格式字体打包，支持复杂字形渲染。\n7. ✅ 🏞️ 字体预览图生成\n8. ✅ ⌨️ 支持 Nodejs、Deno、Bun、Browser，跨平台随处可使用、构建产物一致！\n9. ✅ 🥳 不止中文，只要是包内的字符，统统分包\n10. ✅ 🏞️ 支持自动识别可变字体字重\n\n## 快速使用\n\nNodejs 版本推荐使用 **大于 18 的版本**。如低级版本或者其他的设备环境，[参考兼容性章节](#兼容性提醒)。\n\n### 安装\n\n```bash\nnpm install cn-font-split\nnpm install cn-font-split -g # 如果使用命令行，推荐全局安装\n```\n\n### 命令行使用\n\n```bash\n# -i 输入 -o 输出\ncn-font-split -i=../demo/public/SmileySans-Oblique.ttf -o=./temp\n\n# 参数与正常 js 操作是一样的，深层json则需要使用 . 来赋值\ncn-font-split -i=../demo/public/SmileySans-Oblique.ttf -o=./temp --renameOutputFont='[hash:10][ext]' --css.fontWeight=700\n\n# 显示输入参数说明，虽然会显示 typescript 类型。。。\ncn-font-split -h\n```\n\n### 项目内打包代码\n\n```js\nimport { fontSplit } from 'cn-font-split';\n\nfontSplit({\n    FontPath: './fonts/SourceHanSerifCN-Bold.ttf', // 推荐使用 otf、ttf 字体\n    destFold: './build',\n    chunkSize: 60 * 1024, // 如果需要的话，自己定制吧\n    testHTML: true, // 输出一份 html 报告文件\n    reporter: true, // 输出 json 格式报告\n    previewImage: {}, // 只要填入 这个参数，就会进行图片预览文件生成，文件为 SVG 格式\n    css: {\n        // 覆盖默认的 css 设置，一般不需要进行更改\n        // fontFamily: \"站酷庆科黄油体\",\n        // fontWeight: 400,\n    },\n    // 自定义分包输出的文件名为 10 位短哈希，或者使用自增索引: '[index][ext]'\n    renameOutputFont: '[hash:10][ext]',\n    // 或者也可以像这样传入一个函数返回自定义的文件名\n    // renameOutputFont: ({ transferred, ext, index }) =\u003e {\n    //   return index.toString(36) + ext\n    // }\n});\n```\n\n### 打包成品目录解释\n\n```txt\n- build\n    ... // 很多字体分包，hash 命名\n    - index.html // 用于展示打包分析报告, 需要开一个服务端口进行查看\n    - reporter.json // 打包信息\n    - result.css // css 入口，引入这个 css 文件即可使用字体包\n```\n\n\n### 自定义插件\n\ncn-font-split 在 v6 版本进行了插件化重构，提供了一些高度自定义的方法, 你可以在下面的代码中获取灵感。\n\n1. [自定义分包策略](/packages/subsets/test/overwrite.test.mjs)\n\n### 更多 demo\n\n1. [Nodejs 使用](/packages/subsets/test/node.test.mjs)\n2. [Deno 使用](/packages/subsets/test/deno.test.js)\n3. [Bun 使用](/packages/subsets/test/bun.test.js)\n4. [浏览器使用](https://github.com/KonghaYao/chinese-free-web-font-storage/blob/feature/docs/src/components/online-split/index.tsx)\n\n\n## 提高网站的字体加载速度\n\n1. **切割分包大小适当**：我的建议是设置 50-70KB 左右范围进行打包，这样单个包的大小不会太大，HTTP/2 的加载速度也够快。cn-font-split 的默认值是 70 KB 能够满足大多数场景。\n2. **使用支持并发加载的 CDN**： JSDelivr、ESM.sh 等公益 CDN 都进行了并发数限制，一旦你的网站一次性加载字体包太多就会触发 CDN 熔断。后面我使用了 Netlify 进行私有化部署，速度是瞬间加载！使用 ImageKit CDN 进行字体加载，也是瞬间完成！\n3. **一定要配置 HTTP 缓存条件**：在有缓存时，用户打开你的网站是可以达到 50ms 内瞬间加载完所有字体包的。由于字体文件配置一次就基本上不会进行改动，所以可以持久缓存。\n4. **文档站点的预加载**：如果网站有条件，可以在首页或者是所有页面，在浏览器空闲的时候，使用 js 的 fetch （force-cache） 请求所有的字体包。这样浏览器会把字体都加入进缓存中，从而保证其它页面的文字也能迅速加载。至于分包的具体名称，可以使用 reporter.json 文件查看。\n5. **首屏优化**：推荐使用 [vite-plugin-font](https://npmjs.com/package/vite-plugin-font)。它可以扫描代码中使用的字符，并与你的前端工具链进行结合，实现最小化字体切割。\n\n\n\n## 开发相关\n\n1. 本仓库为 Monorepo，需要使用 pnpm 链接 workspace\n2. 项目源文件在 packages/subsets，通过 workspace 进行模块化链接。\n3. 所有使用的指令必须使用 pnpm 相关的方法，防止 workspace 的兼容问题\n4. 构建 subsets 子项目时，先进行 `pnpm -C ./packages/font-sharp build`\n5. 仓库中引用的部分 npm 包在我的其它仓库中，因为适应性问题进行了一部分源代码的修改。\n\n## 一些特殊情况\n\n1. 不支持 woff 和 eot 文件：\n    1. eot 在 Web 端支持度极低，故不支持\n    2. woff 类型的压缩率和普及率远不及 woff2，提供的字体源也很少使用 woff（一般有 otf 或者 ttf），故不支持。\n2. 部分字体开发的时候用了比较奇怪的字体编辑器，可能最终导出的字体会报错。\n    1. 这种情况最好找字体设计师再导出一份可用版本\n    2. 或者自己用 FontForge 进行修复，这个就比较麻烦了\n\n## 兼容性提醒\n\n### 🚀 Nodejs\n\n\u003e version: ✅^18.0.0 ⏺️ ^14.0.0 可以使用一些 polyfill [Nodejs 使用](/packages/subsets/test/node.test.mjs)\n\n1. Nodejs 几乎不需要进行适配，可以直接使用。\n2. Nodejs 18 以下的代码需要支持 esm、fetch、worker_threads 等高级特性，如果不支持部分特性，可以找找社区的 polyfill 插件。[polyfill 示例](https://github.com/KonghaYao/cn-font-split-test/tree/main/test)\n\n### Browser\n\n\u003e version: ✅ Chrome 102; FireFox 114; Safari 15 [浏览器使用](https://github.com/KonghaYao/chinese-free-web-font-storage/blob/feature/docs/src/components/online-split/index.tsx)\n\n1. 浏览器需要 支持 module worker（多线程必须）、支持 WebAssembly 相关功能\n2. 在网页中引入时，不要对 cn-font-split 再次打包（会导致奇奇怪怪的依赖问题）\n3. 可以使用 CDN 导入 /dist/browser/index.js 文件，这个是支持的。\n4. 浏览器版本可以直接在浏览器运行分包任务，比其他生态环境要方便得多，项目组会一直支持。\n\n### 🚀 Deno\n\n\u003e version: ✅^1.30.0 [Deno 使用](/packages/subsets/test/deno.test.js)\n\n1. 1.30.0 为不自动本地安装的版本，后续版本中使用了本地 npm 路径导入，导致部分情况下性能衰弱。可以参考 `deno run -A --no-npm index.mjs` 避免。\n\n### Bun\n\n\u003e version: ⏺️^1.0.4 [Bun 使用](/packages/subsets/test/bun.test.js)\n\n1. Bun 现在的版本只能跑在 Linux 和 Mac 平台，Windows 似乎官方在支持\n2. Bun 在我的 Mac 上运行良好，但是到某些 Linux 平台上，就会出问题。\n3. Bun 运行速度比 Nodejs 要快 30% 左右（保守估计）。\n\n## 感谢\n\n1. 项目核心插件为 Harfbuzz 项目，源项目使用 C 与 C++ 构建了一个字体布局工具，然后提供了 WASM 的打包方法。项目重新构建并提供了 Typescript 版本的 API 封装，使得代码可以更好地融入生态中。\n2. opentype.js 这个项目为第二解析引擎，主要处理 feature 关系判断和文本转化为 SVG 的任务，在渲染方面给我们的支持很多。\n3. wawoff2 项目将 Google 的 woff2 格式转换功能代码编译成为了 wasm，为我们的字体压缩提供了非常简便的 API。但是 wawoff2 项目的导出方式为 js 嵌入 wasm，极大影响了 js 打包和使用，故项目也重新构建并发布出适合的版本。\n4. @napi-rs/ttf2woff2 使得 Nodejs 平台和 Bun 平台可以以极快的原生速度压缩字体文件，效率极高，速度极快。\n5. 多线程采用了 workerpool 的解决方案，多线程的加持下，速度快了非常多。\n\n## 开源许可证\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkonghayao%2Fcn-font-split","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkonghayao%2Fcn-font-split","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkonghayao%2Fcn-font-split/lists"}