@l1yp/file-viewer
v0.1.2
Published
In-browser file viewer for 60+ formats (office / archives / images / code / …) as a Vue 3 component. Bytes never leave the browser.
Maintainers
Readme
@l1yp/file-viewer
浏览器内的多格式文件查看器,封装成一个 Vue 3 组件。给它一个文件,它自动识别类型并完全在浏览器里解析渲染——文件字节不经过任何服务器。支持 60+ 种格式:Office 文档、压缩包、图片、代码、音频、证书、数据库、3D 模型、电子书……
从 chat-share-proxy 抽取。完整设计见仓库
frontend/docs/file-viewer-package-design.md。
特性
- 60+ 格式:docx/xlsx/pptx/pdf、zip/7z/rar/tar、png/tiff/psd/heic/dcm、csv/jsonl/sqlite、markdown/代码高亮、eml/mht/har、字体/证书/密钥库、epub/mob、drawio/dxf/geojson、hprof/.class/.so/.dll、易语言 .e/.ec 等。
- ZIP 网页预览:打开压缩包里的 HTML 时,自动解析并加载同包的 JS、CSS、图片、字体等相对依赖;源码保持原样,脚本仍需用户主动开启后才会在不透明源沙箱中运行。
- 零后端:上游字节只在浏览器解析;HTML/SVG 走沙箱 iframe、下载端点无法内联执行。
- 按需分包:每个查看器是独立的懒加载 chunk,打开 PDF 才拉 PDF 引擎;用不到的格式零成本。
- 重型依赖可选:只装你需要的格式的引擎;没装时显示「请安装 X」提示卡,不崩溃。
- 主题可定制:CSS 变量作用域限定在组件根,不污染宿主;
themeprop 或覆盖变量即可换肤。
安装
npm i @l1yp/file-viewer vuevue(>=3.5)是 peer 依赖。核心解析(代码高亮 / Markdown 数学 / frontmatter)依赖的 highlight.js / katex / js-yaml 会随包自动安装。
各重型格式的引擎是可选 peer 依赖——按需安装你要支持的格式:
| 格式 | 需额外安装 |
| --- | --- |
| PDF | pdfjs-dist |
| Word .docx | docx-preview |
| Excel .xlsx | exceljs numfmt |
| PowerPoint .pptx | @aiden0z/pptx-renderer pdfjs-dist |
| SQLite .sqlite/.db | sql.js |
| 3D 模型 .stl/.obj/.glb/… | three |
| 地图 .geojson/.kml/.gpx | maplibre-gl |
| Photoshop .psd | ag-psd |
| TIFF .tif/.tiff | utif2 |
| HEIC/HEIF | heic2any |
| EPUB | epubjs |
| DICOM .dcm | dicom-parser(JPEG2000/JPEG-LS 另需 @cornerstonejs/codec-openjpeg @cornerstonejs/codec-charls @cornerstonejs/codec-libjpeg-turbo-8bit) |
| RAR | node-unrar-js |
| Brotli 归档 .br | brotli-dec-wasm |
| 微信/QQ 语音(SILK/AMR) | silk-wasm @audio/decode-amr |
未安装某格式的引擎时,打开该文件会显示一张「预览 X 需要安装 <pkg>」的卡片(含一键复制安装命令 + 下载原文件),不会报错崩溃。
打包器提示:这些可选依赖在库构建里是
external。若你的打包器(Vite/webpack)对未安装的可选依赖在构建期报「无法解析」,把你不用的那几个加进 bundler 的 external /optimizeDeps.exclude即可。
使用
import { FileViewer } from '@l1yp/file-viewer'
import '@l1yp/file-viewer/style.css' // 必需:查看器的样式在这里<!-- 最简:URL + 文件名 -->
<FileViewer :src="url" name="report.csv" />
<!-- 内存字节(拖拽 / 上传的 File 直接喂) -->
<FileViewer :blob="file" :name="file.name" />
<!-- 需要鉴权的 URL:附加 fetch 配置,或用 load 完全自定义取字节 -->
<FileViewer
:input="{
src,
name,
mime,
size,
fetchConfig: { headers: { Authorization: `Bearer ${token}` } },
}"
theme="dark"
@loaded="onText"
@error="onError"
/>数据源(写在 input 上,或用同名简写 props)——四选一,优先级 text > blob > load > src:
| 字段 | 说明 |
| --- | --- |
| src | 可直接 fetch 的 URL(最常用) |
| blob | 内存字节(Blob/File) |
| text | 已解码文本(文本型查看器免网络) |
| fetchConfig | 附加到 fetch(src, …):headers/credentials/mode …(会触发一次性预取到 blob) |
| load | () => Promise<Blob \| ArrayBuffer>,自己拉字节(签名换取 / SDK) |
更底层的出口
import {
FileViewer, // ① 完整面板(含头部、下载、主题),ViewerInput 驱动
FileViewerBody, // ② 只有内容区,塞进你自己的外壳
classifyViewerFile, // 纯函数:文件 → 用哪个查看器,自己路由
isTextFile,
fileExt, // 类型判定辅助
resolveInput, // 把 ViewerInput 归一化成可 fetch 的源
} from '@l1yp/file-viewer'主题 / 样式
所有样式的 CSS 变量作用域限定在组件根 .fv-root,不碰宿主全局样式。三种定制方式:
themeprop:theme="light | dark | system | inherit"。inherit= 不设主题、直接吃宿主已定义的变量。- 覆盖 CSS 变量:在你自己的
.fv-root规则里改,例如.fv-root { --accent: #2563eb; --font-mono: 'JetBrains Mono', monospace; } - 复制
dist里的令牌整套替换。
数学公式:如需 Markdown 里的数学公式正常显示,宿主需自行
import 'katex/dist/katex.min.css'。 直接用低层的<FileViewerPanel>(不带.fv-root包裹)时,请自己定义那批 CSS 变量,或改用带.fv-root的<FileViewer>。
开发
pnpm -C packages/file-viewer type-check # vue-tsc 类型检查
pnpm -C packages/file-viewer build # vp build(JS 分包 + style.css)+ vue-tsc(.d.ts)发布
npm pack --dry-run # 预览将发布的文件(dist + README + LICENSE)
npm publish # publishConfig.access=public,已配好公开发布prepack 脚本会在打包/发布前自动重新构建。发布前记得在 package.json 补上 repository / homepage 字段。
构建产物会同时生成并发布 dist/**/*.js.map,其中包含原始 Vue / TypeScript 源码,使用者的构建工具和浏览器开发者工具可据此还原异常堆栈。
License
MIT
