【问题标题】:Angular CLI with Webpack - How to include global SCSS in project?带有 Webpack 的 Angular CLI - 如何在项目中包含全局 SCSS?
【发布时间】:2017-01-02 11:37:15
【问题描述】:

我正在创建一个全新的 Angular 2 项目,使用 Angular CLI with Webpack。我似乎不太明白如何创建一个全局 SCSS 文件来容纳 mixins、变量和特定标签的导入。

每当我尝试在任何 SCSS 文件中定位 <body> 时,当我检查元素时,这些样式都无处可寻。我尝试创建一个 app.css 文件并将其包含在 index.html 文件的头部,但后来我遇到了无法导入我的 mixins 或变量或任何此类的问题。

是否有人能够创建某种app.scss 文件,所有子组件都从中继承全局样式,并且能够定位<body>

【问题讨论】:

标签: angular angular-cli


【解决方案1】:

在应用全局样式时,使用 Webpack 的最新版本 angular-cli 似乎存在错误。请参考这个Github issue

更新:2016 年 8 月 31 日 升级到最新版本 (1.0.0-beta.11-webpack.8) 似乎已经解决了 angular-cli 全局样式的问题。要设置全局样式,请按照说明here。默认使用全局 CSS 文件,如果您希望使用全局 SCSS 样式表,可以在创建应用时指定 --style=scss 标志:

ng new scss-project --style=scss

angular-cli 将生成一个全局样式表styles.scss 并将其包含在angular-cli.json 文件中。这向angular-cli 表明styles.scss 中声明的样式应该是全局的并应用于整个应用程序(而不是作用于特定组件)。这相当于通过index.html 中的链接语句包含样式表。

对于现有项目,您可以使用以下方式设置默认样式:

ng set defaults.styleExt scss

在您的angular-cli.json 中,可以将额外的全局样式表或脚本添加到如下所示的样式和脚本数组中:

"apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": "assets",
      "index": "index.html",
      "main": "main.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.json",
      "prefix": "app",
      "mobile": false,
      "styles": [
        "styles.scss"
      ],
      "scripts": [],
      "environments": {
        "source": "environments/environment.ts",
        "prod": "environments/environment.prod.ts",
        "dev": "environments/environment.dev.ts"
      }
    }
  ]

为什么样式没有应用到你的 body 标签?

我在这里猜测是因为您没有发布任何代码,但您的 SCSS 样式未应用于<body> 标签的原因是因为您使用的是Component Styles。当使用--style=scss 标志生成angular-cli 项目时,它会创建一个名为app.compontent.ts 的根级组件:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent {
  title = 'app works!';
}

它还会生成一个名为app.component.scssComponent Style。这一点很重要,因为组件样式的范围仅限于它们的组件。在组件中设置组件样式是这样的:

styleUrls: ['app.component.scss']

您在app.component.scss 中包含的任何样式都将仅应用于app.component.ts 及其对应的模板app.component.html(及其子模板)。样式未应用于<body> 标签的原因是它位于angular-cli 生成的index.html 文件中的根级组件范围之外:

  <body>
    <app-root>Loading...</app-root>
  </body>

我希望这能回答你的问题。

【讨论】:

  • 嘿布莱克,非常感谢您的解释,这实际上很有意义。我最终不得不创建一个全局 app.css 并将其包含在 index.html 文件中,这不太理想,但它现在可以工作。再次感谢您的解释:D
  • 没问题,angular-cli中的bug似乎在1.0.0-beta.11-webpack.8中修复了。请参阅我更新的答案,特别是按照此链接中的说明包含全局 SCSS 样式:github.com/angular/angular-cli#global-styles。您应该能够避免在 index.html 文件中使用全局 app.css。
  • 太棒了,感谢更新!我已经更新到 1.0.0-beta.11-webpack.8,但是现在当我尝试运行 ng serve 时,我得到一个错误(即使在我更新了 angular-cli.json 之后):Cannot read property 'length' of undefined TypeError: Cannot read property 'length' of undefined at Object.getWebpackCommonConfig (/Applications/MAMP/htdocs/learnloop/node_modules/angular-cli/addon/ng2/models/webpack-build-common.ts:23:25) 我不是很确定该怎么办,因为我相信我做的一切都是正确的
  • 但是假设您在 app.component.scss 中使用(全局) variables.scss 和 mixins.scss .... 如果您不将它们包含在文件顶部,linter 会抛出错误,认为变量不存在....但是如果您将它们包含在每个组件的 scss 之上,则每次都会将其包含在大 css 文件中....如何避免这种情况?
【解决方案2】:

你必须从组件文件中导入变量所在的文件:

@import "XX/XX/XX/_name.scss";

XX 是您的文件的相对路径,带有变量

【讨论】:

    【解决方案3】:

    游戏可能有点晚了。对于我们来说,我们有我们的自定义 webpack 配置并利用 sass-resources-loader 将全局 mixins/变量公开给组件。

    { test: /\.scss$/, loader: ["raw-loader", "sass-loader", { loader: 'sass-resources-loader', options: { resources: ['./styles/global/_common.scss', './styles/global/_mixins.scss', './styles/global/_grid.scss', 'node_modules/bootstrap/scss/_mixins.scss', 'node_modules/bootstrap/scss/_variables.scss'] }, } ] }

    【讨论】:

      猜你喜欢
      • 2017-11-11
      • 2017-08-22
      • 2017-11-13
      • 2017-08-22
      • 2017-02-08
      • 1970-01-01
      • 2016-12-30
      • 1970-01-01
      • 2018-02-22
      相关资源
      最近更新 更多