Angular中custom-webpack配置下scss模块@use全局变量报错求助
我有一个使用custom-webpack.config.js配置的Angular应用,通过sass-loader的additionalData注入全局SCSS变量文件_variables.scss。但在styles.scss中用@use引入依赖该全局变量的sizes.scss时,出现$breakpoints未定义的构建报错。把@use 'assets/styles/sizes'移到additionalData里能解决问题,但我不想让sizes.scss全局生效,求其他解决方案。
相关配置与代码
custom-webpack.config.js
module.exports = { module: { rules: [ { test: /\.scss$/, use: [ { loader: "sass-loader", options: { implementation: require("sass"), additionalData: ` @use "src/assets/styles/_variables.scss" as *; `, }, }, ], }, ], }, };
_variables.scss
$sm: 375px; $md: 1280px; $lg: 1920px; $breakpoints: ( 'sm': $sm, 'md': $md, 'lg': $lg, );
sizes.scss
@each $key, $val in $breakpoints { @media screen and (max-width: #{$val - 1}) { .min-#{$key} { display: none !important; } } @media screen and (min-width: #{$val}) { .max-#{$key} { display: none !important; } } }
styles.scss
@use 'assets/styles/sizes' as *;
报错信息
./src/styles.scss - Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined variable.
╷
20 │ @each $key, $val in $breakpoints {src\assets\styles_sizes.scss 20:22 @use
src\styles.scss 3:17 root stylesheet
angular.json 相关配置片段
.... "architect": { "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { "customWebpackConfig": { "path": "./custom-webpack.config.js", "replaceDuplicatePlugins": true }, .... "serve": { "builder": "@angular-builders/custom-webpack:dev-server", ....
使用版本
@angular-builders/custom-webpack: ^14.0.1sass: ^1.55.0sass-loader: 13.0.2
解决方案
方案1:在sizes.scss中显式引入变量文件
直接修改sizes.scss,在开头手动引入依赖的变量文件,让它自身具备获取变量的能力,不依赖全局注入:
@use '../assets/styles/_variables.scss' as *; @each $key, $val in $breakpoints { @media screen and (max-width: #{$val - 1}) { .min-#{$key} { display: none !important; } } @media screen and (min-width: #{$val}) { .max-#{$key} { display: none !important; } } }
这样sizes.scss只会在styles.scss引入它时生效,不会全局污染其他组件样式。
方案2:缩小additionalData的作用范围
修改webpack规则,让全局变量注入只对组件内的SCSS文件生效,排除全局的styles.scss,然后在styles.scss中手动引入变量和sizes:
修改custom-webpack.config.js:
module.exports = { module: { rules: [ { // 只匹配组件内的SCSS,排除全局styles.scss test: /\.scss$/, exclude: /src\/styles\.scss$/, use: [ { loader: "sass-loader", options: { implementation: require("sass"), additionalData: ` @use "src/assets/styles/_variables.scss" as *; `, }, }, ], }, ], }, };
修改styles.scss:
@use 'assets/styles/_variables.scss' as *; @use 'assets/styles/sizes' as *;
这种方式既保留了组件SCSS的全局变量注入,又让全局样式文件按正常依赖顺序加载,避免变量未定义问题。
方案3:用Sass模块系统的@forward规范导出变量
调整_variables.scss,用@forward导出变量,让其他文件可以通过@use规范引入:
修改_variables.scss:
$sm: 375px; $md: 1280px; $lg: 1920px; $breakpoints: ( 'sm': $sm, 'md': $md, 'lg': $lg, ); @forward '.'; // 导出当前文件所有变量
然后在sizes.scss中引入:
@use '../assets/styles/_variables.scss' as *; // 后续循环代码不变
这本质和方案1类似,但更贴合Sass模块系统的设计规范,方便后续变量的统一管理和导出。
内容的提问来源于stack exchange,提问作者DLO

