拓冰建站拓冰建站
首页 / 资讯中心 / 正文

PaddleOCR JS 浏览器端 OCR SDK 开发指南:monorepo 构建流程、TypeScript 工程化与 npm 分发兼容实践

PaddleOCR JS 浏览器端 OCR SDK 开发指南monorepo 构建流程、TypeScript 工程化与 npm 分发兼容实践【免费下载链接】PaddleOCR飞桨多语言OCR工具包实用超轻量OCR系统支持80种语言识别提供数据标注与合成工具支持服务器、移动端、嵌入式及IoT设备端的训练与部署 Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80 languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCR本篇指南以paddleocr-js子仓库的开发文档中文版见 development_cn.md为核心骨架系统讲解基于 PaddleOCR 的浏览器端 OCR SDKnpm 包名paddleocr/paddleocr-js的本地开发全流程从 npm 依赖安装、常用命令矩阵到 monorepo 结构、严格 TypeScript 工程规范再到 Vite 库模式构建产物与自定义插件libraryWorkerPlugin为 npm 分发所做的三项关键后处理。读完本文你将能够独立搭建开发环境、运行构建与测试流水线并理解 SDK 的 ESM 产物、Worker bundle 与 WASM 资源在浏览器与下游打包器之间是如何正确协作的。环境要求与依赖安装在进入开发之前需要确认 Node.js 版本满足仓库要求。根目录 package.json 中声明了engines: { node: 20.11 }这是使用 npm workspaces 与 Vite 6 的最低版本门槛建议使用 LTS 版本。安装依赖只需在paddleocr-js/根目录执行npm install由于仓库采用 npm workspaces 管理workspaces字段包含packages/*与apps/*npm install会在根目录统一安装所有 workspace 的依赖并生成package-lock.json无需进入子目录逐个安装。安装完成后根目录会同时具备 SDKpackages/core与 demo 应用apps/demo所需的全部依赖。注意本文所有命令均约定在paddleocr-js/根目录执行。整个paddleocr-js是 PaddleOCR 仓库中的一个独立子项目其目录结构、包管理与 PaddleOCR 主仓库Python 侧相互独立开发时无需关心 Python 侧环境。常用命令全景构建、校验与测试根目录 package.json 的scripts字段集中定义了开发期高频命令它们是理解整个工程流水线的入口命令作用npm run build先构建 SDK 再构建 demo显式拓扑顺序避免 demo 引用到尚未生成的dist/npm run build:sdk仅构建 SDKpackages/core等价于npm run build --workspace packages/corenpm run build:demo仅构建 demo 应用apps/demo等价于npm run build --workspace apps/demonpm run lint对整个仓库执行 ESLint 检查npm run test运行 Vitest 单元测试npm run typecheck对所有 workspace 执行tsc --noEmit类型检查core demonpm run check完整 CI 式流水线format:check→lint→build:sdk→typecheck→test→build:demonpm run clean删除所有dist/目录packages/*/dist与apps/*/distnpm run dev:demo启动 demo 的 Vite 开发服务器等价于npm run dev --workspace apps/demo其中npm run check是提交前最值得依赖的一条命令它以固定顺序依次执行格式检查Prettier、代码规范检查ESLint、SDK 构建、类型检查、单元测试与 demo 构建任何一环失败都会中断可当作本地 CI 使用。配合 husky 与 lint-staged见 package.json 的lint-staged字段提交时还会对暂存文件自动执行eslint --fix与prettier --write。单个 workspace 的命令执行方式当只想操作某个 workspace 时有两种写法# 方式一显式路径推荐见 monorepo 约定 npm run build --workspace packages/core npm run build --workspace apps/demo # 方式二包名无歧义时可用 npm run dev --workspace demo这种根目录统一调度 workspace 定向执行的模式是 monorepo.md 中明确的工程约定packages/*存放可复用、可发布的包SDK 位于packages/core但对外 npm 包名保持paddleocr/paddleocr-jsapps/*存放私有应用如apps/demo不作为 npm 产品发布。TypeScript 工程规范严格模式与分级规则集SDKpackages/core与 demo 应用apps/demo全部使用 TypeScript 编写且开启了严格模式strict: true。代码质量通过 eslint.config.js 分级管控不同目录适用不同强度的规则集源码目录packages/**/src/**/*.ts与apps/**/src/**/*.ts使用typescript-eslint的strictTypeChecked规则集这是类型感知type-aware检查中强度最高的配置覆盖no-unsafe-*系列、严格类型断言等规则配合globals.browser提供浏览器全局变量。该规则集需要parserOptions.project指向 tsconfig.eslint.json 以启用项目级类型信息。测试目录packages/**/test/**/*.ts使用较轻量的recommendedTypeChecked预设并针对性放宽规则例如关闭typescript-eslint/no-unsafe-assignment、no-unsafe-argument、no-unsafe-member-access、no-unsafe-call、no-unsafe-return与no-explicit-any同时放宽require-await、no-extraneous-class、unbound-method。这样既保留了类型检查的主体价值又避免测试代码中常见的类型体操拖慢开发。配置文件apps/**/*.js、根目录*.config.{js,ts}与packages/**/*.config.*使用基础 ESLint 规则并同时启用 Node 与浏览器全局变量。类型检查方面npm run typecheck会执行tsc --noEmit遍历所有 workspace。这里有一个值得注意的设计demo 的 tsconfig.json 通过paths映射将paddleocr/paddleocr-js与paddleocr/paddleocr-js/viz直接指向packages/core/src/index.ts与packages/core/src/viz/index.ts的源码因此 demo 的类型检查不依赖先执行build:sdk生成dist/类型与实现始终同步不会出现类型声明过期的问题。SDK 构建流水线深度解析Vite 库模式与构建产物SDK 使用 Vite 的库模式library mode构建配置见 packages/core/vite.config.ts。构建入口为双入口src/index.ts主 SDK与src/viz/index.ts可视化子路径产物输出到packages/core/dist/index.mjs— 主入口的 ESM 产物index.d.ts— 主入口的类型声明viz.mjs—./viz子路径的 ESM 产物assets/worker-entry-*.js— 自包含的 Worker bundle内置 OpenCV.js 与 ORTONNX Runtime WebJS 运行时。产物映射关系由 packages/core/package.json 的exports字段声明.导出index.mjsindex.d.ts./viz导出viz.mjsviz/index.d.tsfiles字段仅发布dist与 READMEsideEffects: false便于下游打包器做 tree-shaking。构建配置中有几个关键细节worker.format: es且rollupOptions.output.inlineDynamicImports: true将 Worker 侧所有动态导入合并进单个 chunk保证 Worker 产物是自包含的单一文件rollupOptions.external将onnxruntime-web、techstark/opencv-js、clipper-lib、js-yaml标记为外部依赖SDK 自身不打包这些运行时而是通过package.json的dependencies声明版本当前为onnxruntime-web ^1.22.0、techstark/opencv-js ^4.10.0-release.1define中的__ORT_WASM_CDN_PREFIX__在构建期注入为https://cdn.jsdelivr.net/npm/onnxruntime-web${ortVersion}/dist/其中ortVersion是构建时从node_modules/onnxruntime-web实时解析的版本号用作 Worker 模式下 WASM 的 CDN 回退地址。自定义插件 libraryWorkerPlugin为 npm 分发而生的三项后处理Vite 库模式默认面向 Web 应用场景直接产出会导致 Worker 资源路径、WASM 内联等问题无法在 npm 分发后正确工作。因此 vite.config.ts 内置了自定义插件libraryWorkerPlugin在generateBundle阶段执行它做了三件事1. 将 Worker 资源的绝对路径改写为相对路径。插件用正则匹配产物中形如/assets/...的 Worker 引用改写为./assets/...。这样 Worker 文件是相对于 SDK 模块自身位置解析的而不是相对于站点根路径web origin从而保证 SDK 无论被安装到哪个项目、部署在哪个路径下都能正确找到 Worker。2. 拆分new Worker(new URL(...))模式。源码中new Worker(new URL(STRING, import.meta.url))的写法会被下游打包器Vite、webpack 等的特殊插件识别处理但各打包器的行为不同资源复制插件需要看到new URL(资源路径, import.meta.url)才能复制 Worker 文件而 Worker 检测插件可能试图把 Worker 重新打包。插件将这段代码改写为先创建 URL 变量、再构造 Worker的 IIFE 形式(() { const _w new URL(./assets/worker-entry-xxx.js, import.meta.url); return new Worker(_w, { /* options */ }); })()这样既能让下游的资源 URL 插件正确复制 Worker 文件又能避开 Worker 检测插件的二次打包这正是下游兼容downstream-compatible的核心。3. 剥离 base64 内联的 ORT WASM 二进制。Vite 会把 ORT 中new URL(./ort-wasm-*.wasm, import.meta.url)的引用内联成data:application/wasm;base64,...数据 URI一个 Worker 文件会被撑大数十 MB。插件的ortWasmDataUriPattern正则/data:application\/wasm;base64,[A-Za-z0-9/]/g将这些内联二进制整体替换为空的占位前缀从而显著缩小 Worker 体积。之所以只剥离data:application/wasm而不动 OpenCV.js 的data:application/octet-stream是因为Worker 模式下 ORT 会在运行时通过ort.env.wasm.wasmPaths加载 WASM由使用方配置或回退到与安装 ORT 版本绑定的 CDN见 vite.config.ts 中的__ORT_WASM_CDN_PREFIX__而 OpenCV.js 经由 Emscripten 内联的 WASM 没有等价回退方案必须保留。该剥离必须放在主构建的generateBundle阶段而非 Worker 的 rollup 插件链中因为 Vite 是在 Worker 自身 Rollup 流程结束后才注入这些数据 URI 的。运行时层面ORT 环境的配置在 packages/core/src/runtime/ort.ts 中完成initOrtRuntime会先通过navigator.gpu探测 WebGPU 可用性detectWebGpuAvailability再依据backendwebgpu/wasm/auto生成执行提供者候选列表[[webgpu], [wasm]]createSession依次尝试候选 provider 直至成功applyOrtEnvironmentOptions则将wasmPaths、numThreads、simd、proxy等选项写入ort.env.wasm与文档所述运行时通过ort.env.wasm.wasmPaths加载 WASM完全对应。Demo 应用的开发与构建双模式apps/demo是一个 Vite 应用vite.config.js它在开发与生产两种模式下消费 SDK 的方式截然不同开发模式npm run dev:demoVite 通过resolve.alias将paddleocr/paddleocr-js与paddleocr/paddleocr-js/viz直接映射到packages/core/src/index.ts与packages/core/src/viz/index.ts的 TypeScript 源码SDK 代码与 demo 共享同一套 Vite 模块图改动即时反映获得完整的 HMR 体验无需先构建 SDK。生产模式npm run build:demoalias 置空demo 通过 npm workspaces 的链接机制消费 SDK 预构建的dist/demo 的package.json中paddleocr/paddleocr-js: *即 workspace 内部版本链接。此时libraryWorkerPlugin产出的兼容下游打包器的 Worker URL 形式发挥作用Vite 能正确识别并复制assets/worker-entry-*.js到 demo 构建产物中。此外demo 的 Vite 配置为server与preview都设置了 COOP/COEP 响应头Cross-Origin-Opener-Policy: same-origin与Cross-Origin-Embedder-Policy: credentialless。这是 WebAssembly 多线程SharedArrayBuffer场景的典型前置条件同时也说明在开发调试 Worker 推理路径时需要保证这些跨源隔离头生效。测试策略分层、轻量、面向浏览器测试由 Vitest 驱动根目录 vitest.config.js测试用例位于 packages/core/test策略分为三层配置解析与注册表行为的单元测试覆盖模型配置解析如model-config.test.ts、配置分支ocr-config-branches.test.ts、公共 API 与管道注册表public-api.test.ts、pipelines-index.test.ts等纯逻辑部分不依赖浏览器面向浏览器平台辅助函数的轻量级 jsdom 测试利用jsdom根 devDependency 中声明jsdom ^26.1.0模拟 DOM 环境验证platform/browser.ts、platform/worker.ts等平台层辅助函数platform-browser.test.ts、platform-worker.test.ts默认不运行大规模真实模型推理CI 中不下载真实模型执行端到端推理避免测试时间与网络依赖失控模型加载相关路径通过 mock 与 fixture如helpers/mock-ort-tensor.ts、tar-fixture.ts验证例如det-model.test.ts、rec-model.test.ts、runtime-ort.test.ts等。这种逻辑层单测 浏览器辅助层 jsdom 免真实模型的组合保证了测试既覆盖核心行为又保持快速稳定适合作为每次提交的回归防线。版本发布与 npm 分发SDK 的发布链路同样在仓库内闭环npm run release会先执行build:sdk再通过changeset publish发布见根 package.json 的release脚本与 monorepo.md 的说明。版本管理使用 Changesetsdemo 包在.changeset/config.json中被忽略不参与发布。packages/core还声明了prepublishOnly: npm run build确保任何npm publish/npm pack前都会自动重新构建避免发布陈旧产物。结合前面介绍的exports、files、sideEffects等字段整个 SDK 从开发、构建、测试到发布形成了一条面向 npm 生态的完整流水线。小结paddleocr-js的开发工程围绕浏览器端可用 npm 生态兼容这两个核心目标展开monorepo 用根目录统一调度构建与校验命令strictTypeChecked分级规则集保障类型安全Vite 库模式产出 ESM 双入口与自包含 Worker bundle而libraryWorkerPlugin的相对路径改写、Worker URL 拆分与 WASM 剥离三项后处理则精确解决了 SDK 被第三方项目引用时的资源解析问题。理解这条流水线无论你是要贡献 SDK 代码、扩展 demo 功能还是在自己的 Vite/Webpack 项目中集成paddleocr/paddleocr-js都能准确预期构建行为并快速定位问题。【免费下载链接】PaddleOCR飞桨多语言OCR工具包实用超轻量OCR系统支持80种语言识别提供数据标注与合成工具支持服务器、移动端、嵌入式及IoT设备端的训练与部署 Awesome multilingual OCR toolkits based on PaddlePaddle (practical ultra lightweight OCR system, support 80 languages recognition, provide data annotation and synthesis tools, support training and deployment among server, mobile, embedded and IoT devices)项目地址: https://gitcode.com/paddlepaddle/PaddleOCR创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门