Monorepo example #755
Replies: 5 comments 7 replies
-
With Nx Workspace, I updated the Vite Config as follows: /// <reference types='vitest' />
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import { TanStackRouterVite } from '@tanstack/router-vite-plugin';
import { join } from 'path';
export default defineConfig({
root: __dirname,
cacheDir: '../../node_modules/.vite/apps/web',
server: {
port: 4200,
host: 'localhost',
},
preview: {
port: 4300,
host: 'localhost',
},
plugins: [
react(),
TanStackRouterVite({
routesDirectory: join(__dirname, 'src/routes'),
generatedRouteTree: join(__dirname, 'src/routeTree.gen.ts'),
routeFileIgnorePrefix: '-',
quoteStyle: 'single',
}),
nxViteTsPaths(),
],
// Uncomment this if you are using workers.
// worker: {
// plugins: [ nxViteTsPaths() ],
// },
build: {
outDir: '../../dist/apps/web',
reportCompressedSize: true,
commonjsOptions: {
transformMixedEsModules: true,
},
},
test: {
globals: true,
cache: {
dir: '../../node_modules/.vitest',
},
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
reporters: ['default'],
coverage: {
reportsDirectory: '../../coverage/apps/web',
provider: 'v8',
},
},
}); |
Beta Was this translation helpful? Give feedback.
-
Hi @tl-frameplay @rahulretnan , can you please help me in figuring out how routing will work in Microfrontend architecture.. I am using turborepo and tanstack Router |
Beta Was this translation helpful? Give feedback.
-
I guess, @tannerlinsley finally heard us.😅 He is including a example of tanstack router in monorepo. Thanks, Really, appreciate the Effort. ✨ Basic: With React Query: https://github.com/TanStack/router/tree/main/examples/react/router-monorepo-react-query |
Beta Was this translation helpful? Give feedback.
-
I gave it a go and made a turborepo template with tanstack router at the core: It's not a small example, with many other components such as
and so on, but hopefully someone finds it helpful :). |
Beta Was this translation helpful? Give feedback.
-
I'm going to hijack this discussion post to try to explain my main difficulty with the current recommendation of how Router supports monorepos, and what I think some potential solutions are. It all revolves around cyclical dependencies (get it?). What do I mean? Lets say I have the monorepo setup that's currently in the docs:
The main thing to note here is that Now lets imagine that in
Now lets add a component from
Lets say that this this component is the actual thing that cares about our search param. These typed & validated search params are a really powerful feature of Router. Personally, I really like the idea of having component that require / consume these params be responsible for getting them, similar to other ideas of having components that consume specific data be responsible for getting that data. Router thought of that too, and it's great that you can access to these typed & validated values even outside of route components via the Except wait a second, how does
But now we've created a cyclical dependency:
Big no-no in monorepos, most tools will yell at you if you have cyclical dependencies, if not outright refuse to run. So how to solve this? Well there's a few ideas I can think of: 1). Router concerns are router concerns. Leave the router stuff to the router and have packages expect that data via props / another data contract:
I'm totally cool with this being the answer. It's not what I want, but it makes sense. Now our graph has the correct direction again: 2). Loosen types Loosen up our types as outlined in the docs:
I'm down to loosen these types, and type them inside our package instead. But we're better than that, right? Ok cool, moving on. 3). Create a new sink for the Route APIs in our graph Go onto any of these GitHub issues where people complain about cyclical dependencies and the first answer is to create a new package or combine existing packages. We're not gonna combine
But Router doesn't really support this at the moment. When I generate my types for the 4). Import the package in the app only This is how the current monorepo example is set up. In this paradigm, With file based routing, I really like how we can look at our files in our routes folder and understand the structure of the app at a glance. I think by spreading them out like this we've taken the idea of the monorepo too far. I want my router to be responsible for pages and routing, not just routing. Maybe this means that we do need to go back to the single responsibility pattern outlined in solution 1, I'm not sure. All of this is to say that something about splitting my pages from my router feels off to me. I'm open to being wrong on this, but I feel like I'm losing a key advantage of what I like about file based routing. 5). Cheat This is kind of what @davidturissini mentioned in their reply above, which is to just grab the types via a script or task and make them available at a lower package in the graph. I'd go even further honestly, I'd be fine with putting something like that at the root of the repo, something like a My preferred solution Someone tell me if I'm missing something or doing something wrong, because I've found it difficult to get my sweet, sweet type safety with Router in a monorepo. Idk, let me know what you think or if I'm over complicating this. |
Beta Was this translation helpful? Give feedback.
-
Hey guys, we appreciate you sharing this great library.
So far, everything is amazing, but we are having issues strongly type using a monorepo. Before we say which monorepo to avoid promoting one over the other; do you have any examples how tanstack router is meant to work for Typescript in a monorepo?
Specifically, we have a monorepo package called "router", where tanstack router is installed, and the actual "router" file in an app of the monorepo where all the routes are configured and the router exported for the app.
Thank you kindly.
Beta Was this translation helpful? Give feedback.
All reactions