fimo-vite 0.21.0-experimental.1
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.md +24 -0
- package/dist/plugins/content-sync.d.ts +11 -0
- package/dist/plugins/content-sync.js +40 -0
- package/dist/plugins/data-id.d.ts +3 -0
- package/dist/plugins/data-id.js +98 -0
- package/dist/plugins/fimo-config.d.ts +12 -0
- package/dist/plugins/fimo-config.js +68 -0
- package/dist/plugins/overlay.d.ts +3 -0
- package/dist/plugins/overlay.js +153 -0
- package/dist/plugins/robots.d.ts +10 -0
- package/dist/plugins/robots.js +56 -0
- package/dist/plugins/seo.d.ts +3 -0
- package/dist/plugins/seo.js +112 -0
- package/dist/plugins/server-config.d.ts +3 -0
- package/dist/plugins/server-config.js +36 -0
- package/dist/plugins/sitemap.d.ts +3 -0
- package/dist/plugins/sitemap.js +73 -0
- package/dist/plugins/translations.d.ts +11 -0
- package/dist/plugins/translations.js +600 -0
- package/dist/runtime/overlay-hmr.d.ts +2 -0
- package/dist/runtime/overlay-hmr.js +27 -0
- package/dist/runtime/overlay-runtime.d.ts +24 -0
- package/dist/runtime/overlay-runtime.js +103 -0
- package/dist/vite.d.ts +32 -0
- package/dist/vite.js +98 -0
- package/package.json +48 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Vite HMR build-error bridge.
|
|
2
|
+
//
|
|
3
|
+
// This file is served by vite (not embedded inline) so that vite's plugin
|
|
4
|
+
// pipeline transforms `import.meta.hot` into a real hot-context — inline
|
|
5
|
+
// `<script type="module">` blocks bypass that pipeline and `import.meta.hot`
|
|
6
|
+
// stays `undefined`. The inline overlay runtime (overlay-runtime.ts) exposes
|
|
7
|
+
// its helpers on `window.__fimoOverlay`, which we call here.
|
|
8
|
+
function api() {
|
|
9
|
+
if (typeof window === 'undefined') {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
return window.__fimoOverlay;
|
|
13
|
+
}
|
|
14
|
+
if (import.meta && import.meta.hot) {
|
|
15
|
+
import.meta.hot.on('vite:error', (data) => {
|
|
16
|
+
const a = api();
|
|
17
|
+
if (!a)
|
|
18
|
+
return;
|
|
19
|
+
const d = a.getErrorDetails(data);
|
|
20
|
+
a.mount();
|
|
21
|
+
a.notify('Build Error', d.message, d.stack);
|
|
22
|
+
});
|
|
23
|
+
import.meta.hot.on('vite:afterUpdate', () => {
|
|
24
|
+
api()?.unmount();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare const ID = "fimo-error-overlay";
|
|
2
|
+
declare function ensureStyles(): void;
|
|
3
|
+
declare function mountBlack(): void;
|
|
4
|
+
declare function unmount(): void;
|
|
5
|
+
declare function getErrorDetails(e: unknown): {
|
|
6
|
+
message: string;
|
|
7
|
+
stack: string;
|
|
8
|
+
};
|
|
9
|
+
declare function postToTargets(type: string, payload: {
|
|
10
|
+
heading: string;
|
|
11
|
+
message: string;
|
|
12
|
+
stack: string;
|
|
13
|
+
}): void;
|
|
14
|
+
declare function notify(heading: string, message: string, stack: string): void;
|
|
15
|
+
type FimoOverlayApi = {
|
|
16
|
+
mount: () => void;
|
|
17
|
+
unmount: () => void;
|
|
18
|
+
notify: (heading: string, message: string, stack: string) => void;
|
|
19
|
+
getErrorDetails: (e: unknown) => {
|
|
20
|
+
message: string;
|
|
21
|
+
stack: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=overlay-runtime.d.ts.map
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const ID = 'fimo-error-overlay';
|
|
3
|
+
function ensureStyles() {
|
|
4
|
+
if (document.getElementById(ID + '-styles')) {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
const s = document.createElement('style');
|
|
8
|
+
s.id = ID + '-styles';
|
|
9
|
+
s.textContent =
|
|
10
|
+
'vite-error-overlay, #vite-error-overlay, vite-overlay { display: none !important; }' +
|
|
11
|
+
'#' +
|
|
12
|
+
ID +
|
|
13
|
+
' { position: fixed; inset: 0; background: #000; z-index: 2147483647; display: none; }';
|
|
14
|
+
document.head.appendChild(s);
|
|
15
|
+
}
|
|
16
|
+
function mountBlack() {
|
|
17
|
+
ensureStyles();
|
|
18
|
+
let el = document.getElementById(ID);
|
|
19
|
+
if (!el) {
|
|
20
|
+
el = document.createElement('div');
|
|
21
|
+
el.id = ID;
|
|
22
|
+
document.body.appendChild(el);
|
|
23
|
+
}
|
|
24
|
+
el.style.display = 'block';
|
|
25
|
+
}
|
|
26
|
+
function unmount() {
|
|
27
|
+
const el = document.getElementById(ID);
|
|
28
|
+
if (el) {
|
|
29
|
+
el.style.display = 'none';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function getErrorDetails(e) {
|
|
33
|
+
try {
|
|
34
|
+
// Preserve the original loose extraction logic but in typed form
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
+
const anyErr = e && e.error ? e.error : e;
|
|
37
|
+
let err = null;
|
|
38
|
+
if (!anyErr) {
|
|
39
|
+
err = null;
|
|
40
|
+
}
|
|
41
|
+
else if (anyErr.error) {
|
|
42
|
+
err = anyErr.error;
|
|
43
|
+
}
|
|
44
|
+
else if (anyErr.reason) {
|
|
45
|
+
err = anyErr.reason;
|
|
46
|
+
}
|
|
47
|
+
else if (anyErr.err) {
|
|
48
|
+
err = anyErr.err;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
err = anyErr;
|
|
52
|
+
}
|
|
53
|
+
const message = typeof err === 'string' ? err : err && err.message ? err.message : String(err || 'Unknown error');
|
|
54
|
+
const stack = err && err.stack ? String(err.stack) : '';
|
|
55
|
+
return { message, stack };
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return { message: 'Unknown error', stack: '' };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function postToTargets(type, payload) {
|
|
62
|
+
const data = { type, payload };
|
|
63
|
+
try {
|
|
64
|
+
if (window.parent && window.parent !== window) {
|
|
65
|
+
window.parent.postMessage(data, '*');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// ignore
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
if (window.top && window.top !== window && window.top !== window.parent) {
|
|
73
|
+
window.top.postMessage(data, '*');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// ignore
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function notify(heading, message, stack) {
|
|
81
|
+
const payload = { heading, message, stack };
|
|
82
|
+
// First, send a preview-level error so the parent can perform a minimal handshake
|
|
83
|
+
// and lock onto the sandbox origin in build-error scenarios.
|
|
84
|
+
postToTargets('preview/error', payload);
|
|
85
|
+
// Then, send the existing app-level error used by the UI overlay.
|
|
86
|
+
postToTargets('app/error', payload);
|
|
87
|
+
}
|
|
88
|
+
window.addEventListener('error', (e) => {
|
|
89
|
+
const d = getErrorDetails(e);
|
|
90
|
+
mountBlack();
|
|
91
|
+
notify('Runtime Error', d.message, d.stack);
|
|
92
|
+
});
|
|
93
|
+
window.addEventListener('unhandledrejection', (e) => {
|
|
94
|
+
const d = getErrorDetails(e);
|
|
95
|
+
mountBlack();
|
|
96
|
+
notify('Runtime Error', d.message, d.stack);
|
|
97
|
+
});
|
|
98
|
+
window.__fimoOverlay = {
|
|
99
|
+
mount: mountBlack,
|
|
100
|
+
unmount,
|
|
101
|
+
notify,
|
|
102
|
+
getErrorDetails,
|
|
103
|
+
};
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PluginOption } from 'vite';
|
|
2
|
+
export interface FimoViteOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Emit `sitemap.xml` at build (and serve at `/sitemap.xml` in dev). Reads
|
|
5
|
+
* `seo.url` from `.fimo/config.json` as the base URL.
|
|
6
|
+
*
|
|
7
|
+
* Opt-in via `fimo({ sitemap: true })`.
|
|
8
|
+
*/
|
|
9
|
+
sitemap?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Emit `robots.txt` at build (and serve at `/robots.txt` in dev). Defaults
|
|
12
|
+
* to an allow-all robots policy + a `Sitemap:` directive when `seo.url` is
|
|
13
|
+
* set in `.fimo/config.json`.
|
|
14
|
+
*
|
|
15
|
+
* Opt-in via `fimo({ robots: true })`.
|
|
16
|
+
*/
|
|
17
|
+
robots?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Inject SEO meta tags into `index.html` via `transformIndexHtml`. Resolves
|
|
20
|
+
* per-route SEO from `.fimo/config.json#seo` and the matched route.
|
|
21
|
+
*
|
|
22
|
+
* Only applies in projects that have an `index.html` (plain Vite). Conflicts
|
|
23
|
+
* with frameworks that have their own SEO mechanism — React Router's `meta`
|
|
24
|
+
* export, Astro's frontmatter, Next.js's `generateMetadata`. Use those
|
|
25
|
+
* instead via the framework adapter's SEO helpers.
|
|
26
|
+
*
|
|
27
|
+
* Opt-in via `fimo({ seo: true })` — only documented in the plain-Vite recipe.
|
|
28
|
+
*/
|
|
29
|
+
seo?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare function fimo(opts?: FimoViteOptions): PluginOption[];
|
|
32
|
+
//# sourceMappingURL=vite.d.ts.map
|
package/dist/vite.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import runtimeEnvPlugin from 'fimo/vite/runtime-env';
|
|
2
|
+
import contentSyncPlugin from './plugins/content-sync.js';
|
|
3
|
+
import dataIdPlugin from './plugins/data-id.js';
|
|
4
|
+
import fimoConfigPlugin from './plugins/fimo-config.js';
|
|
5
|
+
import overlayPlugin from './plugins/overlay.js';
|
|
6
|
+
import robotsPlugin from './plugins/robots.js';
|
|
7
|
+
import seoPlugin from './plugins/seo.js';
|
|
8
|
+
import serverConfigPlugin from './plugins/server-config.js';
|
|
9
|
+
import sitemapPlugin from './plugins/sitemap.js';
|
|
10
|
+
import translationsPlugin from './plugins/translations.js';
|
|
11
|
+
// Force-bundle fimo into the SSR build, and let the dev optimizer pre-bundle
|
|
12
|
+
// it for the client. fimo's runtime imports `virtual:fimo-config` /
|
|
13
|
+
// `virtual:translations` / `virtual:fimo-overlay-*` — Vite-only specifiers
|
|
14
|
+
// resolved by sibling plugins — which esbuild can't see.
|
|
15
|
+
//
|
|
16
|
+
// Two places this matters:
|
|
17
|
+
// 1. SSR build: bundle fimo into dist/server (top-level `ssr.noExternal`
|
|
18
|
+
// + per-environment `configEnvironment` for react-router 7.15+, which
|
|
19
|
+
// doesn't merge viteUserConfig.environments.ssr for the default
|
|
20
|
+
// non-serverBundles case). Rollup resolves the virtuals through the
|
|
21
|
+
// plugin container, so SSR needs no special-casing.
|
|
22
|
+
// 2. Dev dep scan + optimization: esbuild chokes on `virtual:` ("Could not
|
|
23
|
+
// resolve 'virtual:fimo-config'"). The previous fix excluded the whole
|
|
24
|
+
// package from optimizeDeps, which served every runtime file as an
|
|
25
|
+
// individual module request (~34 extra round-trips per cold preview
|
|
26
|
+
// load through the sandbox proxy). Instead, externalize just the
|
|
27
|
+
// virtual specifiers — kept BARE (`virtual:fimo-config`, not an
|
|
28
|
+
// `/@id/`-prefixed URL): vite:import-analysis re-transforms optimized
|
|
29
|
+
// dep chunks and resolves bare specifiers through the plugin container,
|
|
30
|
+
// rewriting them to `/@id/` URLs itself. A pre-prefixed path fails that
|
|
31
|
+
// resolve ("Failed to resolve import '/@id/virtual:fimo-config'").
|
|
32
|
+
//
|
|
33
|
+
// Only `fimo` is named here. A framework package that also imports the
|
|
34
|
+
// virtual modules (fimo-react-router does) contributes its own package names
|
|
35
|
+
// through its own plugin; Vite concatenates the array config both return.
|
|
36
|
+
function bundleFimoIntoSsrPlugin() {
|
|
37
|
+
return {
|
|
38
|
+
name: 'vite-plugin-fimo-ssr-bundle',
|
|
39
|
+
config: () => ({
|
|
40
|
+
ssr: { noExternal: ['fimo'] },
|
|
41
|
+
optimizeDeps: {
|
|
42
|
+
rolldownOptions: {
|
|
43
|
+
plugins: [
|
|
44
|
+
{
|
|
45
|
+
name: 'fimo-externalize-virtuals',
|
|
46
|
+
resolveId(id) {
|
|
47
|
+
if (id.startsWith('virtual:')) {
|
|
48
|
+
return {
|
|
49
|
+
id,
|
|
50
|
+
external: true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
}),
|
|
59
|
+
configEnvironment(name, config) {
|
|
60
|
+
if (name !== 'ssr')
|
|
61
|
+
return;
|
|
62
|
+
const existing = config.resolve?.noExternal;
|
|
63
|
+
const merged = existing === true
|
|
64
|
+
? true
|
|
65
|
+
: Array.isArray(existing)
|
|
66
|
+
? [...existing, 'fimo']
|
|
67
|
+
: existing
|
|
68
|
+
? [existing, 'fimo']
|
|
69
|
+
: ['fimo'];
|
|
70
|
+
return {
|
|
71
|
+
resolve: { noExternal: merged },
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// NOTE: dataIdPlugin must run before anything else to capture valid line numbers.
|
|
77
|
+
export function fimo(opts = {}) {
|
|
78
|
+
const plugins = [
|
|
79
|
+
runtimeEnvPlugin(),
|
|
80
|
+
bundleFimoIntoSsrPlugin(),
|
|
81
|
+
contentSyncPlugin(),
|
|
82
|
+
serverConfigPlugin(),
|
|
83
|
+
fimoConfigPlugin(),
|
|
84
|
+
dataIdPlugin(),
|
|
85
|
+
translationsPlugin(),
|
|
86
|
+
overlayPlugin(),
|
|
87
|
+
];
|
|
88
|
+
if (opts.sitemap) {
|
|
89
|
+
plugins.push(sitemapPlugin());
|
|
90
|
+
}
|
|
91
|
+
if (opts.robots) {
|
|
92
|
+
plugins.push(robotsPlugin());
|
|
93
|
+
}
|
|
94
|
+
if (opts.seo) {
|
|
95
|
+
plugins.push(seoPlugin());
|
|
96
|
+
}
|
|
97
|
+
return plugins;
|
|
98
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fimo-vite",
|
|
3
|
+
"version": "0.21.0-experimental.1",
|
|
4
|
+
"description": "Framework-neutral Fimo Vite plugin. Pairs with the fimo package at the same version.",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist/",
|
|
7
|
+
"!dist/**/*.d.ts.map",
|
|
8
|
+
"README.md"
|
|
9
|
+
],
|
|
10
|
+
"type": "module",
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"exports": {
|
|
13
|
+
"./package.json": "./package.json",
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/vite.d.ts",
|
|
16
|
+
"import": "./dist/vite.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc -b tsconfig.json",
|
|
24
|
+
"check:types": "tsc -b tsconfig.json --noEmit",
|
|
25
|
+
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:watch": "vitest"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@rollup/pluginutils": "^5.1.0",
|
|
31
|
+
"oxc-parser": "^0.118.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@fimo/tsconfig": "0.21.0-experimental.1",
|
|
35
|
+
"@types/node": "^22.15.29",
|
|
36
|
+
"fimo": "0.21.0-experimental.1",
|
|
37
|
+
"typescript": "7.0.2",
|
|
38
|
+
"vite": "^8.0.13",
|
|
39
|
+
"vitest": "^4.1.6"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"fimo": ">=0.14.0",
|
|
43
|
+
"vite": "^7.0.0 || ^8.0.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.12.0"
|
|
47
|
+
}
|
|
48
|
+
}
|