Skip to content

Commit b4db443

Browse files
committed
chore: merge base,code-router and file-router
1 parent e8fb48f commit b4db443

File tree

25 files changed

+249
-248
lines changed

25 files changed

+249
-248
lines changed

packages/cta-engine/src/create-app.ts

Lines changed: 28 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { basename, resolve } from 'node:path'
22

33
import {
4-
FILE_ROUTER,
54
copyAddOnFile,
65
jsSafeName,
76
packageManagerExecute,
@@ -33,10 +32,6 @@ export async function createApp(
3332

3433
const projectBaseDir = resolve(options.framework.baseDirectory)
3534
const templateDirBase = resolve(options.framework.baseDirectory, 'base')
36-
const templateDirRouter = resolve(
37-
options.framework.baseDirectory,
38-
options.mode,
39-
)
4035

4136
let targetDir: string = cwd || ''
4237
if (!targetDir.length) {
@@ -166,7 +161,6 @@ export async function createApp(
166161
options.projectName,
167162
options,
168163
projectBaseDir,
169-
templateDirRouter,
170164
targetDir,
171165
options.chosenAddOns.map((addOn) => addOn.packageAdditions),
172166
)
@@ -299,76 +293,35 @@ export async function createApp(
299293
}
300294
}
301295

302-
// Create the main entry point
303-
if (!isAddOnEnabled('start')) {
304-
if (options.typescript) {
305-
await templateFile(
306-
templateDirRouter,
307-
'./src/main.tsx.ejs',
308-
'./src/main.tsx',
309-
{
310-
routes,
311-
integrations,
312-
},
313-
)
314-
} else {
315-
await templateFile(
316-
templateDirRouter,
317-
'./src/main.tsx.ejs',
318-
'./src/main.jsx',
319-
{
320-
routes,
321-
integrations,
322-
},
323-
)
324-
}
325-
}
326-
327-
// Setup the app component. There are four variations, typescript/javascript and tailwind/non-tailwind.
328-
if (options.mode === FILE_ROUTER) {
329-
await templateFile(
330-
templateDirRouter,
331-
'./src/routes/__root.tsx.ejs',
332-
'./src/routes/__root.tsx',
333-
{
334-
integrations,
335-
},
336-
)
337-
await templateFile(
338-
templateDirBase,
339-
'./src/App.tsx.ejs',
340-
'./src/routes/index.tsx',
341-
)
342-
} else {
343-
await templateFile(
344-
templateDirBase,
345-
'./src/App.tsx.ejs',
346-
options.typescript ? undefined : './src/App.jsx',
347-
)
348-
// TODO: This is a bit of a hack to check if the framework is react
349-
if (options.framework.id === 'react-cra') {
350-
await templateFile(
351-
templateDirBase,
352-
'./src/App.test.tsx.ejs',
353-
options.typescript ? undefined : './src/App.test.jsx',
354-
)
355-
}
356-
}
296+
await templateFile(templateDirBase, './src/main.tsx.ejs', './src/main.tsx', {
297+
routes,
298+
integrations,
299+
})
300+
301+
await templateFile(
302+
templateDirBase,
303+
'./src/routes/__root.tsx.ejs',
304+
'./src/routes/__root.tsx',
305+
{
306+
integrations,
307+
},
308+
)
357309

358-
if (
359-
routes.length > 0 ||
360-
options.chosenAddOns.length > 0 ||
361-
integrations.length > 0
362-
) {
363-
await templateFile(
364-
templateDirBase,
365-
'./src/components/Header.tsx.ejs',
366-
'./src/components/Header.tsx',
367-
{
368-
integrations,
369-
},
370-
)
310+
if (options.framework.id === 'react-cra') {
311+
await templateFile(templateDirBase, './src/App.test.tsx.ejs')
371312
}
313+
await templateFile(templateDirBase, './src/App.tsx.ejs')
314+
await templateFile(templateDirBase, './src/routes/index.tsx.ejs')
315+
316+
await templateFile(
317+
templateDirBase,
318+
'./src/components/Header.tsx.ejs',
319+
'./src/components/Header.tsx',
320+
{
321+
integrations,
322+
routes,
323+
},
324+
)
372325

373326
const warnings: Array<string> = []
374327
for (const addOn of options.chosenAddOns) {
@@ -398,10 +351,7 @@ export async function createApp(
398351

399352
if (warnings.length > 0) {
400353
if (!silent) {
401-
environment.warn(
402-
'The following will be overwritten:',
403-
warnings.join('\n'),
404-
)
354+
environment.warn('Warnings', warnings.join('\n'))
405355
}
406356
}
407357

packages/cta-engine/src/package-json.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ export async function createPackageJSON(
4242
projectName: string,
4343
options: Options,
4444
templateDir: string,
45-
routerDir: string,
4645
targetDir: string,
4746
addOns: Array<{
4847
dependencies?: Record<string, string>
@@ -69,20 +68,12 @@ export async function createPackageJSON(
6968
options.toolchain === 'eslint+prettier'
7069
? packages.eslintprettier
7170
: undefined,
71+
options.mode === FILE_ROUTER ? packages['file-router'] : undefined,
7272
]
7373
for (const addition of additions.filter(Boolean)) {
7474
packageJSON = mergePackageJSON(packageJSON, addition!)
7575
}
7676

77-
if (options.mode === FILE_ROUTER) {
78-
packageJSON = await appendPackageJSON(
79-
environment,
80-
packageJSON,
81-
routerDir,
82-
'package.fr.json',
83-
)
84-
}
85-
8677
for (const addOn of addOns) {
8778
packageJSON = mergePackageJSON(packageJSON, addOn)
8879
}

packages/cta-engine/src/template-file.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export function createTemplateFile(
107107
if (error instanceof IgnoreFileError) {
108108
ignoreFile = true
109109
} else {
110+
console.error(file, error)
110111
environment.error(`EJS error in file ${file}`, error?.toString())
111112
process.exit(1)
112113
}

templates/react-cra/project/base/src/App.test.tsx.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, test } from "vitest";
1+
<% if (fileRouter) { ignoreFile() } %>import { describe, expect, test } from "vitest";
22
import { render, screen } from "@testing-library/react";
33
import App from "./App.<%= jsx %>";
44

templates/react-cra/project/base/src/App.tsx.ejs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
<% if (fileRouter) { %>
2-
import { createFileRoute } from "@tanstack/react-router";
3-
import logo from "../logo.svg";<% if (!tailwind) { %>
4-
import "../App.css";
5-
<% } %>
6-
<% } else { %>import logo from "./logo.svg";<% if (!tailwind) { %>
1+
<% if (fileRouter) { ignoreFile() } %>import logo from "./logo.svg";<% if (!tailwind) { %>
72
import "./App.css";
8-
<% } %><% } %><% if (fileRouter) { %>
9-
10-
export const Route = createFileRoute("/")({
11-
component: App,
12-
});<% } %>
3+
<% } %>
134

145
function App() {
156
return (<% if (tailwind) { %>
@@ -21,7 +12,7 @@ function App() {
2112
alt="logo"
2213
/>
2314
<p>
24-
Edit <code><% if (fileRouter) { %>src/routes/index.tsx<% } else {%>src/App.<%= jsx %><% } %></code> and save to reload.
15+
Edit <code>src/App.<%= jsx %></code> and save to reload.
2516
</p>
2617
<a
2718
className="text-[#61dafb] hover:underline"
@@ -46,7 +37,7 @@ function App() {
4637
<header className="App-header">
4738
<img src={logo} className="App-logo" alt="logo" />
4839
<p>
49-
Edit <code><% if (fileRouter) { %>src/routes/index.tsx<% } else {%>src/App.<%= jsx %><% } %></code> and save to reload.
40+
Edit <code>src/App.<%= jsx %></code> and save to reload.
5041
</p>
5142
<a
5243
className="App-link"
@@ -69,6 +60,4 @@ function App() {
6960
<% } %> );
7061
}
7162

72-
<% if (!fileRouter) { %>
7363
export default App;
74-
<% } %>

templates/react-cra/project/base/src/components/Header.tsx.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Link } from '@tanstack/react-router'
1+
<% if (addOns.length === 0 && integrations.length === 0 && routes.length === 0) { ignoreFile() } %>import { Link } from '@tanstack/react-router'
22
<% for(const integration of integrations.filter(i => i.type === 'header-user')) { %>
33
import <%= integration.name %> from "../<%= integration.path %>";
44
<% } %>

templates/react-cra/project/code-router/src/main.tsx.ejs renamed to templates/react-cra/project/base/src/main.tsx.ejs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { StrictMode } from "react";
1+
<% if (addOnEnabled.start) { ignoreFile() } %><% if (codeRouter) {
2+
3+
/// Code Router
4+
5+
%>import { StrictMode } from "react";
26
import ReactDOM from "react-dom/client";
37
import {
48
Outlet,
@@ -90,3 +94,62 @@ const rootElement = document.getElementById("app");
9094
// to log results (for example: reportWebVitals(console.log))
9195
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
9296
reportWebVitals();
97+
<% } else {
98+
99+
/* File Router */
100+
101+
%>import { StrictMode } from "react";
102+
import ReactDOM from "react-dom/client";
103+
import { RouterProvider, createRouter } from "@tanstack/react-router";
104+
<% for(const integration of integrations.filter(i => i.type === 'root-provider')) { %>
105+
import * as <%= integration.name %> from "./<%= integration.path %>";
106+
<% } %>
107+
108+
// Import the generated route tree
109+
import { routeTree } from "./routeTree.gen";
110+
111+
import "./styles.css";
112+
import reportWebVitals from "./reportWebVitals.<%= js %>";
113+
114+
// Create a new router instance
115+
const router = createRouter({
116+
routeTree,
117+
context: {
118+
<% for(const integration of integrations.filter(i => i.type === 'root-provider')) { %>
119+
...<%= integration.name %>.getContext(),
120+
<% } %>
121+
},
122+
defaultPreload: "intent",
123+
scrollRestoration: true,
124+
defaultStructuralSharing: true,
125+
defaultPreloadStaleTime: 0,
126+
});
127+
128+
// Register the router instance for type safety
129+
declare module "@tanstack/react-router" {
130+
interface Register {
131+
router: typeof router;
132+
}
133+
}
134+
135+
// Render the app
136+
const rootElement = document.getElementById("app");
137+
if (rootElement && !rootElement.innerHTML) {
138+
const root = ReactDOM.createRoot(rootElement);
139+
root.render(
140+
<StrictMode>
141+
<% for(const integration of integrations.filter(i => i.type === 'root-provider')) { %>
142+
<<%= integration.name %>.Provider>
143+
<% } %>
144+
<RouterProvider router={router} />
145+
<% for(const integration of integrations.filter(i => i.type === 'root-provider').reverse()) { %>
146+
</<%= integration.name %>.Provider>
147+
<% } %>
148+
</StrictMode>
149+
);
150+
}
151+
152+
// If you want to start measuring performance in your app, pass a function
153+
// to log results (for example: reportWebVitals(console.log))
154+
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
155+
reportWebVitals();<% } %>

templates/react-cra/project/file-router/src/routes/__root.tsx.ejs renamed to templates/react-cra/project/base/src/routes/__root.tsx.ejs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Outlet<% if (addOnEnabled.start) { %>
1+
<% if (!fileRouter) { ignoreFile() } %>import { Outlet<% if (addOnEnabled.start) { %>
22
, HeadContent, Scripts<% } %>, <% if (addOnEnabled["tanstack-query"]) { %>createRootRouteWithContext<% } else { %>createRootRoute<% } %> } from '@tanstack/react-router'
33
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
44
<% if (addOns.length) { %>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<% if (codeRouter) { ignoreFile() } %>
2+
import { createFileRoute } from "@tanstack/react-router";
3+
import logo from "../logo.svg";<% if (!tailwind) { %>
4+
import "../App.css";
5+
<% } %>
6+
7+
export const Route = createFileRoute("/")({
8+
component: App,
9+
});
10+
11+
function App() {
12+
return (<% if (tailwind) { %>
13+
<div className="text-center">
14+
<header className="min-h-screen flex flex-col items-center justify-center bg-[#282c34] text-white text-[calc(10px+2vmin)]">
15+
<img
16+
src={logo}
17+
className="h-[40vmin] pointer-events-none animate-[spin_20s_linear_infinite]"
18+
alt="logo"
19+
/>
20+
<p>
21+
Edit <code>src/routes/index.tsx</code> and save to reload.
22+
</p>
23+
<a
24+
className="text-[#61dafb] hover:underline"
25+
href="https://reactjs.org"
26+
target="_blank"
27+
rel="noopener noreferrer"
28+
>
29+
Learn React
30+
</a>
31+
<a
32+
className="text-[#61dafb] hover:underline"
33+
href="https://tanstack.com"
34+
target="_blank"
35+
rel="noopener noreferrer"
36+
>
37+
Learn TanStack
38+
</a>
39+
</header>
40+
</div>
41+
<% } else { %>
42+
<div className="App">
43+
<header className="App-header">
44+
<img src={logo} className="App-logo" alt="logo" />
45+
<p>
46+
Edit <code>src/routes/index.tsx</code> and save to reload.
47+
</p>
48+
<a
49+
className="App-link"
50+
href="https://reactjs.org"
51+
target="_blank"
52+
rel="noopener noreferrer"
53+
>
54+
Learn React
55+
</a>
56+
<a
57+
className="App-link"
58+
href="https://tanstack.com"
59+
target="_blank"
60+
rel="noopener noreferrer"
61+
>
62+
Learn TanStack
63+
</a>
64+
</header>
65+
</div>
66+
<% } %> );
67+
}

templates/react-cra/project/file-router/package.fr.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)