@file-viewer/vite-plugin 3.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +7 -0
- package/README.md +7 -0
- package/dist/index.js +62 -27
- package/package.json +5 -3
package/README.en.md
CHANGED
|
@@ -147,6 +147,13 @@ This is useful when upload accept lists, sample matrices, or attachment allow-li
|
|
|
147
147
|
|
|
148
148
|
When a file extension is in the supported matrix but the current project has not assembled its renderer, core now shows an install-oriented “renderer assembly required” state with the recommended preset / renderer package. For example, `.pdf` points to `@file-viewer/preset-office` or `@file-viewer/renderer-pdf`. Only truly unknown extensions show an unsupported-format state.
|
|
149
149
|
|
|
150
|
+
## Nested Vite Projects
|
|
151
|
+
|
|
152
|
+
From 3.0.3, a nested metadata-only project can use a resolvable Full dependency
|
|
153
|
+
declared in an ancestor `package.json`. A nearer light component or preset keeps
|
|
154
|
+
its own root asset layout. Explicit `copyAssets.baseDir` still takes precedence;
|
|
155
|
+
`publicDir` and `build.outDir` stay relative to the Vite root, not the dependency owner.
|
|
156
|
+
|
|
150
157
|
## Current Boundary
|
|
151
158
|
|
|
152
159
|
The plugin currently generates imports for extracted renderer packages: Word, Spreadsheet, PDF, OFD, Presentation, CAD, Draw.io/Excalidraw/Mermaid/PlantUML, 3D, Data, EDA, Typst, archives, email, EPUB, code/Markdown/Patch/Git Bundle, image, media, XMind, and Geo. Declare them explicitly with `formats`, or let `scan: true` discover source hints automatically; core-supported extensions such as `.zipx`, `.cbz`, `.tiff`, `.mjs`, `.gv`, `.patch`, `.bundle`, `.mermaid`, `.puml`, and `.mpeg` also resolve to their renderer packages. With `copyAssets:true`, the plugin detects installed capability packages. Full packages copy matching assets into dev `publicDir/file-viewer/` and production `outDir/file-viewer/`; standard packages/presets keep the existing root placement, including the Typst compiler / renderer WASM files and default fonts. `preset: 'auto' | 'lite' | 'office' | 'engineering' | 'all'` imports matching `@file-viewer/preset-*` packages; when `formats` are also present, the plugin adds extra renderers outside the preset.
|
package/README.md
CHANGED
|
@@ -147,6 +147,13 @@ export const fileViewerFormats = ['pdf', 'docx', 'xlsx']
|
|
|
147
147
|
|
|
148
148
|
如果用户打开的是支持矩阵内的格式,但项目没有安装或装配对应 renderer,core 会显示“需要装配预览能力”,并提示推荐安装的 preset / renderer 包,例如 `.pdf` 会引导安装 `@file-viewer/preset-office` 或 `@file-viewer/renderer-pdf`。只有真正不在支持矩阵中的扩展名才显示“不支持在线预览”。
|
|
149
149
|
|
|
150
|
+
## 嵌套 Vite 项目
|
|
151
|
+
|
|
152
|
+
从 3.0.3 起,子目录只有项目元数据或 Vite 插件声明时,会沿祖先 `package.json`
|
|
153
|
+
查找实际可解析的 Full 依赖。子项目明确声明轻量组件或 preset 时保留其根目录资产布局,
|
|
154
|
+
不会继承父项目的 Full 布局。`copyAssets.baseDir` 仍具有最高优先级;`publicDir`
|
|
155
|
+
和 `build.outDir` 均相对于 Vite root,不相对于依赖所在目录。
|
|
156
|
+
|
|
150
157
|
## 当前边界
|
|
151
158
|
|
|
152
159
|
当前插件会为已经拆出的 renderer 包生成导入:Word、Spreadsheet、PDF、OFD、Presentation、CAD、Draw.io/Excalidraw/Mermaid/PlantUML、3D、Data、EDA、Typst、压缩包、邮件、EPUB、代码/Markdown/Patch/Git Bundle、图片、媒体、XMind 和 Geo。可以通过 `formats` 显式声明,也可以通过 `scan: true` 从源码 hint 自动发现;`.zipx`、`.cbz`、`.tiff`、`.mjs`、`.gv`、`.patch`、`.bundle`、`.mermaid`、`.puml`、`.mpeg` 等 core 支持的扩展也会映射到对应 renderer。开启 `copyAssets:true` 时会识别已安装能力;full 包把匹配资源复制到开发 `publicDir/file-viewer/` 与构建 `outDir/file-viewer/`,标准包/preset 维持根目录行为,包括 Typst compiler / renderer WASM 与默认字体目录。`preset: 'auto' | 'lite' | 'office' | 'engineering' | 'all'` 会导入对应 `@file-viewer/preset-*` 包;如果同时声明 `formats`,插件会在 preset 之外补充额外 renderer。
|
package/dist/index.js
CHANGED
|
@@ -465,6 +465,15 @@ const rendererModules = [
|
|
|
465
465
|
rendererIds: ['data-asset'],
|
|
466
466
|
chunkName: 'file-viewer-data'
|
|
467
467
|
},
|
|
468
|
+
{
|
|
469
|
+
id: 'binary',
|
|
470
|
+
packageName: '@file-viewer/renderer-binary',
|
|
471
|
+
exportName: 'binaryRenderer',
|
|
472
|
+
formats: ['binary', 'binary-inspector', 'bin', 'hex', 'elf', 'exe', 'dll', 'class', 'macho'],
|
|
473
|
+
rendererIds: ['binary-inspector'],
|
|
474
|
+
chunkName: 'file-viewer-binary',
|
|
475
|
+
includeInPresetAll: false
|
|
476
|
+
},
|
|
468
477
|
{
|
|
469
478
|
id: 'eda',
|
|
470
479
|
packageName: '@file-viewer/renderer-eda',
|
|
@@ -1483,6 +1492,21 @@ async function copyPdfCjkFontAssets(from, to) {
|
|
|
1483
1492
|
await copyFile(license, join(to, 'OFL-1.1.txt'));
|
|
1484
1493
|
return true;
|
|
1485
1494
|
}
|
|
1495
|
+
function hasPdfCjkFontAssets(root, stylesheet, license) {
|
|
1496
|
+
if (!root) {
|
|
1497
|
+
return false;
|
|
1498
|
+
}
|
|
1499
|
+
const files = join(root, 'files');
|
|
1500
|
+
try {
|
|
1501
|
+
return (existsSync(join(root, stylesheet)) &&
|
|
1502
|
+
existsSync(join(root, license)) &&
|
|
1503
|
+
statSync(files).isDirectory() &&
|
|
1504
|
+
readdirSync(files, { withFileTypes: true }).some((entry) => entry.isFile() && entry.name.endsWith('.woff2')));
|
|
1505
|
+
}
|
|
1506
|
+
catch {
|
|
1507
|
+
return false;
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1486
1510
|
async function copyKnownRendererAssets(targetRoot, rendererIds) {
|
|
1487
1511
|
const selected = new Set(rendererIds);
|
|
1488
1512
|
const results = [];
|
|
@@ -1551,25 +1575,24 @@ async function copyKnownRendererAssets(targetRoot, rendererIds) {
|
|
|
1551
1575
|
'@file-viewer/renderer-pdf'
|
|
1552
1576
|
]);
|
|
1553
1577
|
const pdfCjkFontTarget = join(targetRoot, 'vendor/pdf/fonts');
|
|
1554
|
-
// The
|
|
1555
|
-
//
|
|
1556
|
-
//
|
|
1557
|
-
|
|
1558
|
-
const
|
|
1559
|
-
|
|
1560
|
-
|
|
1578
|
+
// The PDF renderer owns the runtime font dependency so direct renderer installs retain
|
|
1579
|
+
// CJK fallback support. The standard profile pack is only a pre-staged copy source.
|
|
1580
|
+
// A missing source means an incomplete install and must not silently drop the fallback.
|
|
1581
|
+
const hasStandardPdfCjkFont = hasPdfCjkFontAssets(standardPdfCjkFontRoot, 'noto-sans-sc.css', 'OFL-1.1.txt');
|
|
1582
|
+
const hasStagedPdfCjkFont = hasPdfCjkFontAssets(stagedPdfCjkFontRoot, 'wght.css', 'LICENSE');
|
|
1583
|
+
const hasDependencyPdfCjkFont = hasPdfCjkFontAssets(dependencyPdfCjkFontRoot, 'wght.css', 'LICENSE');
|
|
1584
|
+
const pdfCjkFontSourceAvailable = hasStandardPdfCjkFont || hasStagedPdfCjkFont || hasDependencyPdfCjkFont;
|
|
1561
1585
|
await push('pdf', 'pdf-cjk-font-fallback', pdfCjkFontTarget, async () => {
|
|
1562
|
-
if (standardPdfCjkFontRoot
|
|
1563
|
-
existsSync(join(standardPdfCjkFontRoot, 'noto-sans-sc.css'))) {
|
|
1586
|
+
if (hasStandardPdfCjkFont && standardPdfCjkFontRoot) {
|
|
1564
1587
|
return copyDirectoryIfPresent(standardPdfCjkFontRoot, pdfCjkFontTarget);
|
|
1565
1588
|
}
|
|
1566
|
-
if (
|
|
1589
|
+
if (hasStagedPdfCjkFont && stagedPdfCjkFontRoot) {
|
|
1567
1590
|
return copyPdfCjkFontAssets(stagedPdfCjkFontRoot, pdfCjkFontTarget);
|
|
1568
1591
|
}
|
|
1569
1592
|
return copyPdfCjkFontAssets(dependencyPdfCjkFontRoot, pdfCjkFontTarget);
|
|
1570
1593
|
}, pdfCjkFontSourceAvailable
|
|
1571
1594
|
? undefined
|
|
1572
|
-
: `
|
|
1595
|
+
: `repair @file-viewer/renderer-pdf and its @fontsource-variable/noto-sans-sc dependency`, undefined, true);
|
|
1573
1596
|
const pptxRoot = resolvePackageRoot('@file-viewer/pptx', [
|
|
1574
1597
|
'@file-viewer/renderer-pptx',
|
|
1575
1598
|
'@file-viewer/renderer-presentation'
|
|
@@ -2066,25 +2089,37 @@ function findNearestProjectPackageJson(projectRoot) {
|
|
|
2066
2089
|
}
|
|
2067
2090
|
}
|
|
2068
2091
|
function resolveInstalledFullPackages(projectRoot) {
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
}
|
|
2092
|
+
let packageJsonPath = findNearestProjectPackageJson(projectRoot);
|
|
2093
|
+
const lightPackages = fileViewerFullPackages.map(packageName => packageName.replace(/-full$/, ''));
|
|
2094
|
+
const projectPackageRequire = createRequire(join(resolve(projectRoot), 'package.json'));
|
|
2073
2095
|
try {
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2096
|
+
while (packageJsonPath) {
|
|
2097
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
2098
|
+
const declaredPackages = new Set([
|
|
2099
|
+
...Object.keys(packageJson.dependencies || {}),
|
|
2100
|
+
...Object.keys(packageJson.devDependencies || {}),
|
|
2101
|
+
...Object.keys(packageJson.optionalDependencies || {}),
|
|
2102
|
+
...Object.keys(packageJson.peerDependencies || {})
|
|
2103
|
+
]);
|
|
2104
|
+
const declaresRuntime = [...declaredPackages].some(packageName => fileViewerFullPackages.some(fullPackage => fullPackage === packageName) ||
|
|
2105
|
+
lightPackages.includes(packageName) ||
|
|
2106
|
+
packageName.startsWith('@file-viewer/preset-') ||
|
|
2107
|
+
packageName.startsWith('@file-viewer/renderer-'));
|
|
2108
|
+
if (declaresRuntime) {
|
|
2109
|
+
return fileViewerFullPackages.filter(packageName => declaredPackages.has(packageName) &&
|
|
2110
|
+
Boolean(tryResolvePackageJson(packageName, projectPackageRequire)));
|
|
2111
|
+
}
|
|
2112
|
+
// Vite roots can contain a metadata-only package.json while runtime
|
|
2113
|
+
// dependencies live in an ancestor. A nearer light runtime is a boundary.
|
|
2114
|
+
const directory = dirname(packageJsonPath);
|
|
2115
|
+
const parent = dirname(directory);
|
|
2116
|
+
packageJsonPath = parent === directory ? null : findNearestProjectPackageJson(parent);
|
|
2117
|
+
}
|
|
2084
2118
|
}
|
|
2085
2119
|
catch {
|
|
2086
2120
|
return [];
|
|
2087
2121
|
}
|
|
2122
|
+
return [];
|
|
2088
2123
|
}
|
|
2089
2124
|
function resolveInstalledAssetPackages(projectRoot) {
|
|
2090
2125
|
const packageJsonPath = findNearestProjectPackageJson(projectRoot);
|
|
@@ -2341,7 +2376,7 @@ export function fileViewerRenderers(options = {}) {
|
|
|
2341
2376
|
const projectRoot = resolve(process.cwd(), userConfig.root || '.');
|
|
2342
2377
|
refreshSelection(projectRoot);
|
|
2343
2378
|
refreshFullAssetRuntime(projectRoot, userConfig.base);
|
|
2344
|
-
const dependencyAnchorPackages = collectDependencyAnchorPackages(selection, autoPresetIds);
|
|
2379
|
+
const dependencyAnchorPackages = collectDependencyAnchorPackages(selection, installedFullPackages.length ? unique([...autoPresetIds, 'all']) : autoPresetIds);
|
|
2345
2380
|
const resolvedDependencyAnchorPackages = runtimeAssetBase
|
|
2346
2381
|
? unique([
|
|
2347
2382
|
...dependencyAnchorPackages,
|
|
@@ -2525,7 +2560,7 @@ export function fileViewerRenderers(options = {}) {
|
|
|
2525
2560
|
return [];
|
|
2526
2561
|
},
|
|
2527
2562
|
async closeBundle() {
|
|
2528
|
-
if (!options.copyAssets || copyOptions(options.copyAssets).mode === 'dev') {
|
|
2563
|
+
if (resolvedConfig?.command === 'serve' || !options.copyAssets || copyOptions(options.copyAssets).mode === 'dev') {
|
|
2529
2564
|
return;
|
|
2530
2565
|
}
|
|
2531
2566
|
const copyTarget = resolveFileViewerCopyAssetsTarget('build', options.copyAssets, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@file-viewer/vite-plugin",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Vite plugin for File Viewer on-demand renderer assembly, chunk planning, and offline asset deployment.",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@types/node": "^26.
|
|
66
|
+
"@types/node": "^26.5.0",
|
|
67
67
|
"typescript": "^6.0.3",
|
|
68
68
|
"vite": "^8.2.2"
|
|
69
69
|
},
|
|
@@ -71,6 +71,8 @@
|
|
|
71
71
|
"scripts": {
|
|
72
72
|
"build": "tsc -b tsconfig.json",
|
|
73
73
|
"type-check": "tsc -b tsconfig.json",
|
|
74
|
-
"verify:github-242": "node scripts/verify-github-242.mjs"
|
|
74
|
+
"verify:github-242": "pnpm build && node scripts/verify-github-242.mjs && node scripts/verify-github-242-copy.mjs",
|
|
75
|
+
"verify:github-257": "pnpm build && node scripts/verify-github-257.mjs",
|
|
76
|
+
"verify:github-257-browser": "npm exec --yes --package playwright@1.61.1 -- node scripts/verify-github-257-browser.mjs"
|
|
75
77
|
}
|
|
76
78
|
}
|