Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions examples/react-syntax-highlighter/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import ClientCode from "./Code.jsx";

import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript";
import { vs } from "react-syntax-highlighter/dist/esm/styles/hljs";

SyntaxHighlighter.registerLanguage("javascript", js);

function Code() {
return (
<SyntaxHighlighter language="javascript" style={vs}>
{`import { createServer } from 'react-server';`}
</SyntaxHighlighter>
);
}

export default function App() {
return (
<html lang="en" suppressHydrationWarning>
<body suppressHydrationWarning>
<h1>react-syntax-highlighter</h1>
<Code />
<ClientCode />
</body>
</html>
);
}
15 changes: 15 additions & 0 deletions examples/react-syntax-highlighter/Code.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"use client";

import { Light as SyntaxHighlighter } from "react-syntax-highlighter";
import js from "react-syntax-highlighter/dist/esm/languages/hljs/javascript";
import { dark } from "react-syntax-highlighter/dist/esm/styles/hljs";

SyntaxHighlighter.registerLanguage("javascript", js);

export default function ClientCode() {
return (
<SyntaxHighlighter language="javascript" style={dark}>
{`import { Link } from '@lazarv/react-server/navigation';`}
</SyntaxHighlighter>
);
}
17 changes: 17 additions & 0 deletions examples/react-syntax-highlighter/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "@lazarv/react-server-example-react-syntax-highlighter",
"private": true,
"description": "@lazarv/react-server React Syntax Highlighter example application",
"scripts": {
"dev": "react-server ./App.jsx",
"build": "react-server build ./App.jsx",
"start": "react-server start"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@lazarv/react-server": "workspace:^",
"react-syntax-highlighter": "^15.6.6"
}
}
4 changes: 2 additions & 2 deletions packages/react-server/bin/cli.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ try {

// Check Node.js version
if (cli.matchedCommand.__react_server_check_node_version__ !== false) {
if (checkJSRuntimeVersion()) {
if (cli.options.check !== false && checkJSRuntimeVersion()) {
exit(1);
}
}
Expand All @@ -62,7 +62,7 @@ try {
cli.matchedCommand &&
cli.matchedCommand.__react_server_check_deps__ !== false
) {
if (await checkReactDependencies()) {
if (cli.options.check !== false && (await checkReactDependencies())) {
exit(1);
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/react-server/bin/commands/build.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default (cli) =>
}
)
.option("--no-color", "disable color output", { default: false })
.option("--no-check", "skip dependency checks", { default: false })
.option("--server", "[boolean] build server", { default: true })
.option("--client", "[boolean] build client", { default: true })
.option("--export", "[boolean] static export")
Expand Down
1 change: 1 addition & 0 deletions packages/react-server/bin/commands/dev.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default (cli) =>
default: false,
})
.option("--no-color", "disable color output", { default: false })
.option("--no-check", "skip dependency checks", { default: false })
.option("-e, --eval <code>", "evaluate code", { type: "string" })
.option("-o, --outDir <dir>", "[string] output directory", {
default: ".react-server",
Expand Down
2 changes: 1 addition & 1 deletion packages/react-server/client/error-overlay.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export const showErrorOverlay = async (error, source, force, type, args) => {
const link = document.createElement("link");
link.rel = "stylesheet";
const { default: href } = await import(
"highlight.js/styles/github-dark.css?url"
"react-server-highlight.js/styles/github-dark.css?url"
);
link.href = href;
overlay.shadowRoot.appendChild(link);
Expand Down
10 changes: 5 additions & 5 deletions packages/react-server/client/highlight.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import hljs from "highlight.js/lib/core";
import diff from "highlight.js/lib/languages/diff";
import javascript from "highlight.js/lib/languages/javascript";
import json from "highlight.js/lib/languages/json";
import xml from "highlight.js/lib/languages/xml";
import hljs from "react-server-highlight.js/lib/core";
import diff from "react-server-highlight.js/lib/languages/diff";
import javascript from "react-server-highlight.js/lib/languages/javascript";
import json from "react-server-highlight.js/lib/languages/json";
import xml from "react-server-highlight.js/lib/languages/xml";

hljs.registerLanguage("diff", diff);
hljs.registerLanguage("javascript", javascript);
Expand Down
15 changes: 11 additions & 4 deletions packages/react-server/lib/build/server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ import {
} from "../utils/plugins.mjs";
import banner from "./banner.mjs";
import customLogger from "./custom-logger.mjs";
import { bareImportRE, findNearestPackageData } from "../utils/module.mjs";
import {
bareImportRE,
findNearestPackageData,
isSubpathExported,
nodeResolve,
} from "../utils/module.mjs";
import { realpathSync } from "node:fs";

const __require = createRequire(import.meta.url);
Expand Down Expand Up @@ -70,6 +75,7 @@ export default async function serverBuild(root, options) {
"picocolors",
"unstorage",
/^unstorage\/drivers\//,
/^react-server-highlight\.js/,
...(Array.isArray(config.build?.rollupOptions?.external)
? config.build?.rollupOptions?.external
: []),
Expand All @@ -95,14 +101,14 @@ export default async function serverBuild(root, options) {
}
return false;
};
const rscExternal = (id) => {
const rscExternal = (id, importer) => {
if (isBuiltin(id)) {
return true;
}

if (bareImportRE.test(id)) {
try {
const mod = __require.resolve(id, { paths: [cwd] });
const mod = nodeResolve(id, realpathSync(importer));
let pkg = findNearestPackageData(mod);
const prev = pkg;
if (pkg) {
Expand All @@ -121,7 +127,8 @@ export default async function serverBuild(root, options) {
if (
/[cm]?js$/.test(mod) &&
!(pkg?.type === "module" || pkg?.module || pkg?.exports) &&
![...(config.ssr?.noExternal ?? [])].includes(id)
![...(config.ssr?.noExternal ?? [])].includes(id) &&
isSubpathExported(pkg, id)
) {
return true;
}
Expand Down
35 changes: 19 additions & 16 deletions packages/react-server/lib/dev/create-server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import * as sys from "../sys.mjs";
import { makeResolveAlias } from "../utils/config.mjs";
import { replaceError } from "../utils/error.mjs";
import merge from "../utils/merge.mjs";
import { findPackageRoot, tryStat } from "../utils/module.mjs";
import { findPackageRoot, nodeResolve, tryStat } from "../utils/module.mjs";
import {
filterOutVitePluginReact,
userOrBuiltInVitePluginReact,
Expand Down Expand Up @@ -147,11 +147,11 @@ export default async function createServer(root, options) {
"react-server-dom-webpack/server.browser",
"react-is",
"@jridgewell/trace-mapping",
"highlight.js/lib/core",
"highlight.js/lib/languages/diff",
"highlight.js/lib/languages/javascript",
"highlight.js/lib/languages/json",
"highlight.js/lib/languages/xml",
"react-server-highlight.js/lib/core",
"react-server-highlight.js/lib/languages/diff",
"react-server-highlight.js/lib/languages/javascript",
"react-server-highlight.js/lib/languages/json",
"react-server-highlight.js/lib/languages/xml",
"socket.io-client",
"web-streams-polyfill/polyfill",
...(config.optimizeDeps?.include ?? []),
Expand Down Expand Up @@ -190,19 +190,23 @@ export default async function createServer(root, options) {
alias: [
...resolvedClientAlias,
{
find: /^highlight\.js\/lib/,
find: /^react-server-highlight\.js\/lib/,
replacement: sys.normalizePath(
dirname(__require.resolve("highlight.js/lib/core"))
),
},
{
find: /^react-server-highlight\.js\/styles/,
replacement: sys
.normalizePath(dirname(__require.resolve("highlight.js/lib/core")))
.replace("/lib", "/styles"),
},
{
find: /^@jridgewell\/trace-mapping$/,
replacement: sys.normalizePath(
typeof import.meta.resolve === "function"
? import.meta.resolve("@jridgewell/trace-mapping")
: __require
.resolve("@jridgewell/trace-mapping")
.replace(/\.umd\.js$/, ".mjs")
__require
.resolve("@jridgewell/trace-mapping")
.replace(/\.umd\.js$/, ".mjs")
),
},
{ find: /^@lazarv\/react-server$/, replacement: sys.rootDir },
Expand Down Expand Up @@ -342,7 +346,7 @@ export default async function createServer(root, options) {
"picocolors",
"unstorage",
"@modelcontextprotocol/sdk",
"highlight.js",
"react-server-highlight.js",
],
alias: [
{
Expand Down Expand Up @@ -512,8 +516,7 @@ export default async function createServer(root, options) {
} catch {
return {
result: {
externalize: specifier,
type: "module",
externalize: nodeResolve(specifier, parentId),
},
};
}
Expand Down Expand Up @@ -561,7 +564,7 @@ export default async function createServer(root, options) {
} = payload.data.data;

let result = {
externalize: specifier,
externalize: nodeResolve(specifier, parentId),
};

if (!isBuiltin(specifier)) {
Expand Down
2 changes: 0 additions & 2 deletions packages/react-server/lib/dev/render-stream.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ Object.keys(console).forEach((method) => {
import("react-server-dom-webpack/server.browser").then(
({ renderToReadableStream }) => {
delete React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;
const cwd = process.cwd();
const normalizedArgs = args.map((arg) => {
if (arg instanceof Error) {
const stacklines = arg.stack
Expand All @@ -54,7 +53,6 @@ Object.keys(console).forEach((method) => {
.map((it) =>
it
.trim()
.replace(location.origin, it.includes(cwd) ? "" : cwd)
.replace("/@fs", "")
.replace(/\?v=[a-z0-9]+/, "")
);
Expand Down
8 changes: 8 additions & 0 deletions packages/react-server/lib/loader/module-alias.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export function moduleAliases(condition) {
// noop
}

let reactClient = react;
if (condition === "react-server") {
reactClient = react;
react = react.replace(/index\.js$/, "react.react-server.js");
reactJsxRuntime = reactJsxRuntime.replace(
/jsx-runtime\.js$/,
Expand All @@ -39,6 +41,7 @@ export function moduleAliases(condition) {
reactDom = reactDom.replace(/index\.js$/, "react-dom.react-server.js");
} else {
react = react.replace(/react\.react-server\.js$/, "index.js");
reactClient = react;
reactJsxRuntime = reactJsxRuntime.replace(
/jsx-runtime\.react-server\.js$/,
"jsx-runtime.js"
Expand Down Expand Up @@ -76,6 +79,9 @@ export function moduleAliases(condition) {
const unstorageDriversSessionStorage = normalizePath(
__require.resolve("unstorage/drivers/session-storage")
);
const reactServerHighlightJs = normalizePath(
__require.resolve("highlight.js")
);
let vite;
try {
vite = normalizePath(__require.resolve("rolldown-vite")).replace(
Expand All @@ -88,6 +94,7 @@ export function moduleAliases(condition) {

const moduleAliases = {
react,
"react/client": reactClient,
"react/jsx-runtime": reactJsxRuntime,
"react/jsx-dev-runtime": reactJsxDevRuntime,
"react-dom": reactDom,
Expand All @@ -102,6 +109,7 @@ export function moduleAliases(condition) {
"unstorage/drivers/session-storage": unstorageDriversSessionStorage,
vite,
scheduler,
"react-server-highlight.js": reactServerHighlightJs,
};

return moduleAliases;
Expand Down
25 changes: 24 additions & 1 deletion packages/react-server/lib/loader/node-loader.mjs
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
import { existsSync } from "node:fs";
import { fileURLToPath, pathToFileURL } from "node:url";

import { moduleAliases } from "../loader/module-alias.mjs";
import { applyAlias } from "./utils.mjs";

const alias = moduleAliases();

export async function resolve(specifier, context, nextResolve) {
return await nextResolve(applyAlias(alias, specifier), context);
try {
return await nextResolve(applyAlias(alias, specifier), context);
} catch (e) {
if (e.code === "ERR_MODULE_NOT_FOUND" && !specifier.endsWith(".js")) {
const jsSpecifier = `${specifier}.js`;

if (jsSpecifier.startsWith("file:")) {
const candidatePath = fileURLToPath(jsSpecifier);
if (existsSync(candidatePath)) {
return await nextResolve(pathToFileURL(candidatePath).href, context);
}
} else {
try {
return await nextResolve(jsSpecifier, context);
} catch {
throw e;
}
}
}
throw e;
}
}
36 changes: 33 additions & 3 deletions packages/react-server/lib/loader/node-loader.react-server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,46 @@ import { applyAlias } from "./utils.mjs";

const alias = moduleAliases("react-server");
const reactUrl = pathToFileURL(alias.react);
const reactClientUrl = pathToFileURL(alias["react/client"]);

export async function resolve(specifier, context, nextResolve) {
return await nextResolve(applyAlias(alias, specifier), {
const reactServerContext = {
...context,
conditions: [...context.conditions, "react-server"],
});
};
try {
return await nextResolve(applyAlias(alias, specifier), {
...reactServerContext,
});
} catch (e) {
if (e.code === "ERR_MODULE_NOT_FOUND" && !specifier.endsWith(".js")) {
const jsSpecifier = `${specifier}.js`;

if (jsSpecifier.startsWith("file:")) {
const candidatePath = fileURLToPath(jsSpecifier);
try {
await readFile(candidatePath);
return await nextResolve(
pathToFileURL(candidatePath).href,
reactServerContext
);
} catch {
throw e;
}
} else {
try {
return await nextResolve(jsSpecifier, reactServerContext);
} catch {
throw e;
}
}
}
throw e;
}
}

export async function load(url, context, nextLoad) {
if (url === reactUrl.href) {
if (url === reactUrl.href || url === reactClientUrl.href) {
const format = "commonjs";
const code = await readFile(fileURLToPath(reactUrl), "utf8");
const source = reactServerPatch(code);
Expand Down
Loading