?raw仅将css文件作为纯文本读取,不触发任何css处理流程,但需确保该文件在项目中仅以?raw形式被导入,否则仍会被正常打包。

直接 import './style.css?raw' 就能拿到纯字符串,但别指望它“不处理”
很多人以为加 ?raw 是为了绕过 Vite 的 CSS 构建流程,结果发现构建产物里还是多了一堆 CSS 文件——其实 ?raw 做的事非常干净:它只让 Vite 把文件当文本读,不走任何 CSS 插件链(比如 postcss、minify、注入 <style></style> 标签等)。但它本身不阻止其他地方的 import,比如你同时写了 import './style.css' 和 import css from './style.css?raw',前者依然会触发完整 CSS 处理。
-
?raw必须作用于一个**真实存在的、可被 Vite 解析的路径**,比如./reset.css;./index.scss?raw会报错,Vite 不支持预处理器文件走?raw - 导出的是字符串,不是模块对象:
console.log(css)输出的是原始 CSS 内容,不含default属性或__esModule - 如果你用的是 pnpm 或 yarn pnp,确保
node_modules下的 CSS 文件也能被?raw正确定位(有时需配resolve.alias)
为什么 import './xxx.css?raw' 后样式没生效,也没报错?
因为 ?raw 真的只是读文本——它不会创建 <style></style> 标签,也不会调用任何 inject 逻辑。你拿到字符串后,得自己决定怎么用:
- 手动插入:
document.head.appendChild(Object.assign(document.createElement('style'), { textContent: css })) - 传给 runtime CSS 库(如
stylis+@emotion/css) - 作为模板字符串拼进 JSX/HTML 字符串中(SSR 场景下注意 escape)
- 千万别写成
import './style.css?raw'(无变量接收),这行代码完全没副作用,连字符串都不会存
?raw 和 ?inline 别混用,它们根本不是一回事
?inline 看起来像“内联”,但实际行为和 ?raw 完全不同:它仍走 CSS 插件链,只是把导出值从空对象改成字符串。所以即使你写了 import css from './style.css?inline',样式照样被注入到 ,且构建时仍参与压缩、提取、code splitting。
-
?raw→ 绕过所有 CSS 处理,只读文本,零副作用 -
?inline→ 仍走完整 CSS 流程,仅改变模块导出内容 -
?raw&inline或?inline?raw这类组合无效,Vite 只认第一个查询参数,?raw优先级更高 - 想禁用自动注入,只用
?raw;想在 JS 里操作 CSS 字符串又保留构建优化,用?inline+ 配合css.devSourcemap: true查看原始内容
构建时 CSS 还是被打包了?检查有没有隐式 import
如果发现最终 dist 目录里仍有 style.css,而你只用了 ?raw,大概率是项目里其他地方存在未加查询参数的 import,比如:
- 某个组件
.vue文件里写了<style src="./base.css"></style> -
vite.config.ts中配置了css.preprocessorOptions.sass.additionalData,里面@import了该文件 - 第三方库(如
naive-ui)内部import了同名 CSS,而你没配optimizeDeps.exclude
真正干净的“只读不用”方案,必须保证这个 CSS 文件在整个依赖图里**只以 ?raw 形式出现一次,且无其他路径指向它**。否则 Vite 的静态分析会把它当作普通资源照常打包。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











