ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vue CLI 中的 CSS 处理完全指南:预处理器、PostCSS 与 CSS Modules 配置实战

Vue CLI 中的 CSS 处理完全指南:预处理器、PostCSS 与 CSS Modules 配置实战 Vue CLI 中的 CSS 处理完全指南预处理器、PostCSS 与 CSS Modules 配置实战【免费下载链接】vue-cli️ webpack-based tooling for Vue.js Development项目地址: https://gitcode.com/gh_mirrors/vu/vue-cli本指南以 Vue CLI 官方文档 docs/guide/css.md 为核心脉络系统讲解 Vue CLI 项目中样式处理的完整方案从 CSS 中引用静态资源的路径规则到 Sass/Less/Stylus 预处理器的安装与配置、PostCSS 与 Autoprefixer 的默认行为、CSS Modules 的三种使用方式以及通过css.loaderOptions向各样式 loader 精确传递参数。读完本文你将能够在 Vue CLI 项目中熟练配置样式编译链路并理解这些配置在 cli-service 的 css 配置源码 中的底层作用机制。概览开箱即用的 CSS 能力Vue CLI 项目天生支持三种样式技术栈PostCSSVue CLI 内部集成了 PostCSS 作为样式后处理管线CSS Modules通过style module与.module.css文件约定开箱即用预处理器Sass、Less、Stylus 三种主流预处理器均内置了 webpack 规则支持。这一点在创建项目时的交互提示中也有体现。查看 cssPreprocessors 提示模块 可以发现其提示文案明确写着PostCSS, Autoprefixer and CSS Modules are supported by default即 PostCSS、Autoprefixer 与 CSS Modules 默认支持用户只需在CSS Pre-processors特性中选择是否启用 Sass/SCSS、Less 或 Stylus。在 CSS 中引用静态资源所有编译后的 CSS 都会经过 css-loader 处理其中的url()引用会被解析为模块请求。这意味着你可以基于本地文件结构使用相对路径引用静态资源/* 相对路径基于当前文件位置 */ .logo { background: url(../assets/logo.png); }特别注意~前缀的用法如果希望引用 npm 依赖包内部的文件或者通过 webpack alias 引用的路径必须在路径前加上~前缀以避免歧义/* 引用 npm 包内的资源 */ .icon { background: url(~some-package/icons/foo.png); } /* 引用 webpack alias如 指向 src/下的资源 */ .bg { background: url(~/assets/bg.png); }关于 URL 的完整转换规则请参见 HTML 与静态资源处理 文档中的 URL Transform Rules 小节其核心规则可概括为以绝对路径如/images/foo.png开头的 URL 原样保留以.开头的 URL 被当作相对模块请求按文件系统目录结构解析以~开头的 URL 其后内容被当作模块请求解析以开头的 URL 同样被当作模块请求Vue CLI 默认将别名为projectRoot/src仅限模板中使用。在该小节中还可看到Vue CLI 内部使用 webpack 的 Asset Modules 决定最终文件的存放位置带内容哈希与正确的 public base path并将小于 8KiB 的资源自动内联为 Data URL从而减少 HTTP 请求数如需调整该阈值可通过chainWebpack修改images规则的dataUrlCondition.maxSize。预处理器Sass / Less / Stylus创建项目时选择你可以在使用vue create创建项目时选择预处理器。查看 cssPreprocessors 提示模块 源码可见其提供的选项为Sass/SCSS (with dart-sass)、Less、Stylus。选择结果会写入项目选项cssPreprocessor随后由 cli 生成器 自动向devDependencies注入对应依赖例如选择 Sass 会得到sass与sass-loader选择 Less 会得到less与less-loader选择 Stylus 会得到stylus与stylus-loader。手动安装 loader即使创建项目时没有选择预处理器cli-service 内置的 webpack 配置依然预配置好了对 Sass/Less/Stylus 的全部处理规则你只需手动安装对应的 webpack loader 即可# Sass npm install -D sass-loader sass # Less npm install -D less-loader less # Stylus npm install -D stylus-loader stylus从 css 配置源码 可以看到createCSSRule为每种语言都注册了独立规则scss/sass对应sass-loaderless对应less-loaderstylus对应stylus-loader且.sass规则会强制注入sassOptions: { indentedSyntax: true }以启用缩进语法。安装完成后即可直接导入对应文件类型或在*.vue单文件组件中通过lang属性使用style langscss $color: red; /stylewebpack 4 兼容性说明当前仓库为 Vue CLI 5默认基于 webpack 5但如果你仍在使用 webpack 4Vue CLI 4 的默认版本必须确保 loader 与其兼容否则会遇到 peer dependencies 冲突报错。此时可安装仍兼容 webpack 4 的旧版 loader# Sasswebpack 4 环境 npm install -D sass-loader^10 sassDart Sass 性能提示使用 Dart Sass 时同步编译默认比异步编译快两倍原因是异步回调存在额外开销。为避免该开销可安装fibers包让异步 importer 走同步代码路径npm install -D fibers需要留意的是fibers是原生模块在不同操作系统与构建环境下可能存在兼容性问题。遇到问题时执行npm uninstall -D fibers即可恢复。自动化导入全局样式变量、颜色、mixin如果你希望在每个单文件组件和每个预处理器样式文件中自动导入公共样式如颜色、变量、mixin推荐使用style-resources-loader。以下示例针对 Stylus在每个 SFC 和每个 Stylus 文件中自动导入./src/styles/imports.styl// vue.config.js const path require(path) module.exports { chainWebpack: config { const types [vue-modules, vue, normal-modules, normal] types.forEach(type addStyleResource(config.module.rule(stylus).oneOf(type))) }, } function addStyleResource (rule) { rule.use(style-resource) .loader(style-resources-loader) .options({ patterns: [ path.resolve(__dirname, ./src/styles/imports.styl), ], }) }这里的types数组对应 cli-service 为每种样式语言生成的四条规则分支详见下文 CSS 规则结构因此需要逐一挂载。除此之外也可以直接使用社区插件vue-cli-plugin-style-resources-loader免去手写配置。PostCSSVue CLI 内部使用了 PostCSS这意味着你无需任何额外配置即可获得 PostCSS 处理能力。配置方式可以通过以下两种方式配置 PostCSS配置文件.postcssrc或任何被 postcss-load-config 支持的配置源如postcss.config.js、.postcssrc.js、.postcssrc.json等vue.config.js通过css.loaderOptions.postcss配置 postcss-loader。从 css 配置源码 可知cli-service 会检测项目是否存在合法的 PostCSS 配置loaderOptions.postcss、pkg.postcss或上述配置文件。若不存在则自动注入默认配置使用autoprefixer插件。若存在自定义配置则用户的配置优先与默认的 Autoprefixer 互不干扰——这一点也被 css.spec.js 中的override postcss config测试用例验证。Autoprefixer 与浏览器目标Autoprefixer 插件默认开启。要配置目标浏览器请使用package.json中的browserslist字段或独立的.browserslistrc文件。该字段同时驱动babel/preset-env的 JS 转译与 Autoprefixer 的 CSS 前缀生成详见 浏览器兼容性文档 的 browserslist 小节。{ browserslist: [ 1%, last 2 versions, not dead ] }关于厂商前缀规则的注意事项在生产构建中Vue CLI 会优化 CSS并基于你的浏览器目标丢弃不必要的厂商前缀规则。由于 Autoprefixer 默认开启你应始终只编写无前缀的 CSS 规则其余交给工具链处理。CSS ModulesCSS Modules 提供作用域隔离的样式能力Vue CLI 中支持三种使用方式。方式一在*.vue文件中使用style moduletemplate p :class$style.redThis should be red/p /template style module .red { color: red; } /stylestyle module开箱即用编译后类名会被替换为哈希化的唯一名称模板中通过$style.red访问。方式二在 JavaScript 中以模块方式导入样式文件在 JS 中导入 CSS 或预处理器文件作为 CSS Modules 时文件名必须以.module.(css|less|sass|scss|styl)结尾import styles from ./foo.module.css // 所有支持的预处理器同样适用 import sassStyles from ./foo.module.scss这种方式由 cli-service 内置的normal-modules规则匹配\.module\.\w$支持相关测试用例见 css.spec.js 中的Auto recognition of CSS Modules by file names。方式三将全部样式文件视为 CSS Modules如果想去掉文件名中的.module约定让所有样式文件都按 CSS Modules 处理可在vue.config.js中配置css-loader的modules.auto// vue.config.js module.exports { css: { loaderOptions: { css: { modules: { auto: () true } } } } }值得说明的是在 Vue CLI 4 及更早版本中该需求是通过css.requireModuleExtension: false实现的中文文档 docs/zh/guide/css.md 保留了这一写法而当前仓库的 css 配置源码 中style module分支vue-modules规则会强制将modules.auto设为() true.module.*文件normal-modules规则始终按模块处理因此自定义modules.auto是面向当前版本css-loader v5/v6的推荐方式。测试用例CSS Moduels Options验证了设置modules: false时.module.css不被转换、设置auto: () true时所有样式文件均被转换的行为。自定义生成的类名如需自定义 CSS Modules 生成的类名同样通过css.loaderOptions.css配置所有css-loader选项均受支持// vue.config.js module.exports { css: { loaderOptions: { css: { // 注意以下配置格式在不同 Vue CLI 版本之间存在差异 // Vue CLI v3 使用 css-loader v1 // Vue CLI v4 使用 css-loader v3 // Vue CLI v5 使用 css-loader v5 // 具体格式请查阅对应版本的 css-loader 文档 modules: { localIdentName: [name]-[hash], exportLocalsConvention: camelCaseOnly } } } } }版本兼容性提示css-loader的选项命名随版本演进有所不同——Vue CLI v3 对应 css-loader v1Vue CLI v4 对应 css-loader v3类名配置在modules.localIdentName下、camelCase 通过localsConvention: camelCaseOnlyVue CLI v5 对应 css-loader v5即本仓库当前使用的配置格式。升级 Vue CLI 时请对照相应版本的 css-loader 文档核对选项名。默认类名格式从源码可见只要cssLoaderOptions.modules存在cli-service 会合并默认的localIdentName: [name]_[local]_[hash:base64:5]即默认类名格式为文件名_原始类名_哈希。若你不做任何modules配置style module与.module.*文件即按此格式生成类名。向预处理器 Loader 传递选项css.loaderOptions有时你需要向预处理器的 webpack loader 传递选项最推荐的方式是使用vue.config.js中的css.loaderOptions。例如向所有 Sass/Less 样式传入共享的全局变量// vue.config.js module.exports { css: { loaderOptions: { // 给 sass-loader 传递选项 // / 是 src/ 的别名 // 所以这里假设你有 src/variables.sass 这个文件 // 注意在 sass-loader v8 中这个选项名是 prependData sass: { additionalData: import ~/variables.sass }, // 默认情况下 sass 选项会同时作用于 sass 和 scss 两种语法 // 因为 scss 语法在内部也是由 sass-loader 处理的 // 但在配置 prependData 时 // scss 语法要求语句结尾必须有分号sass 语法则要求不能有分号 // 因此可用 scss 选项对 scss 语法单独配置 scss: { additionalData: import ~/variables.scss; }, // 给 less-loader 传递 Less.js 选项 less: { // less.js 全局变量globalVars 为字段名 globalVars: { primary: #fff } } } } }loaderOptions.sass与loaderOptions.scss的区别在源码与测试中均有体现从 css 配置源码 可见.scss规则使用loaderOptions.scss || loaderOptions.sass合并配置而.sass规则使用loaderOptions.sass并追加indentedSyntax: truecss.spec.js 的scss loaderOptions测试进一步确认分别配置sass.prependData与scss.prependData时两者互不污染scss的选项不会被合并进sass规则。可通过 loaderOptions 配置的 loader支持通过loaderOptions配置的 loader 包括css-loaderpostcss-loadersass-loaderless-loaderstylus-loader这一点与 options.js 中的配置校验 一致css.loaderOptions仅接受css、sass、scss、less、stylus、postcss六个键名配置错误会触发校验告警。为什么推荐 loaderOptions 而非 chainWebpack官方明确建议使用loaderOptions而不是用chainWebpack手动挂载 loader因为这些选项需要在多个使用对应 loader 的位置同时生效手动挂载极易遗漏。从 css 配置源码 的createCSSRule可以清晰地看到这一点每种样式语言css、postcss、scss、sass、less、stylus都会生成四条规则分支vue-modules匹配resourceQuery(/module/)即style modulevue匹配resourceQuery(/\?vue/)即普通stylenormal-modules匹配\.module\.\w$即.module.*文件导入normal普通样式文件导入。每条分支都要依次挂载样式注入 loader、css-loader、postcss-loader 以及预处理器 loader并通过Object.assign({ sourceMap }, loaderOptions.xxx)合并你的选项。因此通过loaderOptions一处配置即可覆盖全部四条分支这正是官方推荐的原因。深入源码生产构建的样式链路最后从 css 配置源码 梳理一条完整的生产构建样式链路帮助你理解 Vue CLI 在样式层面的整体设计CSS 提取生产环境默认通过mini-css-extract-plugin将 CSS 提取为独立文件默认输出路径css/[name].[contenthash:8].css可通过css.extract关闭或自定义开发环境则使用vue-style-loader将样式注入页面支持热更新。测试用例production defaults与css.extract验证了这两种模式下的 loader 序列差异。Source Map默认关闭css.sourceMap: false开启后同时作用于 css-loader、postcss-loader 与预处理器 loader。内联压缩当生产环境不提取 CSSextract: false时内联样式不会经过压缩插件因此 cli-service 会额外注入一个带cssnano的 postcss-loader 实例做内联压缩同时把importLoaders从 2 提升到 3。提取后的压缩生产环境提取 CSS 后通过css-minimizer-webpack-plugin配合 cssnano 压缩并可选开启多核并行parallel且会基于浏览器目标剔除多余的厂商前缀。如果你希望进一步微调这些行为vue.config.js中css对象的完整可用键extract、sourceMap、loaderOptions与默认值定义在 options.js 中可作为配置参考相关自动化测试见 css.spec.js涵盖了默认 loader 序列、生产环境差异、PostCSS 覆盖、CSS Modules 识别、loaderOptions 传递等全部核心行为。【免费下载链接】vue-cli️ webpack-based tooling for Vue.js Development项目地址: https://gitcode.com/gh_mirrors/vu/vue-cli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表