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></style>,但服务端没DOM,它压根不运行。
- 服务端打包配置(
target: 'node')里必须移除或条件禁用MiniCssExtractPlugin.loader - 改用
css-loader,并设置exportOnlyLocals: true(仅导出类名)或modules: false(普通CSS) - 如果真需要CSS内容字符串,别指望
import返回它——得手动读文件:fs.readFileSync('./dist/main.css', 'utf8')
Vite SSR中CSS未内联到
Vite默认不为服务端输出CSS字符串,import './index.css'只触发加载,不收集内容。你看到HTML里没<style></style>,不是漏了,是Vite没配对插件。
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 装
vite-plugin-css-injected-by-js,它能让服务端运行时把已加载CSS拼成字符串 - 配合服务端
renderToString后的context对象,把CSS字符串注入模板的里 - 别用
<link rel="stylesheet">替代——那是客户端异步加载,必然FOUC
React/Vue同构应用中样式收集漏掉一层就白干
CSS注入不是全局扫描,而是靠组件树遍历收集。漏包一个高阶组件、Router或Suspense边界,对应样式就丢。
- React + styled-components:必须用
ServerStyleSheet,且collectStyles(<app></app>)要包裹最外层,包括<router></router> - Vue 2:
renderer.renderStyles(context)必须在renderToString之后调;Vue 3:必须传{ styleSheets: true },否则context.styles为空 - 用了
defineAsyncComponent或lazy(),动态组件里的import './xxx.module.css'不会被自动收集,得手动触发或预加载
用critters动态提取关键CSS比硬塞全部更靠谱
把整个main.css塞进<style></style>会拖慢TTFB,尤其首屏只用其中20%。静态提取容易过时,而critters能在每次响应时解析生成的HTML,只挑首屏用到的选择器。
- 它只处理
<link rel="stylesheet">,所以服务端先输出带<link>的HTML,再交由critters.process(htmlString)处理 - 传入的HTML必须是完整文档(含
和),否则报Error: No element found - 别混用
@import或内联<style></style>——critters会跳过它们
最容易被忽略的是:服务端收集到的CSS字符串,客户端hydrate时必须精准移除,否则重复应用导致样式冲突。加id="ssr-css"不是可选项,是必选项。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










