Nx 单体仓库中 Angular Material 3 自定义主题无法生效
解决Angular + Nx项目中
mat.define-palette未定义的报错 问题场景
在Nx仓库维护Angular应用,执行npx nx run testapp:serve时触发Sass编译错误,提示mat.define-palette是未定义函数。
报错详情
./src/app/shared/design/testapp.scss - Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js): Undefined function. ╷ 38 │ $testapp-primary: mat.define-palette($palette-testapp-blue); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ╵ src\app\shared\design\testapp.scss 38:16 root stylesheet ./src/app/shared/design/testapp.scss?ngGlobalStyle - Error: Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): HookWebpackError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js): Undefined function. ╷ 38 │ $testapp-primary: mat.define-palette($palette-testapp-blue); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ╵ src\app\shared\design\testapp.scss 38:16 root stylesheet
相关代码与配置
testapp.scss代码
@use "@angular/material" as mat; @include mat.core(); $palette-testapp-blue: ( A100: #8897ba, A200: #5a698a, A400: #2e3f5d, contrast: ( A100: rgb(96, 96, 96), A200: rgb(96, 96, 96), A400: rgb(96, 96, 96), ), ); $palette-testapp-gold: ( A100: #ffe5af, A200: #cfb37f, A400: #9d8452, contrast: ( A100: rgb(96, 96, 96), A200: rgb(96, 96, 96), A400: rgb(96, 96, 96), ), ); $palette-testapp-red: ( A100: #ffafae, A200: #cf7f7f, A400: #9c5153, contrast: ( A100: rgb(96, 96, 96), A200: rgb(96, 96, 96), A400: rgb(96, 96, 96), ), ); $testapp-primary: mat.define-palette($palette-testapp-blue); $testapp-accent: mat.define-palette($palette-testapp-gold); $testapp-warn: mat.define-palette($palette-testapp-red); $testapp-theme: mat.define-light-theme($testapp-primary, $testapp-accent, $testapp-warn); @include mat.all-component-themes($testapp-theme);
project.json中的styles配置
... "styles": [ "src/styles.scss", "src/app/shared/design/testapp.scss" ], ...
package.json依赖版本
"dependencies": { "@angular/animations": "~18.1.2", "@angular/cdk": "^18.1.2", "@angular/common": "~18.1.2", "@angular/compiler": "~18.1.2", "@angular/core": "~18.1.2", "@angular/fire": "^18.0.1", "@angular/forms": "~18.1.2", "@angular/material": "^18.1.2", "@angular/platform-browser": "~18.1.2", "@angular/platform-browser-dynamic": "~18.1.2", "@angular/router": "~18.1.2", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.14.0" }, "devDependencies": { "@angular-devkit/build-angular": "~18.1.2", "@angular-devkit/core": "~18.1.2", "@angular-devkit/schematics": "~18.1.2", "@angular-eslint/eslint-plugin": "~18.1.0", "@angular-eslint/eslint-plugin-template": "~18.1.0", "@angular-eslint/template-parser": "~18.1.0", "@angular/cli": "~18.1.2", "@angular/compiler-cli": "~18.1.2", "@angular/language-service": "~18.1.2", "@nx/angular": "19.5.3", "@nx/workspace": "19.5.3", "@schematics/angular": "~18.1.2", "@types/jasmine": "~5.1.4", "@types/jasminewd2": "~2.0.3", "@types/node": "20.10.3", "codelyzer": "^6.0.2", "jasmine-core": "~5.1.1", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.4.2", "karma-chrome-launcher": "~3.1.0", "karma-coverage-istanbul-reporter": "~3.0.3", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "^2.1.0", "nx": "19.5.3", "protractor": "~7.0.0", "ts-node": "~10.9.2", "tslint": "~6.1.3", "typescript": "5.5.4" }
解决方案
这是Angular Material 18的重大API变化导致的:define-palette、define-light-theme等旧版主题函数已被移除,改用CSS变量驱动的新主题系统。
修改testapp.scss代码如下:
@use "@angular/material" as mat; // 1. 定义自定义调色板(需遵循标准色调键:50,100,...,900,A100,A200,A400,A700) $testapp-blue: mat.palette( mat.$blue-palette, 50: #8897ba, 100: #8897ba, 200: #5a698a, 400: #2e3f5d, contrast: ( 50: rgb(96, 96, 96), 100: rgb(96, 96, 96), 200: rgb(96, 96, 96), 400: rgb(96, 96, 96), ) ); $testapp-gold: mat.palette( mat.$amber-palette, 50: #ffe5af, 100: #ffe5af, 200: #cfb37f, 400: #9d8452, contrast: ( 50: rgb(96, 96, 96), 100: rgb(96, 96, 96), 200: rgb(96, 96, 96), 400: rgb(96, 96, 96), ) ); $testapp-red: mat.palette( mat.$red-palette, 50: #ffafae, 100: #ffafae, 200: #cf7f7f, 400: #9c5153, contrast: ( 50: rgb(96, 96, 96), 100: rgb(96, 96, 96), 200: rgb(96, 96, 96), 400: rgb(96, 96, 96), ) ); // 2. 创建主题配置 $testapp-theme: mat.theme( ( color: ( primary: $testapp-blue, accent: $testapp-gold, warn: $testapp-red, ), typography: mat.$typography-config, density: 0, ) ); // 3. 全局应用主题样式 @include mat.all-component-themes($testapp-theme);
关键变化说明
- 用
mat.palette()替代旧的mat.define-palette(),调色板需使用标准色调键(50到900的渐变值,加上A系列色调) - 用
mat.theme()替代mat.define-light-theme(),通过配置对象统一管理主题的颜色、排版、密度属性 - 保留
mat.all-component-themes()来为所有Material组件应用主题样式
修改后重新执行npx nx run testapp:serve即可正常编译。
内容的提问来源于stack exchange,提问作者pax
相关产品推荐
相关产品推荐

