# 纯 JS 集成
Vanilla JavaScript

纯 JS 包现在提供原生 <flyfish-file-viewer> 组件和 mountViewer(container, options) 两种标准入口。 推荐优先使用 Custom Element;需要完全命令式控制时再使用 controller 挂载。

## 标准安装 新项目优先使用标准包名: ```bash npm install @file-viewer/web @file-viewer/preset-office ``` 想要一步到位获得完整格式矩阵时,直接使用 full 包: ```bash npm install @file-viewer/web-full ``` `@file-viewer/web-full` 会自动启用完整格式矩阵,仍然暴露 ``、`mountViewer` 和同一套 controller API。它的 CDN / IIFE 首包只包含组件壳和 lazy full preset,PDF、Word、Excel、CAD、Typst、压缩包等重型 renderer 会在命中文件类型时异步加载对应 `dist/renderers/*.iife.js`。 历史包名仍同步维护: ```bash npm install @flyfish-group/file-viewer-web ``` ```html ``` ```ts import { defineFileViewerElement } from '@file-viewer/web' import officePreset from '@file-viewer/preset-office' defineFileViewerElement() const viewer = document.getElementById('viewer') as HTMLElement & { options: unknown zoomIn(): Promise printRenderedHtml(): Promise } viewer.options = { preset: officePreset, rendererMode: 'replace', theme: 'light', toolbar: { position: 'bottom-right' } } viewer.addEventListener('viewer-event', event => { console.log((event as CustomEvent).detail.type) }) viewer.zoomIn() ``` 元素容器需要有明确高度,预览器会填满组件本身。 如果项目使用 Vite,可以再加入 `@file-viewer/vite-plugin`。插件会自动发现已安装的 `@file-viewer/preset-*` 并注入 renderer,Custom Element 和 `mountViewer` 都能直接获得对应格式能力,业务代码可以省去上面的 preset import。注意:只安装插件包不会让 Vite 自动运行,仍需要在 `vite.config.ts` 注册一次: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts import { defineConfig } from 'vite' import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default defineConfig({ plugins: [ fileViewerRenderers({ copyAssets: true }) ] }) ``` 只安装 `@file-viewer/web` 是最轻的原生组件入口;PDF、Office、CAD、Typst、压缩包等具体格式能力请安装对应 preset 或 renderer。重度用户需要完整能力时,可以选择 full 包,也可以继续使用标准包 + `preset-all`: ```bash npm install @file-viewer/web @file-viewer/preset-all ``` 如果需要精确控制构建结果,Vite 插件再使用 `formats`、`renderers`、`scan:true`、`inject:false` 或 `chunkStrategy:'renderer'`;默认路径保持 `fileViewerRenderers({ copyAssets:true })`,插件会根据已安装 preset 自动激活能力。 ## 命令式挂载 需要在非组件化脚本里动态创建、替换或销毁预览器时,可以直接使用 `mountViewer`。它返回完整 controller: ```ts import { mountViewer } from '@file-viewer/web' import officePreset from '@file-viewer/preset-office' const controller = mountViewer(document.getElementById('viewer')!, { url: '/files/demo.pdf', options: { preset: officePreset, rendererMode: 'replace', theme: 'light', toolbar: { position: 'bottom-right' }, archive: { cache: true, workerTimeoutMs: 30000 } }, onEvent(event) { console.log(event.type, event.payload) } }) controller.reload() ``` 如果使用 full 包,命令式代码不需要再手动 import preset: ```ts import { mountViewer } from '@file-viewer/web-full' const controller = mountViewer(document.getElementById('viewer')!, { url: '/files/demo.dwg', options: { theme: 'light', toolbar: { position: 'bottom-right' } } }) controller.zoomIn() ``` ## 鉴权文件 业务系统可以先完成登录态、权限或签名校验,再把文件二进制交给预览器。传 `Blob` 或 `ArrayBuffer` 时请同时传 `name`: ```ts const blob = await fetch('/api/files/contract', { credentials: 'include' }).then(res => res.blob()) const viewer = document.querySelector('flyfish-file-viewer') viewer.file = blob viewer.name = 'contract.pdf' viewer.options = { theme: 'light' } ``` ## 构建工具接入 Vite、Webpack、Rspack、Rollup 等构建工具可以直接使用 ESM 包入口。构建工具会负责解析 `@file-viewer/web`、Vue 和底层预览依赖: ```ts import { defineFileViewerElement } from '@file-viewer/web' defineFileViewerElement() ``` 不要把 `dist/index.js` 复制到 public 后直接用浏览器加载。该入口保留了包依赖关系,面向构建工具和包管理器;无构建工具页面请使用下面的 IIFE 全局包。 ## 通过普通 script 引入 IIFE 包会暴露 `window.FlyfishFileViewerWeb`: ```bash cp ./node_modules/@file-viewer/web/dist/flyfish-file-viewer-web.iife.js ./public/vendor/file-viewer-web/flyfish-file-viewer-web.iife.js ``` ```html ``` IIFE 会自动执行 `defineFileViewerElement()` 并暴露 `window.FlyfishFileViewerWeb`。如果你更喜欢命令式方式,仍然可以使用 `window.FlyfishFileViewerWeb.mountViewer(container, options)`。 ### CDN full 完整能力 如果页面不使用构建工具,而且希望无需本地安装就快速接入完整格式矩阵,可以使用 `@file-viewer/web-full` 的 CDN 入口。jsDelivr / unpkg 会直接从 npm 分发完整 IIFE,它会暴露 `window.FlyfishFileViewerWebFull`。首包只加载组件壳和 lazy full preset,具体 PDF、Word、Excel、CAD、Typst、压缩包等 renderer 会在命中文件类型时异步加载 `dist/renderers/*.iife.js`,Worker、WASM、字体和 vendor 资源仍自动按脚本地址定位: ```html
``` Custom Element 也可以直接使用同一个 CDN full 包: ```html ``` CDN full 适合 POC、传统后台和公网生产页面快速获得完整能力。内网、严格 CSP、完全离线或自有 Cloudflare/CDNJS 风格静态域场景,把 `@file-viewer/web-full/dist` 或 `file-viewer-copy-assets` 生成的资源整体同步到自己的 CDN。cdnjs.com 不会自动托管任意 npm 包,只有库被收录后才会有真实 cdnjs 路径。 ## 自托管 Worker / WASM 资源 大多数业务只需要安装包即可。内网、CSP 严格、静态资源前缀特殊或希望固定重型资源路径时,建议把 viewer assets 复制到业务自己的静态目录: ```bash npx file-viewer-copy-assets ./public/file-viewer ``` 复制命令会写入 `flyfish-viewer-assets.json`,并校验 PDF、archive、DOCX、Excel、Draw.io、CAD、Typst、SQLite 等 worker/WASM/字体/vendor 静态资源是否齐全。预览运行时不会默认访问公共 CDN 或第三方在线资源;部署路径特殊时,可以在 `options.pdf.workerUrl`、`options.pdf.cMapUrl`、`options.pdf.wasmUrl`、`options.pdf.standardFontDataUrl`、`options.drawing.viewerScriptUrl`、`options.archive.workerUrl`、`options.archive.wasmUrl`、`options.docx.workerUrl`、`options.docx.workerJsZipUrl`、`options.spreadsheet.workerUrl`、`options.typst.compilerWasmUrl`、`options.typst.rendererWasmUrl`、`options.typst.fontAssetsUrl`、`options.data.sqlWasmUrl` 等参数中指定自托管地址。Draw.io 默认使用随 viewer assets 分发的官方 diagrams.net 离线 viewer,并在官方 viewer 不可用时回退内置 SVG。 ## API | API | 说明 | | --- | --- | | `` | 原生 Web Component,可用属性、property、事件和实例方法控制完整预览器 | | `defineFileViewerElement(tagName?)` | 注册 Custom Element;IIFE 包会自动注册默认标签 | | `mountViewer(container, options)` | 挂载预览器并返回 controller | | `controller.update(options)` | 更新文件或运行参数 | | `controller.reload()` | 重新加载当前文件 | | `controller.destroy()` | 卸载预览器并释放资源 | | `createViewerControllerHandle()` | 创建可复用的 controller handle,适合框架组件包封装 | ### Custom Element 属性和事件 | 类型 | 支持项 | | --- | --- | | HTML 属性 | `src` / `url`、`filename` / `name`、`type`、`size`、`locale`、`theme`、`toolbar`、`toolbar-position`、`watermark`、`search`、`options` | | JS property | `url`、`file`、`buffer`、`name`、`filename`、`type`、`size`、`locale`、`options`、`coreOptions`、`source` | | 原生事件 | `viewer-ready`、`viewer-event`、`viewer-state-change`、`viewer-error`,以及 `viewer-load-complete`、`viewer-search-change` 等按事件类型派发的细分事件 | | 实例方法 | `load`、`update`、`reload`、`destroy`、`downloadOriginalFile`、`printRenderedHtml`、`exportRenderedHtml`、`zoomIn`、`zoomOut`、`resetZoom`、`searchDocument`、`nextSearchResult`、`previousSearchResult`、`collectDocumentAnchors`、`scrollToAnchor`、`scrollToLine`、`getDocumentTextChunks`、`getOperationAvailability`、`getZoomState`、`getSearchState`、`subscribe` | `options` 与 Vanilla JS / Pure Web、Vue、React、jQuery、Svelte 标准组件包保持一致,支持主题、水印、搜索、统一缩放、下载、打印、导出 HTML、beforeOperation 前置校验、生命周期 hooks、压缩包缓存和格式专项参数。 ### 国际化 Custom Element 可以直接使用 `locale` 属性,也可以通过 `options.locale`、`options.messages` 或 `options.i18n` 定制: ```html ``` ```ts viewer.locale = 'zh-CN' viewer.options = { i18n: { locale: 'zh-CN', messages: { 'toolbar.print': '打印文档' } } } ``` ## 常见问题 | 现象 | 处理方式 | | --- | --- | | 控制台提示裸包名无法解析 | 使用构建工具打包,或在无构建页面使用 IIFE 全局包 | | 文件接口 401 | 由宿主页面先 `fetch` 成 `Blob`,再传 `file` + `name` | | 压缩包或 CAD 卡在资源加载 | 运行 `file-viewer-copy-assets`,并检查 worker/WASM 的 MIME、CSP 和访问路径 | | 页面空白 | 确认父容器有稳定高度,且传入文件带有可识别扩展名 |