Skip to content

Commit 87f739f

Browse files
committed
refactor(platform): resolve via #platform import map and unify type contract
Replace the template-literal `await import()` pattern in next.config.mjs, mdx/plugins.mjs, and playwright.config.ts with a static `import from '#platform/...'` resolved by Node's subpath imports. Each platform's build command sets `NODE_OPTIONS=--conditions=<target>` so the imports map selects the matching @node-core/platform-* package; without the flag, the site's local no-op file is used. Consolidate the duplicated PlatformConfig / PlatformPlaywrightConfig types into apps/site, the contract owner. Platform .mjs files JSDoc the site types via relative path; platform-side .d.ts duplicates are removed. Also: arrow-function instrumentation hooks; prune the redundant PLAYWRIGHT_BASE_URL env from the Cloudflare Playwright workflow and config (kept in the Vercel workflow where it carries the dynamic preview URL).
1 parent 23bfde7 commit 87f739f

22 files changed

Lines changed: 50 additions & 93 deletions

.github/workflows/playwright-cloudflare-open-next.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555
run: node --run playwright
5656
env:
5757
NEXT_PUBLIC_DEPLOY_TARGET: cloudflare
58-
PLAYWRIGHT_BASE_URL: http://127.0.0.1:8787
58+
NODE_OPTIONS: --conditions=cloudflare
5959

6060
- name: Upload Playwright test results
6161
if: always()

apps/cloudflare/next.platform.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const require = createRequire(import.meta.url);
1212
* Must export a default `{ nextConfig, aliases, images }` shape — any of
1313
* which may be omitted when the platform has nothing to contribute.
1414
*
15-
* @type {import('@node-core/platform-cloudflare/next.platform.config').PlatformConfig}
15+
* @type {import('../site/next.platform.config').PlatformConfig}
1616
*/
1717
export default {
1818
nextConfig: {

apps/cloudflare/open-next.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const cloudflareConfig = defineCloudflareConfig({
2121
const openNextConfig: OpenNextConfig = {
2222
...cloudflareConfig,
2323
buildCommand:
24-
'cross-env NEXT_PUBLIC_DEPLOY_TARGET=cloudflare pnpm build --webpack',
24+
'cross-env NEXT_PUBLIC_DEPLOY_TARGET=cloudflare NODE_OPTIONS=--conditions=cloudflare pnpm build --webpack',
2525
cloudflare: {
2626
skewProtection: { enabled: true },
2727
},

apps/cloudflare/playwright.platform.config.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
* loader. Spins up the wrangler preview so E2E runs against the
66
* OpenNext worker artifact rather than `next dev`.
77
*
8-
* @type {import('./playwright.platform.config').PlatformPlaywrightConfig}
8+
* @type {import('../site/playwright.platform.config').PlatformPlaywrightConfig}
99
*/
1010
export default {
1111
baseURL: 'http://127.0.0.1:8787',
1212
webServer: {
1313
stdout: 'pipe',
1414
command:
1515
'../../node_modules/.bin/turbo cloudflare:preview --filter=@node-core/platform-cloudflare',
16-
url: process.env.PLAYWRIGHT_BASE_URL || 'http://127.0.0.1:8787',
16+
url: 'http://127.0.0.1:8787',
1717
timeout: 60_000 * 3,
1818
},
1919
};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export function register() {}
1+
export const register = () => {};

apps/cloudflare/tsconfig.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
"include": [
1717
"src",
1818
"next.platform.config.mjs",
19-
"playwright.platform.config.mjs",
20-
"playwright.platform.config.d.ts"
19+
"playwright.platform.config.mjs"
2120
],
2221
"exclude": ["src/worker-entrypoint.ts"]
2322
}

apps/site/mdx/plugins.mjs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,13 @@ import rehypeSlug from 'rehype-slug';
77
import remarkGfm from 'remark-gfm';
88
import readingTime from 'remark-reading-time';
99

10-
import { DEPLOY_TARGET } from '../next.constants.mjs';
11-
import remarkTableTitles from '../util/table';
10+
// MDX overrides contributed by the active deployment target. Resolved via
11+
// the `#platform/next.platform.config` import map in `package.json`; each
12+
// platform owns its own `{ wasm, twoslash }` defaults and the in-repo
13+
// default file acts as the standalone fallback.
14+
import platform from '#platform/next.platform.config';
1215

13-
// Load MDX overrides contributed by the active deployment target. Keeps
14-
// this module free of platform-specific branches — each platform owns
15-
// its own `{ wasm, twoslash }` defaults via `next.platform.config.mjs`,
16-
// with the in-repo default config serving as the standalone fallback.
17-
const { default: platform } = DEPLOY_TARGET
18-
? await import(`@node-core/platform-${DEPLOY_TARGET}/next.platform.config`)
19-
: await import('../next.platform.config.mjs');
16+
import remarkTableTitles from '../util/table';
2017

2118
// Shiki is created out here to avoid an async rehype plugin
2219
const singletonShiki = await rehypeShikiji(platform.mdx);

apps/site/next.config.mjs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,12 @@
22

33
import createNextIntlPlugin from 'next-intl/plugin';
44

5-
import {
6-
BASE_PATH,
7-
DEPLOY_TARGET,
8-
ENABLE_STATIC_EXPORT,
9-
} from './next.constants.mjs';
5+
import platform from '#platform/next.platform.config';
6+
7+
import { BASE_PATH, ENABLE_STATIC_EXPORT } from './next.constants.mjs';
108
import { getImagesConfig } from './next.image.config.mjs';
119
import { redirects, rewrites } from './next.rewrites.mjs';
1210

13-
/**
14-
* Loads the deployment platform's `next.platform.config.mjs` — falling back
15-
* to the local no-op when no platform is active. Each platform package
16-
* (`@node-core/platform-<target>`) owns its own file and contributes
17-
* `{ nextConfig, aliases, images }`. Adding a new platform only means
18-
* creating a new `@node-core/platform-<target>` package.
19-
*/
20-
const { default: platform } = DEPLOY_TARGET
21-
? await import(`@node-core/platform-${DEPLOY_TARGET}/next.platform.config`)
22-
: await import('./next.platform.config.mjs');
23-
2411
/** @type {import('next').NextConfig} */
2512
const nextConfig = {
2613
// Full Support of React 18 SSR and Streaming
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import type { HighlighterOptions } from '@node-core/rehype-shiki';
12
import type { NextConfig } from 'next';
23

3-
type PlatformMdxConfig = Pick<
4-
import('@node-core/rehype-shiki').HighlighterOptions,
5-
'wasm' | 'twoslash'
6-
>;
4+
type PlatformMdxConfig = Pick<HighlighterOptions, 'wasm' | 'twoslash'>;
75
type PlatformNextConfig = Pick<NextConfig, 'deploymentId' | 'env'>;
86

7+
/**
8+
* Shared platform-config contract consumed by `apps/site/next.config.mjs`
9+
* and implemented by each `@node-core/platform-<target>` package.
10+
*/
911
export type PlatformConfig = {
1012
aliases?: Record<string, string>;
1113
images?: NextConfig['images'];

apps/site/next.platform.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
* Alias values are project-relative strings (not absolute paths) so
1010
* Turbopack resolves them correctly — Turbopack treats absolute paths
1111
* as server-relative and rejects them.
12+
*
13+
* @type {import('./next.platform.config').PlatformConfig}
1214
*/
1315
export default {
1416
aliases: {

0 commit comments

Comments
 (0)