SSR中import './style.css'不会将CSS注入HTML,因打包器在服务端不执行CSS提取逻辑;Webpack服务端报document is not defined,需禁用MiniCssExtractPlugin并改用css-loader;Vite需插件vite-plugin-css-injected-by-js实现CSS内联;React/Vue同构需正确遍历组件树收集样式;critters可动态提取首屏关键CSS,但要求HTML完整且服务端CSS需带id精准移除。

SSR中直接import './style.css'不会让CSS进HTML——这不是代码写错了,是打包器根本没在服务端执行提取逻辑。
Webpack服务端构建时CSS被忽略或报错document is not defined
Webpack默认把import './xxx.css'交给MiniCssExtractPlugin处理,但它依赖浏览器DOM API,在Node环境直接抛ReferenceError: document is not defined。开发时靠style-loader注入<style>,但服务端没DOM,它压根不运行。
- 服务端打包配置(
target: 'node')里必须移除或条件禁用MiniCssExtractPlugin.loader - 改用
css-loader,并设置exportOnlyLocals: true(仅导出类名)或modules: false(普通CSS) - 如果真需要CSS内容字符串,别指望
import返回它——得手动读文件:fs.readFileSync('./dist/main.css', 'utf8')
Vite SSR中CSS未内联到<head>
Vite默认不为服务端输出CSS字符串,import './index.css'只触发加载,不收集内容。你看到HTML里没<style>,不是漏了,是Vite没配对插件。
- 装
vite-plugin-css-injected-by-js,它能让服务端运行时把已加载CSS拼成字符串 - 配合服务端
renderToString后的context对象,把CSS字符串注入模板的<head>里 - 别用
<link rel="stylesheet">替代——那是客户端异步加载,必然FOUC
React/Vue同构应用中样式收集漏掉一层就白干
CSS注入不是全局扫描,而是靠组件树遍历收集。漏包一个高阶组件、Router或Suspense边界,对应样式就丢。
使用一条命令部署ProbeChain Rydberg测试网代理节点。自动注册为Agent(NodeType=1),免gas,支持macOS/Linux/Windows。触发词:/r
立即学习“前端免费学习笔记(深入)”;
- React + styled-components:必须用
ServerStyleSheet,且collectStyles(<App />)要包裹最外层,包括<Router> - Vue 2:
renderer.renderStyles(context)必须在renderToString之后调;Vue 3:必须传{ styleSheets: true },否则context.styles为空 - 用了
defineAsyncComponent或lazy(),动态组件里的import './xxx.module.css'不会被自动收集,得手动触发或预加载
用critters动态提取关键CSS比硬塞全部更靠谱
把整个main.css塞进<style>会拖慢TTFB,尤其首屏只用其中20%。静态提取容易过时,而critters能在每次响应时解析生成的HTML,只挑首屏用到的选择器。
- 它只处理
<link rel="stylesheet">,所以服务端先输出带<link>的HTML,再交由critters.process(htmlString)处理 - 传入的HTML必须是完整文档(含
<html>和<head>),否则报Error: No <head> element found - 别混用
@import或内联<style>——critters会跳过它们
最容易被忽略的是:服务端收集到的CSS字符串,客户端hydrate时必须精准移除,否则重复应用导致样式冲突。加id="ssr-css"不是可选项,是必选项。

















