You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:58:14