deleted
このWebサイト、『記事もコメントも自動で翻訳される多言語コミュニティEvame』のメタフレームワークをRemixからNext.jsに移行し、インフラもRenderからVercelへ移行しました。
这个网站『支持自动翻译文章和评论的多语言社区Evame』的元框架已从Remix迁移到Next.js,基础设施也从Render迁移到Vercel。
2週間ほどかけての大掛かりな移行でしたが、結果には満足していて、「小〜中規模なサイトならRemix / React Router、大規模なサイトならNext.jsを選ぶ価値が大いにある」という結論に至りました。
迁移过程耗时两周左右,规模较大,但结果令人满意。最终结论是:对于小型到中型网站,选择Remix/React Router是值得的;而对于大型网站,选择Next.js则更有价值。
この記事では、RemixからNext.jsへの移行についてや、RemixとNext.jsの個人的な比較について書きます。どっちを使うか悩んでいる人や、移行を考えている人はぜひ読んでください!
本文将记录从Remix迁移到Next.js的过程,以及我对Remix和Next.js的个人比较。如果您正在纠结选择哪个框架,或者正在考虑迁移,请务必阅读!
サイト方針の変更と規模の拡大
网站发展方向的改变和规模的扩大
当初Evameは、青空文庫やプロジェクト・グーテンベルク、過去の仏典と言ったpubllic domainのテキストに対訳を付与したくて始めました。しかし開発を進めるうちに、public domainのテキストだけではなくユーザが投稿した記事にも対訳を付与できるようにしたいと考えるようになりました。そもそもEvameを作り始めた目的は知識と物語の循環であり、そのためにはユーザーが記事を投稿できるシステムが必要不可欠だと考えたからです。この方針の変更によってサイトの規模が拡大し、必要な機能が増え、大きなエコシステムを持つNext.jsに惹かれるようになりました。
最初,创建Evame是为了为青空文庫、Project Gutenberg和古代佛经等公共领域的文本添加对译。但在开发过程中,我们希望能够为用户投稿的文章也添加对译。Evame的初衷是知识和故事的循环,为此,用户可以投稿的文章系统必不可少。这一方向的改变导致网站规模扩大,所需功能增多,我们开始被拥有庞大生态系统的Next.js所吸引。
Remixの今後の不明瞭さ
Remix未来发展的不确定性
2024/11/22、Remix v2はReact Router v7とマージされました。https://remix.run/blog/react-router-v7
2024年11月22日,Remix v2与React Router v7合并。https://remix.run/blog/react-router-v7
Remixは消え、React Routerとして続いていくのかと思っていましたが、上記ブログの著者でもあるCo-FounderがTwitterで、次はRemix v3になるという発言をしています。
我原本以为Remix会消失,以React Router的形式继续存在,但上述博客的作者,也是Remix的联合创始人,在Twitter上表示接下来是Remix v3。
名前の変更はエコシステム全体に変化を余儀なくさせる大きなものです。実際、別のプロジェクトでRemix v2からReact Router v7へアップデートしたのですが、Remix関連の各種ライブラリが使えなくなり、多くの対応が必要で結構な工数がかかりました。再度名前の変更で同様の対応を迫られる可能性もあり、そうすると今回アップデートしてもまた使えなくなるライブラリが多く出るかも、といった不安がありました。
更名会迫使整个生态系统发生巨大的变化。事实上,在另一个项目中,我们将Remix v2更新到React Router v7后,许多与Remix相关的库都无法使用,需要大量工作才能解决,耗费了相当大的精力。如果再次更名,我们可能面临同样的问题,许多库可能再次失效,这让我们感到担忧。
React と Next.js の緊密化
React与Next.js的紧密结合
https://nextjs.org/blog/next-12
https://nextjs.org/blog/next-12
ReactとNext.jsは、上記の記事にもあるようにどんどん連携を深めており、Next.jsは他のフレームワークよりも先行して多くの技術を使用しています。
正如上文所述,React和Next.js正日益紧密地结合在一起,Next.js比其他框架更早地使用了许多新技术。
RSCがNext.jsでリリースされたのは2023年でもう2年近く経っているのに、まだRSCを使えるフレームワークがほとんどないことがその証明です。
RSC在2023年发布,至今已近两年,但仍然很少有框架能够使用RSC,这足以证明Next.js的领先性。
今後も優先的に新機能を実装できるだろう点は大きなアドバンテージだと感じました。
未来能够优先使用新功能,这一点是一个巨大的优势。
React 19がフルに活用できる
能够充分利用React 19
Remix / React Router v7 だと、route modulesの loader / action でデータを扱うため、コンポーネントとデータ部分が分離しがちでした。
Next.js(App Router)ではRSC (React Server Components) や Server Actions 、useActionState等を活用することで、コンポーネントとデータの距離が縮まり、開発生産性が向上しました。また、コロケーションに基づいたディレクトリ構成がRemixより行いやすくなった点も開発生産性の向上に繋がりました。
在Remix/React Router v7中,数据处理在route modules的loader/action中进行,组件和数据部分往往分离。而在Next.js(App Router)中,通过使用RSC(React Server Components)、Server Actions和useActionState等,组件和数据的距离缩短,开发效率得到提升。此外,基于协同定位的目录结构也比Remix更容易实现,进一步提高了开发效率。
豊富なエコシステム
丰富的生态系统
Next.jsの場合、Sentry、Supabase、Stripe など多くのサービスの公式例があり、周辺ライブラリも充実しています。next/font や next/image も素晴らしく、これによってLight HouseのPerformanceが100点になり、Best Practicesも100点になりました。
Next.js拥有许多服务的官方示例,例如Sentry、Supabase、Stripe等,并且周边库也很丰富。next/font和next/image也非常出色,它们使Lighthouse的性能得分达到100分,最佳实践也达到100分。

移行前は以下の点数だったので、エコシステムの力を大いに感じています。(Accessibility頑張ります。)
迁移前,得分如下(可访问性方面还需要努力)。

AIフレンドリー
AI友好
ClaudeやGPTに、Remixで書いてと指示を出してもNext.jsのコードを吐いてくることがよくありました。ユーザが多い分、Next.jsの場合最初から使えるコードを出してくれる割合が増えたと感じます。これもAI時代の新たなエコシステムと呼べるかもしれません。
我经常向Claude或GPT提出用Remix编写代码的请求,但它们经常输出Next.js的代码。由于用户众多,Next.js从一开始就能提供可用代码的概率更高。这或许可以被称为AI时代的新型生态系统。
ビルドが遅い
构建速度慢
Remix は HMR が速く、ローカル開発が非常に快適でした。Next.js はファイルによってはビルドに数秒かかり、時にはリロード必須になるなど、開発体験としてはストレスがあります。
Remix的HMR速度很快,本地开发体验非常舒适。Next.js中,某些文件的构建需要几秒钟,有时甚至需要强制重新加载,开发体验上会有些压力。
メンタルモデルの複雑さ
更复杂的思维模型
Remixのメンタルモデルは、loader→component→actionというシンプルでわかりやすい流れでした。
Remix的思维模型是loader→component→action,流程简单明了。
Next.jsの場合、RSC/Server Actions/revalidatePath/revalidateTag/next/dynamic/Request Memoizationなど様々な概念が登場します。最適化されたことでLighthouseのスコアは上がりましたが、体感ではRemixの時と速度に差はありません。ユーザとしては体感速ければどうでもいいので、勝手に速くなるようにしてほしいという感想です。
Next.js中出现了RSC/Server Actions/revalidatePath/revalidateTag/next/dynamic/Request Memoization等多种概念。虽然优化后Lighthouse的得分提高了,但实际体验与Remix没有速度差异。作为用户,如果体验速度够快就可以了,我希望它能够自动变快。
黒魔術
黑魔法
Remixの吐くhtmlは非常にシンプルでした。書いたものがそのまま出力されているという感じで、把握しやすかったです。
Remix生成的HTML非常简洁,感觉写的代码就是直接输出的,易于理解。
Next.js はフレームワーク独自のロジックでclassNameやcanvasタグが差し込まれていたり、デバッグが複雑です。また、Edge Runtimeと絡んで、ローカルでは動くのに本番だと動かない問題にも遭遇しがちです。
Next.js使用框架特有的逻辑插入className和canvas标签等,调试比较复杂。而且,与Edge Runtime结合时,经常会出现本地运行正常,但生产环境运行失败的问题。
最初にブランチを切ってcreate next し、ライブラリの移行から始めました。具体的には以下のライブラリを移行する必要がありました。
首先创建分支并使用create next,从库迁移开始。具体来说,需要迁移以下库:
remix-auth → auth.js
remix-auth → auth.js
react-i18next → next-intl
react-i18next → next-intl
remix-auth → auth.jsの変更には、DBスキーマの対応とORMとして使っているPrismaのEdge Runtime対応が必要で、移行全体の中でもここが一番大変でした。
remix-auth → auth.js的更改需要更改数据库模式,并且需要使用Prisma作为ORM进行Edge Runtime的适配,这是整个迁移过程中最困难的部分。
DBスキーマはauth.js側に合わせたスキーマを用意し、既存データをマイグレーションし、カスタマイズを減らすことでアップデート時のリスクを抑えました。
数据库模式采用与auth.js一致的模式,迁移现有数据,并减少自定义以降低更新时的风险。
Edge Runtimeは、Prisma Accelerate はまだ事例が少なく、ローカルと本番の差異が大きそうで懸念があり、Drizzle への移行は自由度が高い一方で工数が大きいので、結果、Neon + Prisma を選択して最小限の工数に留めました。
对于Edge Runtime,Prisma Accelerate的案例还很少,本地和生产环境的差异似乎很大,让人担心;而迁移到Drizzle虽然自由度高,但工作量也很大。最终,我们选择Neon + Prisma,将工作量降到最低。
次に、既存の Remix のルーティングや loader / action 部分を、Next.js App Router での RSC / Server Actions に置き換えました。
ここではAIが非常に役に立ちました。と言ってもuseActionStateやServer ActionはまだAIには書けないので自力で頑張る必要があります。
接下来,将现有的Remix路由和loader/action部分替换为Next.js App Router中的RSC/Server Actions。这里AI帮了很大的忙。不过,useActionState和Server Action目前还无法用AI编写,需要人工完成。
Server Actions に共通ロジックを持たせない工夫
避免在Server Actions中包含公共逻辑
すべての Server Actions が外部公開されるため、認証コードをいちいち書く必要があります。できるだけ認証ロジックをまとめた関数や、Middleware で対応できないか検討しましょう。
所有Server Actions都是公开的,因此需要编写认证代码。我们需要考虑是否可以将认证逻辑整合到函数中,或者使用中间件来处理。
RSC コンポーネントのテスト
RSC组件的测试
RSC は 現状テスト手法が確立されていないので、ビジネスロジックや認証ロジックを分け、Unit テスト可能にするのがおすすめです。
目前RSC的测试方法尚未完全确立,建议将业务逻辑和认证逻辑分开,以便进行单元测试。
useActionState の型付け
useActionState的类型化
useActionStateの返り値に型情報を付与する仕組みはまだ確立されていません。自前で定義するのが現状ベターです。個人的には以下のようにしています。(about_hiroppyさんのtweetを参考にしています。)
目前还没有确立为useActionState返回值添加类型信息的机制。目前最好自己定义。我个人是这样做的(参考了about_hiroppy的推文)。
export type ActionResponse<T = void, U = Record<string, unknown>> = {
success: boolean;
message?: string;
data?: T;
zodErrors?: typeToFlattenedError<U>["fieldErrors"];
};form の型検証
表单的类型验证
Server Action 内でバリデーションするといいです。個人的にはzodで以下のようにしています。
最好在Server Action中进行验证。我个人使用zod,如下所示。
const editPageContentSchema = z.object({
slug: z.string().min(1),
title: z.string().min(1).max(100),
pageContent: z.string().min(1),
});
const parsedFormData = editPageContentSchema.safeParse({
slug: formData.get("slug"),
title: formData.get(
小〜中規模のアプリ
小型到中型应用
そこまで最新の React 機能を活用しなくても良ければ、Remix / React Router はシンプルで高速な開発体験を得やすい。メンタルモデルも明快。
如果不需要使用最新的React功能,Remix/React Router可以提供简单、快速的开发体验。思维模型也很清晰。
toBやSPAなら個人的にはRemix / React Router。
对于B端应用或单页应用,我个人推荐Remix/React Router。
中〜大規模 or エコシステムを活かしたい場合
中型到大型应用或希望利用生态系统
Next.jsを選べばサービス・ライブラリとの連携がしやすく、将来的な React のアップデートにも先行して対応できる。
选择Next.js可以更容易地与服务和库集成,并能够抢先体验React的未来更新。
toCやSSRをしたいならNext.js。
对于C端应用或服务器端渲染,我推荐Next.js。
個人的には「リリースして伸びてきたら Next.js に移行」というアプローチも十分アリだと思います。Remix/React Routerならcloudflareを使えばコストもかなり抑えられます。ただし、移行時はやはり工数も掛かるので、将来的な拡張を見据えている場合は最初から Next.js を使う選択肢も強いです。
我个人认为,“发布后增长后再迁移到Next.js”这种方法也很可行。如果使用Cloudflare,Remix/React Router的成本也可以大幅降低。但是,迁移时仍然需要投入大量工作,如果考虑到未来的扩展性,从一开始就使用Next.js也是一个不错的选择。
フレームワーク、DB、インフラの移行と大掛かりな変更だったのですが、重要な部分にテストコードを書いていたことや、DB周りのコードをCQRSで分離していたことで、認証周り以外は比較的スムーズでした。改めて、コードの品質やアーキテクチャに投資することが大事だと実感しています。
这次对框架、数据库和基础设施进行了大规模的更改,但由于我们为重要部分编写了测试代码,并且将数据库代码用CQRS分离,因此除了认证部分以外,迁移过程相对顺利。再次体会到,对代码质量和架构的投入非常重要。
このサイト「Evame」は、書いた記事やコメントをAIが自動翻訳してくれる多言語コミュニティです。僕もこの移行記を日本語で書き、英語圏にシェアできるようになりました。
这个网站“Evame”是一个多语言社区,可以自动使用AI翻译文章和评论。通过这次迁移,我可以用日语编写迁移记录,并分享给英语国家。
もし興味があれば、ぜひ好きな言語で記事を書いて、世界中に発信してみてください!
如果您感兴趣,请用您喜欢的语言撰写文章,并将其分享到全世界!
以上が、Remix / React Router v7 から Next.js へ移行した感想と比較、そして移行手順です。何か参考になる部分があれば嬉しいです!
以上就是我将Remix/React Router v7迁移到Next.js的心得、比较和迁移步骤。如果对您有所帮助,我将非常高兴!
I don't have any further plans to work on RR v7. I'm personally done with that project. Remix v3 is just something I've been calling it internally. Since we haven't released a v3 yet, it would make sense to publish the next version of Remix as v3.