You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Remix+Turborepo时Cloudflare Pages本地开发返回404

问题

将Remix + Cloudflare单应用迁移到Turborepo管理的Remix monorepo架构后,Wrangler无法识别构建后的Remix应用,所有路由均返回404错误。该配置在单仓库环境下可正常运行。

已做排查步骤

  • 反复检查package.json配置
  • 将构建路径从相对路径改为绝对路径
  • 检查tsconfig.json配置
  • 检查vite.config.json配置
  • 把monorepo构建文件夹内容复制到单应用构建文件夹,反之亦然,两者在单应用环境下均可运行,但monorepo环境下不行
  • 删除app文件夹下的node_modules

异常现象

Remix和Vite构建完成后不会生成index.html文件,手动创建空的index.html后,Wrangler能识别并返回该文件。

相关配置文件

apps/alertdown/package.json

{"name": "@alertdown/app","private": true,"sideEffects": false,"type": "module","scripts": {"build": "remix vite:build","dev": "remix vite:dev","lint": "eslint --ignore-path .gitignore --cache --cache-location ./node_modules/.cache/eslint .","start": "dotenv wrangler pages dev ./build/client","tsc": "tsc --noEmit","extract": "lingui extract --clean","compile": "lingui compile","w:deploy": "npm run build && wrangler pages deploy ./build/client --project-name=alertdown","w:deploy:prod": "npm run build && wrangler pages deploy ./build/client --project-name=alertdown --branch=production","preview": "npm run build && wrangler pages dev ./build/client","build-cf-types": "wrangler types","icons": "npx @svgr/cli --ext=jsx  --out-dir  app/assets/generated/icons -- app/assets/icons","icons:watch": "npm-watch icons","stripe:webhook": "stripe listen --forward-to http://localhost:5173/api/webhooks/stripe","analyze": "vite-bundle-visualizer"},"dependencies": {"@alertdown/auth": "workspace:*","@alertdown/configs": "workspace:*","@alertdown/core": "workspace:*","@alertdown/db": "workspace:*","@alertdown/email": "workspace:*","@alertdown/storage": "workspace:*","@alertdown/stripe": "workspace:*","@remix-run/node": "^2.11.1","@remix-run/react": "^2.11.1","@remix-run/serve": "^2.11.1","isbot": "^5.1.14","react": "^18.3.1","react-dom": "^18.3.1","vite-plugin-commonjs": "^0.10.1","vite-tsconfig-paths": "^5.0.1"},"devDependencies": {"@remix-run/dev": "^2.11.1","@types/react": "^18.3.3","@types/react-dom": "^18.3.0","@vitejs/plugin-react": "^4.3.1","@vitest/coverage-v8": "^2.0.5","@vitest/ui": "^2.0.5","eslint": "^9.9.0","fluid-tailwind": "^1.0.3","prettier": "^3.3.3","typescript": "~5.5.4","vite": "^5.4.0","vite-plugin-babel-macros": "^1.0.6","vite-plugin-dts": "~4.0.2","vitest": "^2.0.5","wrangler": "^3.71.0"},"engines": {"node": "20"}}

turbo.json

{"$schema": "https://turbo.build/schema.json","tasks": {"build": {"dependsOn": ["^build"],"outputs": ["dist/**"]},"dev": {"cache": false},"preview": {}}}

wrangler.toml

name = "alertdown"
compatibility_date = "2024-04-05"
compatibility_flags = ["nodejs_compat"]

Vite 配置

import {
  vitePlugin as remix,
  cloudflareDevProxyVitePlugin as remixCloudflareDevProxy,
} from '@remix-run/dev'
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'
import { lingui } from '@lingui/vite-plugin'
import macrosPlugin from 'vite-plugin-babel-macros'
import tailwindcss from 'tailwindcss'
import { getLoadContext } from './load-context'

export default defineConfig({
  plugins: [
    remixCloudflareDevProxy({
      getLoadContext,
    }),
    remix(),
    tsconfigPaths(),
    lingui(),
    macrosPlugin(),
  ],
  css: {
    postcss: {
      plugins: [tailwindcss()],
    },
  },
})

tsconfig.json

{"$schema": "https://json.schemastore.org/tsconfig","include": ["**/*.ts","**/*.tsx","**/.server/**/*.ts","**/.server/**/*.tsx","**/.client/**/*.ts","**/.client/**/*.tsx"],"compilerOptions": {"lib": ["DOM", "DOM.Iterable", "ES2022"],"isolatedModules": true,"esModuleInterop": true,"jsx": "react-jsx","module": "ESNext","moduleResolution": "Bundler","resolveJsonModule": true,"target": "ES2022","strict": true,"allowJs": true,"forceConsistentCasingInFileNames": true,"baseUrl": ".","experimentalDecorators": true,"emitDecoratorMetadata": true,"noEmit": true,"types": ["@remix-run/cloudflare", "vite/client"],"skipLibCheck": true}}
解决思路
  1. 修正Turbo构建输出配置
    当前turbo.json中build任务的outputs只包含dist/**,但Remix Vite构建会生成build/目录(包含client和server文件夹),需要把build/**也加入outputs:

    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**", "build/**"]
    }
    

    确保Turbo正确缓存和传递Remix的构建产物,避免monorepo中构建产物不完整。

  2. 指定Wrangler的入口函数路径
    在wrangler.toml中明确指定Remix的server入口,解决monorepo环境下Wrangler无法自动识别的问题:

    [[pages_functions]]
    entry = "./build/server/entry.server.js"
    

    确保路径是相对于app目录的正确位置,对应Remix构建后的server入口文件。

  3. 明确Remix Vite构建的输出目录
    在vite.config.ts中添加Remix的build配置,强制指定输出目录,避免monorepo路径解析异常:

    remix({
      buildDirectory: "./build",
      serverBuildPath: "./build/server/entry.server.js",
      clientBuildDirectory: "./build/client",
    })
    

    保证Remix在指定位置生成完整的server端代码和client资源。

  4. 验证monorepo依赖安装正确性
    在monorepo根目录执行依赖安装命令,而非仅在app目录安装。通过npm list @alertdown/core验证workspace依赖是否正确链接到本地包。

  5. 固定Wrangler运行的工作目录
    执行Wrangler命令时,确保在app目录下运行,或在命令中添加--cwd apps/alertdown参数,避免Wrangler在根目录找不到正确的构建产物和配置:

    npm run preview -- --cwd apps/alertdown
    
  6. 检查Remix构建产物完整性
    确认build/server目录下存在entry.server.js及相关server bundle文件。如果缺失,排查Turbo是否触发了Remix的完整构建流程,或是否有依赖构建失败导致Remix构建中断。


内容的提问来源于stack exchange,提问作者Jose A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:05:56