1
0
mirror of synced 2026-02-09 00:00:11 -05:00

Compare commits

...

11 Commits

Author SHA1 Message Date
Siddharth Suresh
f3d6e275fb throw error only in pages router 2024-04-02 17:26:08 +05:30
Siddharth Suresh
86ce7c8ff3 Merge branch 'main' into 03-16-Turbopack_support_for_Blitz 2024-04-02 12:16:22 +05:30
Siddharth Suresh
3a6f434ac8 chore: minor fix on how the test is run 2024-04-01 18:24:42 +05:30
Siddharth Suresh
de2a6e1f3d chore: add changeset 2024-04-01 18:10:32 +05:30
Siddharth Suresh
57b27ff137 use latest canary in internal packages and tests 2024-04-01 18:07:00 +05:30
Siddharth Suresh
f647881af4 upgrade to latest next version 2024-04-01 18:04:09 +05:30
Siddharth Suresh
0e66ba7947 feat: add tests for turbo and expose new turbo boolean 2024-04-01 18:01:13 +05:30
Siddharth Suresh
8f8e4eabc0 fix: CI and update next.js version in test app 2024-03-18 22:19:20 +05:30
Tim Neutkens
d74450e606 Update packages/blitz-rpc/src/server/loader/server/loader-server.ts
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
2024-03-17 16:15:26 +01:00
Tim Neutkens
f2c4f96cd5 Turbopack support for Blitz 2024-03-16 22:15:49 +01:00
Tim Neutkens
20309bc3fe Use this.rootContext instead of webpack internals
Ensures the root context is read from the public API that webpack exposes. This is the first step for Turbopack support as Turbopack includes `this.rootContext` as well
2024-03-15 17:00:53 +01:00
41 changed files with 1081 additions and 329 deletions

View File

@@ -0,0 +1,22 @@
---
"blitz": minor
"@blitzjs/next": minor
"@blitzjs/rpc": minor
---
Turbopack support for Blitz
This PR includes the changes required to make the Blitz loaders work with Turbopack.
Usage:
```ts
//next.config.js
const nextConfig = {
blitz: {
turbo: true,
},
}
module.exports = withBlitz(nextConfig)
```

View File

@@ -1,6 +1,18 @@
const {withBlitz} = require("@blitzjs/next")
const loaderClient = require.resolve("@blitzjs/rpc/dist/loader-client.cjs")
const loaderServer = require.resolve("@blitzjs/rpc/dist/loader-server.cjs")
const loaderServerResolvers = require.resolve("@blitzjs/rpc/dist/loader-server-resolvers.cjs")
console.log("loaderClient", loaderClient)
console.log("loaderServer", loaderServer)
console.log("loaderServerResolvers", loaderServerResolvers)
/** @type {import('next').NextConfig} */
const nextConfig = {}
const nextConfig = {
blitz: {
turbo: true,
},
}
module.exports = withBlitz(nextConfig)

View File

@@ -22,7 +22,7 @@
"@tanstack/react-query": "4.0.10",
"blitz": "2.0.6",
"flatted": "3.2.7",
"next": "14.0.4",
"next": "canary",
"prisma": "^4.5.0",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -31,7 +31,7 @@
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"openid-client": "5.2.1",
"prisma": "4.6.1",
"react": "18.2.0",

View File

@@ -32,7 +32,7 @@
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"next-auth": "4.18.7",
"prisma": "4.6.1",
"react": "18.2.0",

View File

@@ -26,7 +26,7 @@
"blitz": "2.0.6",
"jest": "29.3.0",
"jest-environment-jsdom": "29.3.0",
"next": "14.0.4",
"next": "canary",
"passport-mock-strategy": "2.0.0",
"passport-twitter": "1.0.4",
"prisma": "4.6.1",

View File

@@ -1,2 +1,6 @@
const {withBlitz} = require("@blitzjs/next")
module.exports = withBlitz({})
module.exports = withBlitz({
blitz: {
turbo: true,
},
})

View File

@@ -26,7 +26,7 @@
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"delay": "5.0.0",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -275,7 +275,7 @@ const runTests = () => {
}
describe("Auth Tests", () => {
describe("dev mode", () => {
describe("dev mode - webpack", () => {
beforeAll(async () => {
mode = "dev"
try {
@@ -290,6 +290,21 @@ describe("Auth Tests", () => {
runTests()
})
describe("dev mode - turbo", () => {
beforeAll(async () => {
mode = "dev"
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()}, true)
} catch (error) {
console.log(error)
}
}, 5000 * 60 * 2)
afterAll(async () => await killApp(app))
runTests()
})
describe("server mode", () => {
beforeAll(async () => {
mode = "server"

View File

@@ -23,7 +23,7 @@
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"lowdb": "3.0.0",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -22,7 +22,7 @@
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"lowdb": "3.0.0",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -15,7 +15,7 @@
"@blitzjs/next": "2.0.6",
"@blitzjs/rpc": "2.0.6",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -1,34 +0,0 @@
"use client"
import {useQuery, useMutation} from "@blitzjs/rpc"
import logout from "../src/auth/mutations/logout"
import getCurrentUser from "../src/users/queries/getCurrentUser"
import {useTransition} from "react"
import {useRouter} from "next/navigation"
export default function Test() {
const router = useRouter()
const [user] = useQuery(getCurrentUser, null)
const [isPending, startTransition] = useTransition()
const [logoutMutation] = useMutation(logout)
console.log(user)
return (
<div>
<h1>Test</h1>
<p>{user?.email}</p>
<button
className="button small"
onClick={async () => {
await logoutMutation()
startTransition(() => {
// Refresh the current route and fetch new data from the server without
// losing client-side browser or React state.
router.refresh()
})
}}
>
Logout
</button>
</div>
)
}

View File

@@ -1,2 +1,6 @@
const {withBlitz} = require("@blitzjs/next")
module.exports = withBlitz({})
module.exports = withBlitz({
blitz: {
turbo: true,
},
})

View File

@@ -24,7 +24,7 @@
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"lowdb": "3.0.0",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -153,7 +153,7 @@ const runTests = (mode?: string) => {
}
describe("Auth Tests", () => {
describe("dev mode", async () => {
describe("dev mode - webpack", async () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
@@ -169,19 +169,19 @@ describe("Auth Tests", () => {
runTests()
})
// describe("server mode", () => {
// beforeAll(async () => {
// try {
// await runBlitzCommand(["prisma", "generate"])
// await runBlitzCommand(["prisma", "migrate", "deploy"])
// await blitzBuild()
// // appPort = await findPort()
// app = await blitzStart(appPort, {cwd: process.cwd()})
// } catch (err) {
// console.log(err)
// }
// }, 5000 * 60 * 2)
// afterAll(async () => await killApp(app))
// runTests()
// })
describe("dev mode - turbo", async () => {
beforeAll(async () => {
try {
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
appPort = await findPort()
app = await blitzLaunchApp(appPort, {cwd: process.cwd()}, true)
} catch (error) {
console.log(error)
}
}, 5000 * 60 * 2)
afterAll(async () => {
await killApp(app)
})
runTests()
})
})

View File

@@ -22,7 +22,7 @@
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"lowdb": "3.0.0",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -15,7 +15,7 @@
"@prisma/client": "4.6.1",
"@tanstack/react-query": "4.0.10",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -21,7 +21,7 @@
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"lowdb": "3.0.0",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -22,7 +22,7 @@ function Content() {
)
}
function PageWithGetQueryData() {
function PageWithMonorepoGetQueryData() {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
@@ -32,4 +32,4 @@ function PageWithGetQueryData() {
)
}
export default PageWithGetQueryData
export default PageWithMonorepoGetQueryData

View File

@@ -11,7 +11,7 @@
"@blitzjs/next": "2.0.6",
"@blitzjs/rpc": "2.0.6",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -11,7 +11,7 @@
"@blitzjs/next": "2.0.6",
"@blitzjs/rpc": "2.0.6",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -22,7 +22,7 @@
"@prisma/client": "4.6.1",
"blitz": "2.0.6",
"lowdb": "3.0.0",
"next": "14.0.4",
"next": "canary",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -231,9 +231,11 @@ export function runBlitzCommandDev(argv, stdOut, opts: RunNextCommandDevOptions
__NEXT_TEST_MODE: "true",
...opts.env,
}
const turbo = opts.turbo ? ["--turbo"] : []
return new Promise<void>((resolve, reject) => {
const instance = spawn("node", [blitzBin, ...argv], {
console.log(`Running command "blitz ${argv.join(" ")}"`)
const instance = spawn("node", [blitzBin, ...argv, ...turbo], {
cwd,
env,
} as {})
@@ -294,8 +296,8 @@ export function runBlitzCommandDev(argv, stdOut, opts: RunNextCommandDevOptions
}
// Blitz Utils
export function blitzLaunchApp(port, opts: RunNextCommandDevOptions) {
return runBlitzCommandDev(["dev", "-p", port], undefined, opts)
export function blitzLaunchApp(port, opts: RunNextCommandDevOptions, turbo = false) {
return runBlitzCommandDev(["dev", "-p", port, turbo ? "--turbo" : ""], undefined, opts)
}
export function blitzBuild(args = [], opts = {}): any {
@@ -437,7 +439,7 @@ export function runNextCommandDev(argv, stdOut, opts: RunNextCommandDevOptions =
}
if (opts.stdout !== false) {
process.stdout.write(message)
process.stdout.write(message)
}
}
@@ -923,4 +925,5 @@ interface RunNextCommandDevOptions {
nodeArgs?: []
bootupMarker?: any
nextStart?: boolean
turbo?: boolean
}

View File

@@ -29,7 +29,7 @@
"husky": "8.0.2",
"jsdom": "^19.0.0",
"lint-staged": "13.0.3",
"next": "14.0.4",
"next": "canary",
"only-allow": "1.1.0",
"prettier": "^2.7.1",
"prettier-plugin-prisma": "4.4.0",

View File

@@ -76,7 +76,7 @@
"@types/react": "18.0.25",
"@types/react-dom": "17.0.14",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"next-auth": "4.18.7",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -59,7 +59,7 @@
"blitz": "2.0.6",
"cross-spawn": "7.0.3",
"find-up": "4.1.0",
"next": "14.0.4",
"next": "canary",
"next-router-mock": "0.9.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -28,6 +28,7 @@ import {
getInfiniteQueryKey,
getQueryKey,
installWebpackConfig,
installTurboConfig,
InstallWebpackConfigOptions,
ResolverPathOptions,
DefaultOptions,
@@ -239,6 +240,7 @@ export interface BlitzConfig extends NextConfig {
customServer?: {
hotReload?: boolean
}
turbo: boolean
}
}
@@ -300,6 +302,12 @@ export function withBlitz(nextConfig: BlitzConfig = {}): NextConfig {
},
})
if (nextConfig.blitz?.turbo) {
;(config as any).experimental = {
turbo: installTurboConfig(),
}
}
const {blitz, ...rest} = config
return rest
}

View File

@@ -49,7 +49,7 @@
"@types/react": "18.0.25",
"@types/react-dom": "17.0.14",
"blitz": "2.0.6",
"next": "14.0.4",
"next": "canary",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "^4.8.4",

View File

@@ -157,6 +157,44 @@ export function installWebpackConfig({
})
}
export function installTurboConfig() {
return {
resolveAlias: {
"cross-spawn": {browser: "./turbopack/empty.js"},
"npm-which": {browser: "./turbopack/empty.js"},
fs: {browser: "./turbopack/empty.js"},
},
rules: {
"**/*...blitz*.{jsx,tsx,js,ts}": {
default: {
loaders: [{loader: loaderServer, options: {}}],
as: "*.ts",
},
},
"**/{queries,mutations}/**": {
browser: {
loaders: [
{
loader: loaderClient,
options: {},
},
],
as: "*.ts",
},
default: {
loaders: [
{
loader: loaderServerResolvers,
options: {},
},
],
as: "*.ts",
},
},
},
}
}
// ----------
// END LOADER
// ----------

View File

@@ -86,8 +86,10 @@ export function useQuery<
const suspenseEnabled = Boolean(globalThis.__BLITZ_SUSPENSE_ENABLED)
let enabled = isServer && suspenseEnabled ? false : options?.enabled ?? options?.enabled !== null
let routerIsReady = false
let isPagesRouter = false
const router = useRouter()
if (router) {
isPagesRouter = true
routerIsReady = router?.isReady || (isServer && suspenseEnabled)
} else {
routerIsReady = true
@@ -110,7 +112,8 @@ export function useQuery<
suspenseEnabled !== false &&
!data &&
(!options || !("suspense" in options) || options.suspense) &&
(!options || !("enabled" in options) || options.enabled)
(!options || !("enabled" in options) || options.enabled) &&
isPagesRouter
) {
const e = new NextError()
e.name = "Rendering Suspense fallback..."
@@ -174,8 +177,10 @@ export function usePaginatedQuery<
let enabled = isServer && suspenseEnabled ? false : options?.enabled ?? options?.enabled !== null
let routerIsReady = false
const router = useRouter()
let isPagesRouter = false
if (router) {
routerIsReady = router?.isReady || (isServer && suspenseEnabled)
isPagesRouter = true
} else {
routerIsReady = true
}
@@ -198,7 +203,8 @@ export function usePaginatedQuery<
suspenseEnabled !== false &&
!data &&
(!options || !("suspense" in options) || options.suspense) &&
(!options || !("enabled" in options) || options.enabled)
(!options || !("enabled" in options) || options.enabled) &&
isPagesRouter
) {
const e = new NextError()
e.name = "Rendering Suspense fallback..."
@@ -270,9 +276,11 @@ export function useInfiniteQuery<
const suspenseEnabled = Boolean(globalThis.__BLITZ_SUSPENSE_ENABLED)
let enabled = isServer && suspenseEnabled ? false : options?.enabled ?? options?.enabled !== null
let routerIsReady = false
let isPagesRouter = false
const router = useRouter()
if (router) {
routerIsReady = router?.isReady || (isServer && suspenseEnabled)
isPagesRouter = true
} else {
routerIsReady = true
}
@@ -298,7 +306,8 @@ export function useInfiniteQuery<
suspenseEnabled !== false &&
!data &&
(!options || !("suspense" in options) || options.suspense) &&
(!options || !("enabled" in options) || options.enabled)
(!options || !("enabled" in options) || options.enabled) &&
isPagesRouter
) {
const e = new NextError()
e.name = "Rendering Suspense fallback..."

View File

@@ -14,12 +14,24 @@ import {getResolverConfig} from "../../parsers/parse-rpc-config"
// Subset of `import type { LoaderDefinitionFunction } from 'webpack'`
export async function loader(this: Loader, input: string): Promise<string> {
const compiler = this._compiler!
const id = this.resource
const root = this._compiler!.context
const root = this.rootContext
const isSSR = compiler.name === "server"
if (!isSSR) {
// Webpack has `_compiler` property. Turbopack does not.
const webpackCompilerName = this._compiler?.name
if (webpackCompilerName) {
const isSSR = webpackCompilerName === "server"
if (!isSSR) {
return await transformBlitzRpcResolverClient(
input,
toPosixPath(id),
toPosixPath(root),
this.query,
)
}
// Handle Turbopack / other bundlers case.
// The decision of which environment to run the loader in is decided by the loader configuration instead.
} else {
return await transformBlitzRpcResolverClient(
input,
toPosixPath(id),

View File

@@ -13,12 +13,24 @@ import {posix} from "path"
// Subset of `import type { LoaderDefinitionFunction } from 'webpack'`
export async function loader(this: Loader, input: string): Promise<string> {
const compiler = this._compiler!
const id = this.resource
const root = this._compiler!.context
const root = this.rootContext
const isSSR = compiler.name === "server"
if (isSSR) {
// Webpack has `_compiler` property. Turbopack does not.
const webpackCompilerName = this._compiler?.name
if (webpackCompilerName) {
const isSSR = webpackCompilerName === "server"
if (isSSR) {
return await transformBlitzRpcResolverServer(
input,
toPosixPath(id),
toPosixPath(root),
this.query,
)
}
// Handle Turbopack / other bundlers case.
// The decision of which environment to run the loader in is decided by the loader configuration instead.
} else {
return await transformBlitzRpcResolverServer(
input,
toPosixPath(id),

View File

@@ -1,4 +1,4 @@
import {join} from "path"
import {join, relative} from "path"
import {promises} from "fs"
import {
assertPosixPath,
@@ -14,17 +14,37 @@ import {
// Subset of `import type { LoaderDefinitionFunction } from 'webpack'`
export async function loader(this: Loader, input: string): Promise<string> {
const compiler = this._compiler!
const id = this.resource
const root = this._compiler!.context
const root = this.rootContext
const rpcFolders = this.query.includeRPCFolders ? this.query.includeRPCFolders : []
const isSSR = compiler.name === "server"
if (isSSR) {
// Webpack has `_compiler` property. Turbopack does not.
const webpackCompilerName = this._compiler?.name
if (webpackCompilerName) {
const isSSR = webpackCompilerName === "server"
if (isSSR) {
this.cacheable(false)
const resolvers = await collectResolvers(root, rpcFolders, ["ts", "js", "tsx", "jsx"])
return await transformBlitzRpcServer(
this.context,
input,
toPosixPath(id),
toPosixPath(root),
resolvers,
this.query,
)
}
// Handle Turbopack / other bundlers case.
// The decision of which environment to run the loader in is decided by the loader configuration instead.
} else {
this.cacheable(false)
const resolvers = await collectResolvers(root, rpcFolders, ["ts", "js", "tsx", "jsx"])
return await transformBlitzRpcServer(
this.context,
input,
toPosixPath(id),
toPosixPath(root),
@@ -43,6 +63,7 @@ function slash(str: string) {
}
export async function transformBlitzRpcServer(
context: string,
src: string,
id: string,
root: string,
@@ -68,7 +89,9 @@ export async function transformBlitzRpcServer(
code += `__internal_addBlitzRpcResolver('${routePath}','${slash(
resolverFilePath,
)}',() => ${importStrategy}('${slash(resolverFilePath)}'));`
)}',() => ${importStrategy}('${slash(
relative(context, resolverFilePath).replace(/\\/g, "/"),
)}'))`
code += "\n"
}

View File

@@ -9,10 +9,11 @@ export interface LoaderOptions {
}
export interface Loader {
_compiler?: {
_compiler: {
name: string
context: string
}
rootContext: string
context: string
resource: string
cacheable: (enabled: boolean) => void
query: LoaderOptions

View File

@@ -84,6 +84,5 @@ if (typeof window !== "undefined" && process.env.NODE_ENV === "development") {
export * from "./utils"
export * from "./types"
export * from "./utils/enhance-prisma"
export * from "./utils/zod"
export {reduceBlitzClientPlugins} from "./plugin"

View File

@@ -13,6 +13,7 @@ export {reduceBlitzServerPlugins} from "./plugin"
export {findNodeModulesRoot, findNodeModulesRootSync} from "./cli/utils/find-node-modules"
export {startWatcher, stopWatcher} from "./cli/utils/routes-manifest"
export * from "./utils/enhance-prisma"
export interface MiddlewareResponse<C extends Ctx = Ctx> extends ServerResponse {
blitzCtx: C

View File

@@ -31,7 +31,7 @@
"@prisma/client": "5.4.2",
"blitz": "latest",
"formik": "2.4.5",
"next": "13.5.4",
"next": "14.1.4",
"prisma": "5.4.2",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -27,7 +27,7 @@
"@blitzjs/rpc": "latest",
"@prisma/client": "4.6.1",
"blitz": "latest",
"next": "13.4.5",
"next": "14.1.4",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -27,7 +27,7 @@
"@blitzjs/rpc": "latest",
"@prisma/client": "4.6.1",
"blitz": "latest",
"next": "13.4.5",
"next": "14.1.4",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",

1077
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff