浏览器云端写代码,远程开发 Next.js 应用的简易教程

浏览器云端写代码,远程开发 Next.js 应用的简易教程

本文简单记录我通过 code-server 在浏览器云端中运行 Next.js 15 项目的流程。

1. 准备工作

确保服务器已经安装并登录 1Panel。

借助 1Panel 的可视化面板,我们可以非常轻松地以 Docker 容器方式部署 code-server。


2. 新建 code-server 应用

2.1 记住以下信息

  • 默认端口号40031
  • 网页访问密码password
  • sudo密码password

2.2 访问 & 登录

  • 控制台开启 SSL 反向代理以确保 HTTPS 访问。

后端代理地址 http://127.0.0.1:40031 并通过域名访问,例如code.yourdomain.com。 至此,code-server 就通过 1Panel + Docker 成功跑起来了。


3. 环境准备命令

如果你的远程环境还没有 Node.js / npm / pnpm,可以先执行以下命令完成安装与升级:

bash 复制代码
# 切换到 root
su
# 修改 root 密码
sudo passwd root
bash 复制代码
apt-get update
apt-get install -y nodejs npm

node -v   # 确认 Node.js 版本

npm install -g pnpm
pnpm -v   # 确认 pnpm 已全局安装

安装完成后,就可以继续按照后文步骤在 code-server 中创建并运行 Next.js 项目了。

4. 使用create-next-app自动安装

你可以使用 create-next-app 脚手架工具来快速创建一个新的Next.js项目。这个工具会自动为你设置好一切。

示例:

npx create-next-app@latest my-next-app

在安装过程中,你会看到一些提示,按照提示选择相应的选项即可。

cd my-next-app && pnpm dev

默认启动端口为 3000


5. 修改 basePath 与静态资源前缀

按照官方文档,访问 https://<域名>/absproxy/<端口>,例如code.yourdomain.com/absproxy/3000

5.1. 按照以下规则调整代码

  1. 在 Next.js 层面设置 basePath :强制 Next.js 生成的所有路由都带上 /absproxy/3000
  2. 导出公共环境变量 NEXT_PUBLIC_BASE_PATH:在页面组件里拼接任何静态资源路径。
  3. 代码中统一使用 prefix :不论是 next/image 还是 <a href>,一律走 ${prefix}/xxx

5.2. .env.localnext.config.ts

首先在项目根目录创建 .env.local

bash 复制代码
NEXT_PUBLIC_BASE_PATH=/absproxy/3000

然后在 next.config.ts 中启用 basePath 并把该值同步到客户端环境变量,确保编译阶段即可读到:

ts 复制代码
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  basePath: "/absproxy/3000",
};

export default nextConfig;

⚠️ 注意:basePath 必须在构建时确定,因此每次修改都需要重新 next build(开发模式下会自动热重启)。


5.3. 页面示例:统一前缀的组件写法

下面是一个改造后的 src/app/page.tsx 示例。核心是读取环境变量 NEXT_PUBLIC_BASE_PATH,在所有 Image 及链接地址前拼接 prefix

tsx 复制代码
import Image from "next/image";

const prefix = process.env.NEXT_PUBLIC_BASE_PATH ?? "";

export default function Home() {
  return (
    <div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
      <main className="flex flex-col gap-[32px] row-start-2 items-center sm:items-start">
        <Image
          className="dark:invert"
          src={`${prefix}/next.svg`}
          alt="Next.js logo"
          width={180}
          height={38}
          priority
        />
        <ol className="font-mono list-inside list-decimal text-sm/6 text-center sm:text-left">
          <li className="mb-2 tracking-[-.01em]">
            Get started by editing{" "}
            <code className="bg-black/[.05] dark:bg-white/[.06] font-mono font-semibold px-1 py-0.5 rounded">
              src/app/page.tsx
            </code>
            .
          </li>
          <li className="tracking-[-.01em]">
            Save and see your changes instantly.
          </li>
        </ol>

        <div className="flex gap-4 items-center flex-col sm:flex-row">
          <a
            className="rounded-full border border-solid border-transparent transition-colors flex items-center justify-center bg-foreground text-background gap-2 hover:bg-[#383838] dark:hover:bg-[#ccc] font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 sm:w-auto"
            href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
          >
            <Image
              className="dark:invert"
              src={`${prefix}/vercel.svg`}
              alt="Vercel logomark"
              width={20}
              height={20}
            />
            Deploy now
          </a>
          <a
            className="rounded-full border border-solid border-black/[.08] dark:border-white/[.145] transition-colors flex items-center justify-center hover:bg-[#f2f2f2] dark:hover:bg-[#1a1a1a] hover:border-transparent font-medium text-sm sm:text-base h-10 sm:h-12 px-4 sm:px-5 w-full sm:w-auto md:w-[158px]"
            href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
            target="_blank"
            rel="noopener noreferrer"
          >
            Read our docs
          </a>
        </div>
      </main>
      <footer className="row-start-3 flex gap-[24px] flex-wrap items-center justify-center">
        <a
          className="flex items-center gap-2 hover:underline hover:underline-offset-4"
          href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          <Image
            aria-hidden
            src={`${prefix}/file.svg`}
            alt="File icon"
            width={16}
            height={16}
          />
          Learn
        </a>
        <a
          className="flex items-center gap-2 hover:underline hover:underline-offset-4"
          href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          <Image
            aria-hidden
            src={`${prefix}/window.svg`}
            alt="Window icon"
            width={16}
            height={16}
          />
          Examples
        </a>
        <a
          className="flex items-center gap-2 hover:underline hover:underline-offset-4"
          href="https://nextjs.org?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          <Image
            aria-hidden
            src={`${prefix}/globe.svg`}
            alt="Globe icon"
            width={16}
            height={16}
          />
          Go to nextjs.org →
        </a>
      </footer>
    </div>
  );
}

要点

  • process.env.NEXT_PUBLIC_BASE_PATH 在客户端可直接访问。
  • next/image、自定义 <img><link>fetch 等只要写绝对路径都记得加 prefix
  • 如果你有很多地方需要拼接,可以封装一个 util:
ts 复制代码
export const withBasePath = (path: string) =>
  `${process.env.NEXT_PUBLIC_BASE_PATH ?? ""}${path}`;

5.4. 常见坑点排查

问题 解决办法
仍然返回 404 检查 .env.local 是否被 Next.js 读取 (需重启 dev server)。
静态资源 MIME 错误 多半是访问到了根路径的 Cloudflare/反向代理,确认所有 URL 都用 prefix
SockJS / HMR 无法连接 记得设定 WDS_SOCKET_PATH=${PREFIX}/sockjs-node(参见 code-server 文档)。
生产环境刷新返回 404 部署时确保 basePath 与实际访问路径一致,例如 Nginx/Caddy 上也要匹配 /absproxy/3000.

6. 总结

  1. code-server 的 /absproxy 模式不会裁剪请求路径,因此 Next.js 必须显式知道自己挂在 /absproxy/3000
  2. basePath 解决路由与 next/link 问题,但 静态资源必须手动带前缀
  3. 借助 NEXT_PUBLIC_BASE_PATH 就能让组件层保持统一写法。
  4. 修改以上配置后,Next.js 开发体验与本地一致,再也不会看到 404/MIME 报错。

7. 参考链接

相关推荐
PaytonD3 小时前
LoopBack 2 如何设置静态资源缓存时间
前端·javascript·node.js
snow@li3 小时前
d3.js:学习积累
开发语言·前端·javascript
vincention3 小时前
JavaScript 中 this 指向完全指南
前端
qyresearch_4 小时前
射频前端MMIC:5G时代的技术引擎与市场机遇
前端·5g
天蓝色的鱼鱼4 小时前
Next.js 渲染模式全解析:如何正确选择客户端与服务端渲染
前端·react.js·next.js
一枚前端小能手4 小时前
🚀 巨型列表渲染卡顿?这几个优化技巧让你的页面丝滑如德芙
前端·javascript
酷柚易汛智推官4 小时前
Electron技术深度解析:跨平台桌面开发的利器与挑战
前端·javascript·electron
llz_1124 小时前
第五周作业(JavaScript)
开发语言·前端·javascript
yannick_liu4 小时前
nuxt4 + nuxt-swiper实现官网全屏播放
前端