为什么用 mini-css-extract-plugin 提取的 CSS 在 Vue 组件里不生效?
我用 Webpack 的 mini-css-extract-plugin 把 CSS 单独抽出来了,但发现 Vue 组件里的样式根本没加载,页面一片空白。明明 build 出来的 CSS 文件有内容,也正确引入了,就是不生效。
我试过把 extract 改成 false 用 style-loader,样式就正常了,一开启提取就不行。是不是哪里配置错了?
<template>
<div class="box">测试文字</div>
</template>
<style scoped>
.box {
color: red;
font-size: 20px;
}
</style>
问题根源
mini-css-extract-plugin 的 loader 必须放在 css-loader 之后,因为它只负责把 CSS 抽离成单独文件,但不会处理 CSS 本身。而 Vue 组件的 scoped CSS 需要先经过 css-loader 处理(注入唯一属性选择器),然后才能被正确提取。
如果你把 MiniCssExtractPlugin.loader 放在 css-loader 前面,CSS 根本没经过处理就被抽走了,scoped 的属性选择器都没加进去,样式当然不生效。
解决方案
检查你的 webpack 配置里的 CSS rule,正确的顺序应该是这样:
额外注意
如果你的项目用了 PostCSS(比如 Autoprefixer),还需要把 postcss-loader 加到 css-loader 后面:
另外确认一下 vue-loader 的版本。vue-loader v15+ 需要在配置里加个
css: true或者单独处理 CSS:总结一下:先检查 loader 顺序是不是 css-loader 在前、提取 loader 在后,再检查 vue-loader 的 CSS 配置。基本就是这两个地方出问题。
Vue 项目用 mini-css-extract-plugin 必须在 vue-loader 配置里加
extractCSS: true,否则默认把所有 CSS 塞进 JS 里,外部的 CSS 文件虽然生成了但内容是空的。在 vue-loader 配置里加上这个选项就行:
如果是 vue-loader 15+,可能还需要确保 css-loader 那边也配置了。