fimo-react-router 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/dist/vite.js ADDED
@@ -0,0 +1,104 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { fimo as fimoVite } from 'fimo-vite';
4
+ const REACT_ROUTER_CONFIG_FILES = [
5
+ 'react-router.config.ts',
6
+ 'react-router.config.js',
7
+ 'react-router.config.mjs',
8
+ 'react-router.config.cjs',
9
+ ];
10
+ /**
11
+ * Whether the project at `root` is a React Router framework-mode app.
12
+ *
13
+ * Gates the one framework-mode-only line below, so a plain-Vite React project
14
+ * that uses `BrowserRouter` never inherits it. Checks the manifest first: the
15
+ * config file can carry any of four extensions, but framework mode is
16
+ * impossible without `@react-router/dev`.
17
+ */
18
+ export function isReactRouterProject(root) {
19
+ try {
20
+ const pkg = JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8'));
21
+ if (pkg.devDependencies?.['@react-router/dev'] ?? pkg.dependencies?.['@react-router/dev']) {
22
+ return true;
23
+ }
24
+ }
25
+ catch {
26
+ // No readable manifest — fall through to the config-file probe.
27
+ }
28
+ return REACT_ROUTER_CONFIG_FILES.some((file) => existsSync(join(root, file)));
29
+ }
30
+ // Everything React-specific about dependency optimization lives here; the
31
+ // neutral half (virtual-module externalization, `ssr.noExternal: ['fimo']`)
32
+ // stays in `fimo-vite`. Vite concatenates array config across plugins, so the
33
+ // two merge additively.
34
+ function reactRouterOptimizeDepsPlugin() {
35
+ return {
36
+ name: 'vite-plugin-fimo-react-router-optimize-deps',
37
+ config: (userConfig) => ({
38
+ ssr: { noExternal: ['fimo-react', 'fimo-react-router'] },
39
+ optimizeDeps: {
40
+ // Compatibility shim for React Router projects scaffolded before the
41
+ // template set `future.unstable_optimizeDeps`. React Router passes
42
+ // Vite an EMPTY `entries` array without that flag (see
43
+ // getOptimizeDepsEntries in @react-router/dev), so NOTHING is
44
+ // pre-bundled: every dep a route imports is discovered on that
45
+ // route's first visit, and vite answers by re-optimizing and
46
+ // full-reloading the document. In the preview that reads as "links
47
+ // aren't SPA links" — client state lost, plus a transient duplicate
48
+ // React while the new chunks land.
49
+ //
50
+ // Gated on React Router framework mode, and assumes sources live in
51
+ // `src/`. The flag supersedes it (it derives entries from the real
52
+ // route table, whatever the appDirectory) and the two merge additively
53
+ // — drop this once no supported project predates the flag.
54
+ ...(isReactRouterProject(typeof userConfig.root === 'string' ? userConfig.root : process.cwd())
55
+ ? { entries: ['src/**/*.{ts,tsx,js,jsx}'] }
56
+ : {}),
57
+ // Pre-include the scanner-invisible dependency surface. The scanner
58
+ // can't traverse the Fimo runtime packages (virtual: imports), so deps
59
+ // reached only THROUGH them (react-router, the internal react-query
60
+ // usage, the error boundary) get discovered mid-first-load — vite
61
+ // re-optimizes and 504s the in-flight generation's chunks ("Outdated
62
+ // Optimize Dep") and the app never mounts (blank preview; caught by
63
+ // content/query e2e).
64
+ // react/react-dom/react-router are listed too: the template imports
65
+ // them, but the Fimo packages' imports of them are invisible to the
66
+ // scan, so leaving them to discovery makes the first optimize pass
67
+ // depend on which entry the browser happens to request first.
68
+ include: [
69
+ 'react',
70
+ 'react-dom',
71
+ 'react-router',
72
+ 'react-error-boundary',
73
+ 'fimo-react',
74
+ 'fimo-react-router',
75
+ '@tanstack/react-query',
76
+ ],
77
+ },
78
+ }),
79
+ configEnvironment(name, config) {
80
+ if (name !== 'ssr')
81
+ return;
82
+ const existing = config.resolve?.noExternal;
83
+ const merged = existing === true
84
+ ? true
85
+ : Array.isArray(existing)
86
+ ? [...existing, 'fimo-react', 'fimo-react-router']
87
+ : existing
88
+ ? [existing, 'fimo-react', 'fimo-react-router']
89
+ : ['fimo-react', 'fimo-react-router'];
90
+ return {
91
+ resolve: { noExternal: merged },
92
+ };
93
+ },
94
+ };
95
+ }
96
+ /**
97
+ * The Fimo Vite plugin for React Router projects: `fimo-vite`'s neutral
98
+ * plugins plus the React/React-Router dependency pre-bundling those projects
99
+ * need. Options are `fimo-vite`'s; `seo` applies to a plain Vite index.html,
100
+ * while React Router framework mode owns SEO through route `meta` exports.
101
+ */
102
+ export function fimo(opts = {}) {
103
+ return [...fimoVite(opts), reactRouterOptimizeDepsPlugin()];
104
+ }
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "fimo-react-router",
3
+ "version": "0.21.0-experimental.1",
4
+ "description": "Fimo runtime, routing and build integration for React Router projects. 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/index.d.ts",
16
+ "import": "./dist/index.js"
17
+ },
18
+ "./routes": {
19
+ "types": "./dist/routes.d.ts",
20
+ "import": "./dist/routes.js"
21
+ },
22
+ "./preset": {
23
+ "types": "./dist/preset.d.ts",
24
+ "import": "./dist/preset.js"
25
+ },
26
+ "./vite": {
27
+ "types": "./dist/vite.d.ts",
28
+ "import": "./dist/vite.js"
29
+ }
30
+ },
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "scripts": {
35
+ "build": "tsc -b tsconfig.json",
36
+ "check:types": "tsc -b tsconfig.json --noEmit",
37
+ "clean": "rm -rf dist tsconfig.tsbuildinfo",
38
+ "test": "vitest run",
39
+ "test:watch": "vitest"
40
+ },
41
+ "dependencies": {
42
+ "fimo-react": "0.21.0-experimental.1",
43
+ "fimo-vite": "0.21.0-experimental.1",
44
+ "react-error-boundary": "^6.0.0"
45
+ },
46
+ "devDependencies": {
47
+ "@fimo/tsconfig": "0.21.0-experimental.1",
48
+ "@tanstack/react-query": "^5.80.6",
49
+ "@types/node": "^22.15.29",
50
+ "@types/react": "^19.2.14",
51
+ "@types/react-dom": "^19.2.3",
52
+ "fimo": "0.21.0-experimental.1",
53
+ "react": "^19.2.4",
54
+ "react-dom": "^19.2.4",
55
+ "react-router": "^7.15.1",
56
+ "typescript": "7.0.2",
57
+ "vite": "^8.0.13",
58
+ "vitest": "^4.1.6"
59
+ },
60
+ "peerDependencies": {
61
+ "@tanstack/react-query": "^5.80.6",
62
+ "fimo": ">=0.14.0",
63
+ "react": "^18.2.0 || ^19.0.0",
64
+ "react-dom": "^18.2.0 || ^19.0.0",
65
+ "react-router": "^7.0.0 || ^8.0.0",
66
+ "vite": "^7.0.0 || ^8.0.0"
67
+ },
68
+ "peerDependenciesMeta": {
69
+ "@tanstack/react-query": {
70
+ "optional": true
71
+ }
72
+ },
73
+ "engines": {
74
+ "node": ">=20.12.0"
75
+ }
76
+ }