Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(router-vite-plugin): remove the start logic from @tanstack/router-vite-plugin and update @tanstack/start with the new imports #1771

Merged
merged 10 commits into from
Jun 18, 2024
Merged
184 changes: 2 additions & 182 deletions packages/router-vite-plugin/src/compilers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,97 +91,7 @@ export async function compileFile(opts: {
{
CallExpression: (path) => {
if (path.node.callee.type === 'Identifier') {
if (path.node.callee.name === 'createServerFn') {
// If the function at createServerFn(_, MyFunc) doesn't have a
// 'use server' directive at the top of the function scope,
// then add it.

const fn = path.node.arguments[1]

if (
t.isFunctionExpression(fn) ||
t.isArrowFunctionExpression(fn)
) {
if (t.isBlockStatement(fn.body)) {
const hasUseServerDirective =
fn.body.directives.some((directive) => {
return (
directive.value.value === 'use server'
)
})

if (!hasUseServerDirective) {
fn.body.directives.unshift(
t.directive(
t.directiveLiteral('use server'),
),
)
}
}
} else if (
t.isIdentifier(fn) ||
t.isCallExpression(fn)
) {
// A function was passed to createServerFn in the form of an
// identifier or a call expression that returns a function.

// We wrap the identifier/call expression in a function
// expression that accepts the same arguments as the original
// function with the "use server" directive at the top of the
// function scope.

const args = t.restElement(t.identifier('args'))

// Annotate args with the type:
// Parameters<Parameters<typeof createServerFn>[1]>

args.typeAnnotation = t.tsTypeAnnotation(
t.tsTypeReference(
t.identifier('Parameters'),
t.tsTypeParameterInstantiation([
t.tsIndexedAccessType(
t.tsTypeReference(
t.identifier('Parameters'),
t.tsTypeParameterInstantiation([
t.tsTypeQuery(
t.identifier('createServerFn'),
),
]),
),
t.tsLiteralType(t.numericLiteral(1)),
),
]),
),
)

const wrappedFn = t.arrowFunctionExpression(
[args],
t.blockStatement(
[
t.returnStatement(
t.callExpression(
t.memberExpression(
fn,
t.identifier('apply'),
),
[
t.identifier('this'),
t.identifier('args'),
],
),
),
],
[
t.directive(
t.directiveLiteral('use server'),
),
],
),
)

path.node.arguments[1] = wrappedFn
}
} else if (
if (
path.node.callee.name === 'createRoute' ||
path.node.callee.name === 'createFileRoute'
) {
Expand Down Expand Up @@ -389,97 +299,7 @@ export async function splitFile(opts: {
{
CallExpression: (path) => {
if (path.node.callee.type === 'Identifier') {
if (path.node.callee.name === 'createServerFn') {
// If the function at createServerFn(_, MyFunc) doesn't have a
// 'use server' directive at the top of the function scope,
// then add it.

const fn = path.node.arguments[1]

if (
t.isFunctionExpression(fn) ||
t.isArrowFunctionExpression(fn)
) {
if (t.isBlockStatement(fn.body)) {
const hasUseServerDirective =
fn.body.directives.some((directive) => {
return (
directive.value.value === 'use server'
)
})

if (!hasUseServerDirective) {
fn.body.directives.unshift(
t.directive(
t.directiveLiteral('use server'),
),
)
}
}
} else if (
t.isIdentifier(fn) ||
t.isCallExpression(fn)
) {
// A function was passed to createServerFn in the form of an
// identifier or a call expression that returns a function.

// We wrap the identifier/call expression in a function
// expression that accepts the same arguments as the original
// function with the "use server" directive at the top of the
// function scope.

const args = t.restElement(t.identifier('args'))

// Annotate args with the type:
// Parameters<Parameters<typeof createServerFn>[1]>

args.typeAnnotation = t.tsTypeAnnotation(
t.tsTypeReference(
t.identifier('Parameters'),
t.tsTypeParameterInstantiation([
t.tsIndexedAccessType(
t.tsTypeReference(
t.identifier('Parameters'),
t.tsTypeParameterInstantiation([
t.tsTypeQuery(
t.identifier('createServerFn'),
),
]),
),
t.tsLiteralType(t.numericLiteral(1)),
),
]),
),
)

const wrappedFn = t.arrowFunctionExpression(
[args],
t.blockStatement(
[
t.returnStatement(
t.callExpression(
t.memberExpression(
fn,
t.identifier('apply'),
),
[
t.identifier('this'),
t.identifier('args'),
],
),
),
],
[
t.directive(
t.directiveLiteral('use server'),
),
],
),
)

path.node.arguments[1] = wrappedFn
}
} else if (
if (
path.node.callee.name === 'createRoute' ||
path.node.callee.name === 'createFileRoute'
) {
Expand Down
6 changes: 2 additions & 4 deletions packages/router-vite-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,8 @@ export function TanStackRouterViteCodeSplitter(

return compiled
} else if (
(fileIsInRoutesDirectory(id, userConfig.routesDirectory) &&
(code.includes('createRoute(') ||
code.includes('createFileRoute('))) ||
code.includes('createServerFn')
fileIsInRoutesDirectory(id, userConfig.routesDirectory) &&
(code.includes('createRoute(') || code.includes('createFileRoute('))
) {
if (code.includes('@react-refresh')) {
throw new Error(
Expand Down
40 changes: 0 additions & 40 deletions packages/router-vite-plugin/tests/snapshots/createServerFn.tsx

This file was deleted.

This file was deleted.

44 changes: 0 additions & 44 deletions packages/router-vite-plugin/tests/test-files/createServerFn.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion packages/start-vite-plugin/src/compilers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export async function createServerFnCompiler(opts: {
if (specifier.type === 'ImportNamespaceSpecifier') {
identifierType = 'ImportNamespaceSpecifier'
namespaceId = specifier.local.name
serverFnId = `${specifier.local.name}.createServerFn`
serverFnId = `${namespaceId}.createServerFn`
}
})
},
Expand Down
9 changes: 5 additions & 4 deletions packages/start/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,11 @@
"src"
],
"dependencies": {
"@tanstack/react-cross-context": "workspace:*",
"@tanstack/react-router": "workspace:*",
"@tanstack/router-generator": "workspace:*",
"@tanstack/router-vite-plugin": "workspace:*",
"@tanstack/react-cross-context": "workspace:^",
"@tanstack/react-router": "workspace:^",
"@tanstack/router-generator": "workspace:^",
"@tanstack/router-vite-plugin": "workspace:^",
"@tanstack/start-vite-plugin": "workspace:^",
"@types/jsesc": "^3.0.3",
"@vinxi/react": "0.2.2",
"@vinxi/server-components": "^0.3.3",
Expand Down
8 changes: 5 additions & 3 deletions packages/start/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* eslint-disable no-shadow */
import path from 'path'
import { existsSync, readFileSync, writeFileSync } from 'fs'
import { readFile } from 'fs/promises'
import path from 'node:path'
import { existsSync, readFileSync, writeFileSync } from 'node:fs'
import { readFile } from 'node:fs/promises'
import reactRefresh from '@vitejs/plugin-react'
import { resolve } from 'import-meta-resolve'
import { TanStackRouterVite, configSchema } from '@tanstack/router-vite-plugin'
import { TanStackStartVite } from '@tanstack/start-vite-plugin'
import { getConfig } from '@tanstack/router-generator'
import { createApp } from 'vinxi'
import { config } from 'vinxi/plugins/config'
Expand Down Expand Up @@ -226,6 +227,7 @@ function startRouterProxy(tsrConfig: z.infer<typeof configSchema>) {
enableCodeSplitting: true,
},
}),
TanStackStartVite(),
...((await router?.plugins?.()) ?? []),
],
}
Expand Down
Loading