在现有 React 应用程序中逐渐 Next.js 采用
Gradual Next.js adoption from within existing React application
我正在尝试寻找任何示例来概述如何采用现有的 React 应用程序并逐渐开始向 Next.js 迁移。我已经阅读了所有关于增量采用策略(例如子路径、重写、微前端、代理)的 Next.js 文档,但还没有找到一个可靠的例子来展示这在现实生活中的实际情况“我已经有了一个庞大的 React 代码库”场景。
期望的结果是关闭我现有应用程序的子路径,比如 /workshop
,并让 /workshop
成为 Next.js 应用程序的入口点。然后我希望能够在这两个应用程序之间无缝导航,尽管一旦您进入 Next.js 领域并需要导航回代理之外,这种机制似乎很模糊。
为了增加上下文,React 和 Next.js 应用程序都将在 Netlify 上提供服务。我已经仔细阅读了他们的文档以及 Vercel 的文档,寻找一个有效的示例,但我仍然不走运。非常感谢任何关于如何最好地解决此类问题的知识或指导!
对于那些感兴趣的人,我能够创建一个工作演示。
https://hybrid-next-react.vercel.app/
https://github.com/coloradocolby/hybrid-next-react
它的工作方式相当简单。这是一个基本的 Next.js 应用程序,具有 [...app].js
的捕获所有路由,它服务于 React SPA 的入口点。一个简单的 isMounted
变量(可以很容易地重构为一个钩子)确保服务器永远不会处理 React SPA(可能具有特定于浏览器的代码)。
import { useEffect, useState } from "react";
import CreateReactAppRoot from "../src/App";
const App = () => {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
// Don't render client-side app unless window is available.
// NOTE: Page not statically pre-rendered nor server-side renderable
return isMounted ? <CreateReactAppRoot /> : null;
};
export default App;
最后一步是确保实现从 React SPA 到任何用于 Next.js 的路由的整页重新加载。这确保了 Next.js 路由机制被触发。在上面的演示中,我创建了 Next.js 和 React 特定的导航栏。
import React from "react";
import Link from "next/link";
import { useRouter } from "next/router";
export const NextNavbar = () => {
const router = useRouter();
return (
<nav>
{!router.pathname.includes("[...app]") && (
<ul className="flex p-4">
<li className="mr-3">
<Link href="/" passHref>
<div className="inline-block px-4 py-2 rounded cursor-pointer">
Home
</div>
</Link>
</li>
...
</ul>
)}
</nav>
);
};
再一次,虽然 Next.js 可以智能地 link 到 React SPA,因为我们的 catch all 路由,React SPA 需要整页重新加载到任何用于 Next.js 的路由.如您所料,如果目标路由要保留在 React SPA 内,则没有必要。
import React from "react";
import { Link } from "react-router-dom";
export const ReactNavbar = () => (
<nav>
<ul className="flex p-4">
<li className="mr-3">
<a href="/">
<div className="inline-block px-4 py-2 rounded cursor-pointer">
Home
</div>
</a>
</li>
...
<li className="mr-3">
<Link to="/faq">
<div className="inline-block px-4 py-2 rounded cursor-pointer">
FAQ
</div>
</Link>
</li>
...
</ul>
</nav>
);
此设计的一个重要警告是,如果 CreateReactApp 具有全局 css 导入,它将无法工作,因为 Next.js 需要在 _app.js
文件中导入所有全局样式. From their documentation:
Due to the global nature of stylesheets, and to avoid conflicts, you may only import them inside pages/_app.js.
我想你可以通过在不同的主机上提供 Next.js 和 React SPA 并在两者之间进行代理来解决这个问题(注意:这需要在 catch-all 路由中自定义外部路由),但是它可能比它的价值更麻烦。更简单的解决方案可能只是将全局 CSS 重构为 CSS modules.
我正在尝试寻找任何示例来概述如何采用现有的 React 应用程序并逐渐开始向 Next.js 迁移。我已经阅读了所有关于增量采用策略(例如子路径、重写、微前端、代理)的 Next.js 文档,但还没有找到一个可靠的例子来展示这在现实生活中的实际情况“我已经有了一个庞大的 React 代码库”场景。
期望的结果是关闭我现有应用程序的子路径,比如 /workshop
,并让 /workshop
成为 Next.js 应用程序的入口点。然后我希望能够在这两个应用程序之间无缝导航,尽管一旦您进入 Next.js 领域并需要导航回代理之外,这种机制似乎很模糊。
为了增加上下文,React 和 Next.js 应用程序都将在 Netlify 上提供服务。我已经仔细阅读了他们的文档以及 Vercel 的文档,寻找一个有效的示例,但我仍然不走运。非常感谢任何关于如何最好地解决此类问题的知识或指导!
对于那些感兴趣的人,我能够创建一个工作演示。
https://hybrid-next-react.vercel.app/
https://github.com/coloradocolby/hybrid-next-react
它的工作方式相当简单。这是一个基本的 Next.js 应用程序,具有 [...app].js
的捕获所有路由,它服务于 React SPA 的入口点。一个简单的 isMounted
变量(可以很容易地重构为一个钩子)确保服务器永远不会处理 React SPA(可能具有特定于浏览器的代码)。
import { useEffect, useState } from "react";
import CreateReactAppRoot from "../src/App";
const App = () => {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
// Don't render client-side app unless window is available.
// NOTE: Page not statically pre-rendered nor server-side renderable
return isMounted ? <CreateReactAppRoot /> : null;
};
export default App;
最后一步是确保实现从 React SPA 到任何用于 Next.js 的路由的整页重新加载。这确保了 Next.js 路由机制被触发。在上面的演示中,我创建了 Next.js 和 React 特定的导航栏。
import React from "react";
import Link from "next/link";
import { useRouter } from "next/router";
export const NextNavbar = () => {
const router = useRouter();
return (
<nav>
{!router.pathname.includes("[...app]") && (
<ul className="flex p-4">
<li className="mr-3">
<Link href="/" passHref>
<div className="inline-block px-4 py-2 rounded cursor-pointer">
Home
</div>
</Link>
</li>
...
</ul>
)}
</nav>
);
};
再一次,虽然 Next.js 可以智能地 link 到 React SPA,因为我们的 catch all 路由,React SPA 需要整页重新加载到任何用于 Next.js 的路由.如您所料,如果目标路由要保留在 React SPA 内,则没有必要。
import React from "react";
import { Link } from "react-router-dom";
export const ReactNavbar = () => (
<nav>
<ul className="flex p-4">
<li className="mr-3">
<a href="/">
<div className="inline-block px-4 py-2 rounded cursor-pointer">
Home
</div>
</a>
</li>
...
<li className="mr-3">
<Link to="/faq">
<div className="inline-block px-4 py-2 rounded cursor-pointer">
FAQ
</div>
</Link>
</li>
...
</ul>
</nav>
);
此设计的一个重要警告是,如果 CreateReactApp 具有全局 css 导入,它将无法工作,因为 Next.js 需要在 _app.js
文件中导入所有全局样式. From their documentation:
Due to the global nature of stylesheets, and to avoid conflicts, you may only import them inside pages/_app.js.
我想你可以通过在不同的主机上提供 Next.js 和 React SPA 并在两者之间进行代理来解决这个问题(注意:这需要在 catch-all 路由中自定义外部路由),但是它可能比它的价值更麻烦。更简单的解决方案可能只是将全局 CSS 重构为 CSS modules.