revine 0.9.1 → 1.0.2

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.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/dist/client.d.ts +8 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +4 -0
  5. package/dist/commands/createProject.d.ts.map +1 -1
  6. package/dist/commands/createProject.js +44 -3
  7. package/dist/components/Link.d.ts +8 -0
  8. package/dist/components/Link.d.ts.map +1 -0
  9. package/dist/components/Link.js +5 -0
  10. package/dist/components/NavLink.d.ts +8 -0
  11. package/dist/components/NavLink.d.ts.map +1 -0
  12. package/dist/components/NavLink.js +5 -0
  13. package/dist/index.js +33 -26
  14. package/dist/runtime/bundler/defaults/vite.d.ts +6 -0
  15. package/dist/runtime/bundler/defaults/vite.d.ts.map +1 -1
  16. package/dist/runtime/bundler/defaults/vite.js +8 -2
  17. package/dist/runtime/bundler/revinePlugin.d.ts +0 -7
  18. package/dist/runtime/bundler/revinePlugin.d.ts.map +1 -1
  19. package/dist/runtime/bundler/revinePlugin.js +70 -27
  20. package/dist/runtime/bundler/viteLoggerPlugin.d.ts.map +1 -1
  21. package/dist/runtime/bundler/viteLoggerPlugin.js +2 -2
  22. package/dist/runtime/defineConfig.d.ts +6 -0
  23. package/dist/runtime/defineConfig.d.ts.map +1 -0
  24. package/dist/runtime/defineConfig.js +3 -0
  25. package/dist/runtime/routing.d.ts +2 -0
  26. package/dist/runtime/routing.d.ts.map +1 -0
  27. package/dist/runtime/routing.js +1 -0
  28. package/dist/runtime/types.d.ts +5 -0
  29. package/dist/runtime/types.d.ts.map +1 -0
  30. package/dist/runtime/types.js +1 -0
  31. package/dist/setup/dependencies.d.ts.map +1 -1
  32. package/dist/setup/dependencies.js +1 -8
  33. package/package.json +7 -21
  34. package/src/client.ts +14 -0
  35. package/src/commands/createProject.ts +55 -9
  36. package/src/components/Link.tsx +18 -0
  37. package/src/components/NavLink.tsx +18 -0
  38. package/src/index.ts +41 -31
  39. package/src/runtime/bundler/defaults/vite.ts +8 -2
  40. package/src/runtime/bundler/revinePlugin.ts +71 -28
  41. package/src/runtime/bundler/viteLoggerPlugin.ts +4 -3
  42. package/src/runtime/defineConfig.ts +9 -0
  43. package/src/runtime/routing.ts +4 -0
  44. package/src/runtime/types.ts +5 -0
  45. package/src/setup/dependencies.ts +1 -9
  46. package/template/package.json +1 -2
  47. package/template/revine.config.ts +4 -2
  48. package/template/src/pages/index.tsx +18 -16
  49. package/template/src/root.tsx +2 -2
  50. package/tsconfig.json +4 -2
  51. package/dist/runtime/routing/fileBased.d.ts +0 -2
  52. package/dist/runtime/routing/fileBased.d.ts.map +0 -1
  53. package/dist/runtime/routing/fileBased.js +0 -29
  54. package/src/runtime/routing/fileBased.tsx +0 -46
@@ -12,6 +12,46 @@ import { logError, logInfo } from "../utils/logger.js";
12
12
  const __filename = fileURLToPath(import.meta.url);
13
13
  const __dirname = path.dirname(__filename);
14
14
 
15
+ const GITIGNORE_CONTENT = `# Dependencies
16
+ node_modules/
17
+ dist/
18
+ dist-ssr/
19
+
20
+ # Vite cache
21
+ .vite/
22
+ *.local
23
+
24
+ # Environment files
25
+ .env
26
+ .env.local
27
+ .env.development.local
28
+ .env.test.local
29
+ .env.production.local
30
+
31
+ # Logs
32
+ npm-debug.log*
33
+ yarn-debug.log*
34
+ yarn-error.log*
35
+
36
+ # Editor/IDE
37
+ .vscode/
38
+ .idea/
39
+ *.swp
40
+ *.swo
41
+
42
+ # OS metadata
43
+ .DS_Store
44
+ Thumbs.db
45
+
46
+ # TypeScript build info
47
+ *.tsbuildinfo
48
+
49
+ # Optional
50
+ .cache/
51
+ .tmp/
52
+ .sass-cache/
53
+ `;
54
+
15
55
  export async function createProject(
16
56
  projectName: string,
17
57
  options: { force?: boolean }
@@ -23,13 +63,16 @@ export async function createProject(
23
63
 
24
64
  try {
25
65
  logInfo(`Creating project in ${projectDir}...`);
26
-
66
+
27
67
  // Ensure the project directory exists
28
68
  await fs.ensureDir(projectDir);
29
-
69
+
30
70
  // This copies everything, including hidden directories like .revine
31
71
  await copyTemplate(templateDir, projectDir, options.force);
32
72
 
73
+ // Explicitly write .gitignore because npm strips it from published tarballs
74
+ await fs.writeFile(path.join(projectDir, ".gitignore"), GITIGNORE_CONTENT);
75
+
33
76
  // Derive final project name
34
77
  const finalProjectName = isCurrentDir
35
78
  ? path.basename(projectDir)
@@ -37,28 +80,31 @@ export async function createProject(
37
80
 
38
81
  // Check if package.json exists after template copy
39
82
  const packageJsonPath = path.join(projectDir, "package.json");
40
-
83
+
41
84
  // Create basic package.json if it doesn't exist
42
- if (!await fs.pathExists(packageJsonPath)) {
85
+ if (!(await fs.pathExists(packageJsonPath))) {
43
86
  const basicPackageJson = {
44
87
  name: finalProjectName,
45
88
  version: "0.1.0",
46
89
  private: true,
47
- type: "module"
90
+ type: "module",
48
91
  };
49
92
  await fs.writeJSON(packageJsonPath, basicPackageJson, { spaces: 2 });
50
93
  }
51
-
94
+
52
95
  // Update package.json with the correct details
53
96
  const useTailwind = await askForTailwindSetup();
54
97
  await updatePackageJson(packageJsonPath, finalProjectName, { useTailwind });
55
98
 
56
99
  // Check if README exists, create it if it doesn't
57
100
  const readmePath = path.join(projectDir, "README.md");
58
- if (!await fs.pathExists(readmePath)) {
59
- await fs.writeFile(readmePath, `# ${finalProjectName}\n\nCreated with Revine`);
101
+ if (!(await fs.pathExists(readmePath))) {
102
+ await fs.writeFile(
103
+ readmePath,
104
+ `# ${finalProjectName}\n\nCreated with Revine`
105
+ );
60
106
  }
61
-
107
+
62
108
  // Update README with the project name
63
109
  await updateReadme(readmePath, finalProjectName);
64
110
 
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from "react";
2
+ import {
3
+ Link as RouterLink,
4
+ type LinkProps as RouterLinkProps,
5
+ } from "react-router-dom";
6
+
7
+ export interface LinkProps extends Omit<RouterLinkProps, "to"> {
8
+ href: string;
9
+ children?: ReactNode;
10
+ }
11
+
12
+ export function Link({ href, children, ...rest }: LinkProps) {
13
+ return (
14
+ <RouterLink to={href} {...rest}>
15
+ {children}
16
+ </RouterLink>
17
+ );
18
+ }
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from "react";
2
+ import {
3
+ NavLink as RouterNavLink,
4
+ type NavLinkProps as RouterNavLinkProps,
5
+ } from "react-router-dom";
6
+
7
+ export interface NavLinkProps extends Omit<RouterNavLinkProps, "to"> {
8
+ href: string;
9
+ children?: ReactNode;
10
+ }
11
+
12
+ export function NavLink({ href, children, ...rest }: NavLinkProps) {
13
+ return (
14
+ <RouterNavLink to={href} {...rest}>
15
+ {children}
16
+ </RouterNavLink>
17
+ );
18
+ }
package/src/index.ts CHANGED
@@ -1,16 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from "commander";
3
- import { createProject } from "./commands/createProject.js";
4
- import { spawn } from "child_process";
3
+ import { readFileSync } from "fs";
5
4
  import path from "path";
6
5
  import { fileURLToPath } from "url";
6
+ import { createProject } from "./commands/createProject.js";
7
7
 
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = path.dirname(__filename);
10
10
 
11
+ const pkgPath = path.resolve(__dirname, "../package.json");
12
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
13
+
11
14
  const program = new Command();
12
15
 
13
- // Main command handler for direct project creation
14
16
  const handleProjectCreation = async (
15
17
  projectName: string,
16
18
  options: { force?: boolean },
@@ -18,44 +20,52 @@ const handleProjectCreation = async (
18
20
  await createProject(projectName, options);
19
21
  };
20
22
 
21
- // Helper to run vite with internal config
22
- const runViteCommand = (command: string) => {
23
- // Path to the compiled vite.config.js in dist
23
+ const runViteCommand = async (command: string) => {
24
24
  const configPath = path.resolve(__dirname, "runtime/bundler/vite.config.js");
25
25
 
26
- const args = [command, "--config", configPath];
27
- if (command === "dev") {
28
- // Vite dev doesn't need 'dev' argument, just calling vite is enough
29
- args.shift();
30
- }
26
+ // Set the config path as env variable — vite reads VITE_CONFIG_FILE
27
+ process.env.VITE_CONFIG_PATH = configPath;
31
28
 
32
- spawn("npx", ["vite", ...args], {
33
- stdio: "inherit",
34
- shell: true,
35
- });
36
- };
29
+ // Dynamically import vite's programmatic API
30
+ const vitePath = path.resolve(
31
+ process.cwd(),
32
+ "node_modules/vite/dist/node/index.js",
33
+ );
34
+ const vite = await import(vitePath);
37
35
 
38
- // Main command handler for direct project creation with command check
39
- const handleRootAction = async (
40
- projectName: string | undefined,
41
- options: { force?: boolean },
42
- ) => {
43
- const knownCommands = ["create", "dev", "build", "preview"];
44
- if (projectName && !knownCommands.includes(projectName)) {
45
- await handleProjectCreation(projectName, options);
46
- } else if (!projectName) {
47
- program.help();
36
+ // Load the revine config
37
+ const { generateRevineViteConfig } = await import(
38
+ path.resolve(__dirname, "runtime/bundler/generateConfig.js")
39
+ );
40
+ const config = await generateRevineViteConfig();
41
+
42
+ if (command === "dev") {
43
+ const server = await vite.createServer({
44
+ ...config,
45
+ configFile: false, // we pass config directly, no file needed
46
+ });
47
+ await server.listen();
48
+ server.printUrls();
49
+ } else if (command === "build") {
50
+ await vite.build({
51
+ ...config,
52
+ configFile: false,
53
+ });
54
+ } else if (command === "preview") {
55
+ const server = await vite.preview({
56
+ ...config,
57
+ configFile: false,
58
+ });
59
+ server.printUrls();
48
60
  }
49
61
  };
50
62
 
51
- // Root command
63
+ // Root command — handles: npx revine <project-name>
52
64
  program
53
- .version("0.8.0")
65
+ .version(pkg.version)
54
66
  .argument("[project-name/command]")
55
67
  .option("-f, --force", "Force creation in non-empty directory")
56
68
  .action(async (arg: string | undefined, options: { force?: boolean }) => {
57
- // If it's a known command, Commander will handle it in the subcommand action.
58
- // We only handle it here if it's NOT a known command.
59
69
  const knownCommands = ["create", "dev", "build", "preview"];
60
70
  if (arg && !knownCommands.includes(arg)) {
61
71
  await handleProjectCreation(arg, options);
@@ -64,7 +74,7 @@ program
64
74
  }
65
75
  });
66
76
 
67
- // Create subcommand (npx revine create my-app)
77
+ // npx revine create <project-name>
68
78
  program
69
79
  .command("create")
70
80
  .argument("<project-name>")
@@ -1,18 +1,24 @@
1
1
  import react from "@vitejs/plugin-react";
2
- import { revineLoggerPlugin } from "../viteLoggerPlugin.js";
3
2
  import { revinePlugin } from "../revinePlugin.js";
3
+ import { revineLoggerPlugin } from "../viteLoggerPlugin.js";
4
4
 
5
5
  export const defaultViteConfig = {
6
6
  plugins: [react(), revinePlugin(), revineLoggerPlugin()],
7
7
  logLevel: "silent",
8
8
  server: {
9
9
  clearScreen: false,
10
- open: true,
10
+ open: false,
11
11
  port: 3000,
12
12
  host: true,
13
13
  },
14
14
  build: {
15
15
  outDir: "build",
16
16
  emptyOutDir: true,
17
+ rollupOptions: {
18
+ external: ["revine"],
19
+ },
20
+ },
21
+ optimizeDeps: {
22
+ exclude: ["revine"],
17
23
  },
18
24
  };
@@ -1,16 +1,9 @@
1
1
  const VIRTUAL_ROUTING_ID = "\0revine:routing";
2
2
 
3
- /**
4
- * The Revine Vite plugin.
5
- *
6
- * Provides a virtual module for `revine/routing` so that:
7
- * - `import.meta.glob` is resolved by Vite in the *project* context (not node_modules)
8
- * - React runtime is resolved from the project's own node_modules
9
- */
10
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
3
  export function revinePlugin(): any {
12
4
  return {
13
5
  name: "revine",
6
+ enforce: "pre",
14
7
 
15
8
  resolveId(id: string) {
16
9
  if (id === "revine/routing") {
@@ -18,44 +11,94 @@ export function revinePlugin(): any {
18
11
  }
19
12
  },
20
13
 
21
- // Return the routing source as a virtual module.
22
- // Because it's virtual (not inside node_modules), Vite processes
23
- // import.meta.glob and all imports normally in the project context.
24
14
  load(id: string) {
25
15
  if (id === VIRTUAL_ROUTING_ID) {
26
16
  return `
27
17
  import { createBrowserRouter } from "react-router-dom";
28
18
  import { lazy, Suspense, createElement } from "react";
29
19
 
30
- // Eagerly load NotFound from the project's src directory.
31
20
  const notFoundModules = import.meta.glob("/src/NotFound.tsx", { eager: true });
32
21
  const NotFoundComponent = Object.values(notFoundModules)[0]?.default;
33
22
 
34
- // Lazily load all page components under /src/pages.
35
23
  const pages = import.meta.glob("/src/pages/**/*.tsx");
24
+ const layoutModules = import.meta.glob("/src/pages/**/layout.tsx", { eager: true });
25
+ const loadingModules = import.meta.glob("/src/pages/**/loading.tsx", { eager: true });
36
26
 
37
- const routes = Object.entries(pages).map(([filePath, component]) => {
38
- let cleaned = filePath.replace(/\\\\/g, "/");
39
- cleaned = cleaned.replace(/.*\\/pages\\//, "");
40
- cleaned = cleaned.replace(/\\.tsx$/i, "");
41
- cleaned = cleaned.replace(/\\/index$/, "");
42
- cleaned = cleaned.replace(/\\[(\\w+)\\]/g, ":$1");
43
- if (cleaned === "index") cleaned = "";
27
+ function getLayoutsForPath(filePath) {
28
+ const parts = filePath.split("/");
29
+ parts.pop();
30
+ const layouts = [];
31
+ const accumulated = [];
32
+ for (const part of parts) {
33
+ accumulated.push(part);
34
+ const key = accumulated.join("/") + "/layout.tsx";
35
+ if (layoutModules[key] && layoutModules[key].default) {
36
+ layouts.push(layoutModules[key].default);
37
+ }
38
+ }
39
+ return layouts;
40
+ }
41
+
42
+ function getLoadingForPath(filePath) {
43
+ const parts = filePath.split("/");
44
+ parts.pop();
45
+ while (parts.length >= 2) {
46
+ const key = parts.join("/") + "/loading.tsx";
47
+ if (loadingModules[key] && loadingModules[key].default) {
48
+ return loadingModules[key].default;
49
+ }
50
+ parts.pop();
51
+ }
52
+ return null;
53
+ }
54
+
55
+ function wrapWithLayouts(element, layouts) {
56
+ return layouts.reduceRight((wrapped, Layout) => {
57
+ return createElement(Layout, null, wrapped);
58
+ }, element);
59
+ }
60
+
61
+ function toRoutePath(filePath) {
62
+ let p = filePath;
63
+ p = p.replace(/[\\\\]/g, "/");
64
+ p = p.replace(/.*[/]pages[/]/, "");
65
+ p = p.replace(/[.]tsx$/i, "");
66
+ p = p.replace(/[/]index$/, "");
67
+ p = p.replace(/[(][^)]+[)][/]/g, "");
68
+ p = p.replace(/[[]([\\w]+)[\\]]/g, ":$1");
69
+ if (p === "index" || p === "") return "/";
70
+ return "/" + p;
71
+ }
72
+
73
+ const pageEntries = Object.entries(pages).filter(([filePath]) => {
74
+ if (filePath.endsWith("/layout.tsx")) return false;
75
+ if (filePath.endsWith("/loading.tsx")) return false;
76
+ const segments = filePath.split("/");
77
+ return !segments.some((s) => s.startsWith("_"));
78
+ });
44
79
 
45
- const routePath = cleaned === "" ? "/" : \`/\${cleaned}\`;
80
+ const routes = pageEntries.map(([filePath, component]) => {
81
+ const routePath = toRoutePath(filePath);
46
82
  const Component = lazy(component);
83
+ const layouts = getLayoutsForPath(filePath);
84
+ const Loading = getLoadingForPath(filePath);
85
+
86
+ const fallback = Loading
87
+ ? createElement(Loading)
88
+ : createElement("div", null, "Loading\\u2026");
89
+
90
+ const pageElement = createElement(
91
+ Suspense,
92
+ { fallback },
93
+ createElement(Component)
94
+ );
47
95
 
48
96
  return {
49
97
  path: routePath,
50
- element: createElement(
51
- Suspense,
52
- { fallback: createElement("div", null, "Loading\u2026") },
53
- createElement(Component)
54
- ),
98
+ element: layouts.length > 0 ? wrapWithLayouts(pageElement, layouts) : pageElement,
55
99
  };
56
100
  });
57
101
 
58
- // 404 fallback
59
102
  routes.push({
60
103
  path: "*",
61
104
  element: NotFoundComponent
@@ -68,4 +111,4 @@ export const router = createBrowserRouter(routes);
68
111
  }
69
112
  },
70
113
  };
71
- }
114
+ }
@@ -1,5 +1,5 @@
1
- import type { Plugin, ViteDevServer } from "vite";
2
1
  import chalk from "chalk";
2
+ import type { Plugin, ViteDevServer } from "vite";
3
3
 
4
4
  export function revineLoggerPlugin(): Plugin {
5
5
  // custom chalk instance pointing to the indigo color
@@ -10,14 +10,15 @@ export function revineLoggerPlugin(): Plugin {
10
10
  configureServer(server: ViteDevServer) {
11
11
  server.httpServer?.once("listening", () => {
12
12
  const protocol = server.config.server.https ? "https" : "http";
13
- const host = server.resolvedUrls?.local[0] || "localhost:3000";
13
+ const localUrl =
14
+ server.resolvedUrls?.local[0] || `http://localhost:3000`;
14
15
  const { network = [] } = server.resolvedUrls ?? {};
15
16
 
16
17
  // Use the 'indigo' instance in place of 'chalk.cyan'
17
18
  console.log(indigo("─────────────────────────────────────────────"));
18
19
  console.log(indigo.bold("🚀 Revine Dev Server is now running!"));
19
20
  console.log(indigo("─────────────────────────────────────────────"));
20
- console.log(indigo(`Local: ${chalk.green(`${protocol}://${host}`)}`));
21
+ console.log(indigo(`Local: ${chalk.green(localUrl)}`));
21
22
 
22
23
  if (network.length) {
23
24
  network.forEach((url: string) => {
@@ -0,0 +1,9 @@
1
+ import type { UserConfig } from "vite";
2
+
3
+ export interface RevineConfig {
4
+ vite?: UserConfig;
5
+ }
6
+
7
+ export function defineConfig(config: RevineConfig): RevineConfig {
8
+ return config;
9
+ }
@@ -0,0 +1,4 @@
1
+ // This module is intentionally empty.
2
+ // `revine/routing` is a virtual module resolved by the Revine Vite plugin at build time.
3
+ // The actual router is injected via the plugin's resolveId/load hooks.
4
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ export interface LayoutProps {
4
+ children: ReactNode;
5
+ }
@@ -8,19 +8,11 @@ export async function installDependencies(projectDir: string): Promise<void> {
8
8
  const installResult = spawnSync(npmCmd, ["install"], {
9
9
  stdio: "inherit",
10
10
  cwd: projectDir,
11
- shell: true,
11
+ shell: false,
12
12
  });
13
13
  if (installResult.error || installResult.status !== 0) {
14
14
  logError("Error installing dependencies:", installResult.error);
15
15
  logInfo("Try running manually: npm install");
16
16
  process.exit(1);
17
17
  }
18
-
19
- // Step 2: Link local revine if available (replaces npm version with local build)
20
- // This is a no-op if revine hasn't been globally linked via `npm link` in the revine repo.
21
- spawnSync(npmCmd, ["link", "revine"], {
22
- stdio: "pipe", // suppress output — silently skip if not linked
23
- cwd: projectDir,
24
- shell: true,
25
- });
26
18
  }
@@ -10,8 +10,7 @@
10
10
  "dependencies": {
11
11
  "revine": "latest",
12
12
  "react": "^18.2.0",
13
- "react-dom": "^18.2.0",
14
- "react-router-dom": "^6.22.3"
13
+ "react-dom": "^18.2.0"
15
14
  },
16
15
  "devDependencies": {
17
16
  "@types/react": "^18.2.45",
@@ -1,4 +1,6 @@
1
- export default {
1
+ import { defineConfig } from "revine";
2
+
3
+ export default defineConfig({
2
4
  vite: {
3
5
  server: {
4
6
  open: false,
@@ -10,4 +12,4 @@ export default {
10
12
  emptyOutDir: true,
11
13
  },
12
14
  },
13
- };
15
+ });
@@ -1,3 +1,5 @@
1
+ import { Link } from "revine";
2
+
1
3
  export default function HomePage() {
2
4
  return (
3
5
  <main>
@@ -11,51 +13,51 @@ export default function HomePage() {
11
13
 
12
14
  {/* CTA Buttons */}
13
15
  <div className="cta">
14
- <a href="#get-started" className="primary-btn">
16
+ <Link href="#get-started" className="primary-btn">
15
17
  Get Started
16
- </a>
17
- <a href="#docs" className="secondary-btn">
18
+ </Link>
19
+ <Link href="#docs" className="secondary-btn">
18
20
  Read Docs
19
- </a>
21
+ </Link>
20
22
  </div>
21
23
 
22
24
  {/* Features Section */}
23
25
  <div className="features">
24
- <a href="#fast">
26
+ <Link href="#fast">
25
27
  <h3>Lightning Fast</h3>
26
28
  <p>Built on Vite for ultra-fast development and instant HMR.</p>
27
- </a>
28
- <a href="#routing">
29
+ </Link>
30
+ <Link href="#routing">
29
31
  <h3>Simple File-based Routing</h3>
30
32
  <p>
31
33
  Create pages in <code>src/pages</code> and Revine will handle the
32
34
  rest.
33
35
  </p>
34
- </a>
35
- <a href="#tailwind">
36
+ </Link>
37
+ <Link href="#tailwind">
36
38
  <h3>Tailwind Integration</h3>
37
39
  <p>
38
40
  Pre-configured for Tailwind CSS, so you can style quickly and
39
41
  easily.
40
42
  </p>
41
- </a>
42
- <a href="#dev-experience">
43
+ </Link>
44
+ <Link href="#dev-experience">
43
45
  <h3>Great DX</h3>
44
46
  <p>Minimal config, fast builds, custom logging, and more.</p>
45
- </a>
46
- <a href="#abstract">
47
+ </Link>
48
+ <Link href="#abstract">
47
49
  <h3>Abstracted Internals</h3>
48
50
  <p>
49
51
  A .revine folder houses the complex Vite config. Keep your root
50
52
  clean.
51
53
  </p>
52
- </a>
53
- <a href="#customize">
54
+ </Link>
55
+ <Link href="#customize">
54
56
  <h3>Fully Customizable</h3>
55
57
  <p>
56
58
  Easily extend or override settings in <code>revine.config.ts</code>.
57
59
  </p>
58
- </a>
60
+ </Link>
59
61
  </div>
60
62
  </main>
61
63
  );
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { createRoot } from "react-dom/client";
3
- import { RouterProvider } from "react-router-dom";
3
+ import { RouterProvider } from "revine";
4
4
  import { router } from "revine/routing";
5
5
  import "./styles/global.css";
6
6
 
@@ -11,4 +11,4 @@ root.render(
11
11
  <React.StrictMode>
12
12
  <RouterProvider router={router} />
13
13
  </React.StrictMode>,
14
- );
14
+ );
package/tsconfig.json CHANGED
@@ -2,7 +2,8 @@
2
2
  "compilerOptions": {
3
3
  "target": "ES2020",
4
4
  "module": "ES2020",
5
- "moduleResolution": "node",
5
+ "moduleResolution": "bundler",
6
+ "rootDir": "src",
6
7
  "outDir": "dist",
7
8
  "strict": true,
8
9
  "esModuleInterop": true,
@@ -11,7 +12,8 @@
11
12
  "jsx": "react-jsx",
12
13
  "declaration": true,
13
14
  "declarationMap": true,
14
- "emitDeclarationOnly": false
15
+ "emitDeclarationOnly": false,
16
+ "resolveJsonModule": true
15
17
  },
16
18
  "include": ["src/**/*"],
17
19
  "exclude": ["src/template/**/*"]
@@ -1,2 +0,0 @@
1
- export declare const router: import("@remix-run/router").Router;
2
- //# sourceMappingURL=fileBased.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fileBased.d.ts","sourceRoot":"","sources":["../../../src/runtime/routing/fileBased.tsx"],"names":[],"mappings":"AA6CA,eAAO,MAAM,MAAM,oCAA8B,CAAC"}
@@ -1,29 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { createBrowserRouter } from "react-router-dom";
3
- import { lazy, Suspense } from "react";
4
- // @ts-ignore
5
- import NotFound from "/src/NotFound";
6
- // @ts-ignore
7
- const pages = import.meta.glob("/src/pages/**/*.tsx");
8
- const routes = Object.entries(pages).map(([filePath, component]) => {
9
- let cleaned = filePath.replace(/\\/g, "/");
10
- cleaned = cleaned.replace(/.*\/pages\//, "");
11
- cleaned = cleaned.replace(/\.tsx$/i, "");
12
- cleaned = cleaned.replace(/\/index$/, "");
13
- cleaned = cleaned.replace(/\[(\w+)\]/g, ":$1");
14
- if (cleaned === "index") {
15
- cleaned = "";
16
- }
17
- const routePath = cleaned === "" ? "/" : `/${cleaned}`;
18
- const Component = lazy(component);
19
- return {
20
- path: routePath,
21
- element: (_jsx(Suspense, { fallback: _jsx("div", { children: "Loading..." }), children: _jsx(Component, {}) })),
22
- };
23
- });
24
- // fallback route for 404s
25
- routes.push({
26
- path: "*",
27
- element: _jsx(NotFound, {}),
28
- });
29
- export const router = createBrowserRouter(routes);