手册

静态站上线前该检查什么

静态产物背后没有服务器,这些文件里错了什么,对每一个访客就都是错的。下面这些 React2Static 会拿你自己的产物全跑一遍。这里是完整清单,每条都附修法。

下面示例里的包名、路径和数值都只是举例,工作台填进去的是你自己项目里的那个。

.env 文件被发布出去了

你看到的是

dist/
  .env
  index.html
  assets/index-a3f1c2.js

整个文件任何访客都能直接下载。先把里面的每一个值都轮换掉,再把 .env 移出构建会原样拷贝的那个目录(通常是 public/)。

代码里读了 process.env.API_KEY,但没有人给它赋值

你看到的是

const apiKey = process.env.API_KEY;

fetch(url, { headers: { Authorization: `Bearer ${apiKey}` } });
// Vite turns process.env into {} — the header goes out as
// "Bearer undefined" and the API answers 401. No error in the console.

Vite 会把 process.env 整个替换成空对象,所以这个值在浏览器里就是 undefined——不报错,也没有任何提示,请求照发,只是没带上这个值,然后接口回你一个 401。改成用 import.meta.env.VITE_xxx 读,或者在 vite.config 里 define 它。

改成

const apiKey = import.meta.env.VITE_API_KEY;

产物里还留着 process.env.API_KEY

你看到的是

Uncaught ReferenceError: process is not defined
    at index-a3f1c2.js:1:2043

浏览器里没有 process 这个对象,代码跑到这行就会报错,通常表现为整页白屏。在 Vite 里,浏览器要用的值必须通过 import.meta.env 读,而且变量名要以 VITE_ 开头。

改成

const apiKey = import.meta.env.VITE_API_KEY;

产物里的地址指向你自己的电脑

你看到的是

const API = "http://localhost:3000/api";

里面有 http://localhost:3000/api。这个地址只在构建这台机器上存在,所有访客的这个请求都会失败。改成一个公网地址。

改成

const API = "https://api.example.com";

产物里没有 index.html

你看到的是

dist/
  assets/index-a3f1c2.js
  assets/index-9b2e01.css

静态托管把 index.html 当入口页。没有它,访客看到的是文件列表或者 404。确认一下你的构建到底输出了什么。

标题还是模板自带的默认值

你看到的是

<title>Vite + React + TS</title>

现在是"Vite + React + TS"。搜索结果和别人分享出去的链接显示的就是这行字。到 index.html 里改掉。

改成

<title>Your product name — what it does, in one line</title>

页面没有标题

浏览器标签页和所有搜索结果用的都是 <title> 标签。在 index.html 里补一个。

改成

<title>Your product name — what it does, in one line</title>

没有 meta description

搜索引擎只能自己从页面里抓一段来凑。<meta name="description"> 里那一句话,直接决定别人点不点进来。

改成

<meta name="description" content="One clear sentence about what this page is for." />

没有 viewport 标签

手机会按桌面宽度渲染再缩小,结果就是所有字都小得看不清。在 index.html 里加上 <meta name="viewport" content="width=device-width, initial-scale=1">。

改成

<meta name="viewport" content="width=device-width, initial-scale=1" />

没有 Open Graph 标签

分享到聊天软件或社交平台时,只会显示一条光秃秃的网址,没有标题也没有配图。补上 og:title、og:description 和 og:image。

改成

<meta property="og:title" content="Your product name" />
<meta property="og:description" content="One clear sentence." />
<meta property="og:image" content="https://example.com/og.png" />

没有自己的站点图标

你看到的是

<link rel="icon" type="image/svg+xml" href="/vite.svg" />

浏览器标签页和收藏夹里显示的是一张白纸,或者你从模板里继承下来的那个图标。放一个自己的 favicon,并在 index.html 里引用。

改成

<link rel="icon" href="/favicon.ico" sizes="any" />

<html> 标签上没有 lang 属性

读屏软件靠它决定怎么念,浏览器靠它决定要不要提示翻译。加上 lang="zh",或者页面实际用的语言。

改成

<html lang="en">

没有 robots.txt

没有它爬虫照样会收录,但 robots.txt 是你告诉它们 sitemap 在哪的地方。可以在"上线"那一步让我们补上。

改成

User-agent: *
Allow: /

Sitemap: https://example.com/sitemap.xml

有一个脚本 2.4 MB

你看到的是

dist/assets/index-a3f1c2.js   2,418.55 kB │ gzip: 731.20 kB

(!) Some chunks are larger than 500 kB after minification.

手机网络下这就是好几秒的白屏。用动态 import() 把重的部分拆出去,首屏通常能降下来一大截。

改成

const Editor = lazy(() => import('./Editor'));

有一个静态资源 4.0 MB

你看到的是

dist/assets/hero-8f2a1b.png   4,102.11 kB

大图和大字体会拖住首屏渲染。把图片转成 WebP、按实际显示尺寸缩小,通常能去掉大部分体积。

让它替你找

把 ZIP 拖进工作台。构建会在你自己的浏览器里真跑一遍,出问题时它指出关键的那一行,而不是把整篇日志甩给你。

打开构建台

相关

构建报错怎么修AI 生成的 React 项目最常见的 13 种构建失败:npm、Vite、tsc 打出来的原始报错,各自是什么意思,怎么改。