【问题标题】:Angular 6 library shared stylesheetsAngular 6 库共享样式表
【发布时间】:2018-11-07 23:36:06
【问题描述】:

如何设置 index.scss 并将变量、mixins 等的全局样式表导入 Angular 6 库?

Angular CLI 生成一个带有根组件和组件 scss 的库,但添加或导入到根组件的样式对子组件不可用。默认情况下封装样式是有意义的,但我找不到任何关于如何设置它的信息或示例。

可用于 "projectType": "application" 的 angular.json "styles": [...] 路径似乎也不适用于 "projectType": "library"

提前感谢您的帮助!


更新:我的项目是使用 angular cli v6.0.5 启动的,遵循本指南:https://medium.com/@tomsu/how-to-build-a-library-for-angular-apps-4f9b38b0ed11

TL;指南的 DR:

ng new my-app --style=scss
ng generate library my-library --prefix ml

这是angular 6生成的文件结构:

    my-app
      projects/
        my-library/
          src/
            lib/
              shared/..
              widgets/..
              my-library.component.ts
              my-library.module.ts
            sass/
              _variables.scss
              styles.scss // <<< This is where I want to `@import 'variables';`, and for it to be available in all the components of the "my-library" project.
            public_api.ts
      src/
        app/
          app.module.ts // << imports projects/my-library/lib/my-library.module as "my-library".
        main.ts
        index.scss
        index.html
      README.md

软件包版本:

    Angular CLI: 6.0.5
    Node: 10.2.1
    OS: darwin x64
    Angular: 6.0.3
    ... animations, common, compiler, compiler-cli, core, forms
    ... http, language-service, platform-browser
    ... platform-browser-dynamic, router

    Package                            Version
    ------------------------------------------------------------
    @angular-devkit/architect          0.6.5
    @angular-devkit/build-angular      0.6.5
    @angular-devkit/build-ng-packagr   0.6.5
    @angular-devkit/build-optimizer    0.6.5
    @angular-devkit/core               0.6.5
    @angular-devkit/schematics         0.6.5
    @angular/cli                       6.0.5
    @ngtools/json-schema               1.1.0
    @ngtools/webpack                   6.0.5
    @schematics/angular                0.6.5
    @schematics/update                 0.6.5
    ng-packagr                         3.0.0
    rxjs                               6.2.0
    typescript                         2.7.2
    webpack                            4.8.3

【问题讨论】:

  • 看来你的项目不是用@angular/cli创建的,如果是新项目我强烈推荐你使用它。
  • @Ploppy 我做了,我使用本指南启动了这个项目:medium.com/@tomsu/…
  • 我面临着完全相同的问题。您找到解决方案了吗?
  • @BramW。不,我没有,我刚刚在每个我想使用公共资源的文件中添加了导入。
  • github.com/angular/angular-cli/issues/10927 表示这是 ng-packagr 的限制,github.com/angular/angular-cli/issues/10869 指定了 gulp 解决方法。对不得不引入 gulp 并不感到兴奋,因此我尝试并正在考虑的另一个(非理想)选项是使用 Angular CLI 创建的“根”库组件来保存库的全局样式。它将有一个空模板,但带有encapsulation: ViewEncapsulation.None,这将导致其样式被添加到全局样式中。然后在应用程序的某处包含(空)模板标签。

标签: angular angular-cli libraries angular6 angular-cli-v6


【解决方案1】:

关于全局样式,我已经在this question回答了。

更新

适用于ng-packgr 9.x 及以上版本

现在直接支持将资产复制到输出文件夹,如this page 中所述

{
  "$schema": "./node_modules/ng-packagr/package.schema.json",
  "name": "@my/library",
  "version": "1.0.0",
  "ngPackage": {
    "assets": [
      "CHANGELOG.md",
      "./styles/**/*.theme.scss"
    ],
    "lib": {
      ...
    }
  }
}

旧答案

**对于其他版本**
  1. 在库的根文件夹中创建一个index.scss 文件。如果您关注this guide from Angular,那么您的路径将是my-project/projects/my-library/index.scss。这也是您的package.json 所在的文件夹。

所以,index.scss 将是包含变量和 mixins 的文件

$grey: #222;
@mixin mymixin {
    background: #222;
}
  1. 使用import 将其包含在您的库 scss 文件中
@import '../../index.scss';

或您的组件 scss 文件所在的任何相对路径。

  1. 现在,为了在您的应用项目中拥有此文件,请将其复制到构建后的 dist 目录中。为此,请编辑 Angular 库项目的 package.json 文件(不是库的文件)。
{
    "name": "my-project",
    "version": "1.0.0",
    "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build && npm run copyScss",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e",
        "copyScss": "xcopy \"projects\my-library\index.scss\" \"dist\\my-library\\\""
    },

    ...
}
  1. 现在,非常重要的是,不要使用ng build 来构建您的库,而是使用npm run build。这将自动执行复制命令。现在index.scss 文件与您的库一起导出到my-project/dist 文件夹中。

  2. 在您的应用项目的 scss 文件中包含 index.scss

// ~ stands for the node_modules folder
@import '~my-library/index.scss';

现在,您在安装库的所有项目中都拥有了所有库 mixin。

干杯!

PS 变通办法不是最优雅的解决方案,但当没有其他办法时,它们会变通!

【讨论】:

  • 如果你想在当前项目之外公开一个库怎么办?就像通过npm link 或发布的 npm 模块一样,如何让 lib-mixin 可以从消费者的应用程序中访问?
  • @Mozgor 解决方案已经解决了这个问题。查看第 3 点。index.scss 被复制到 dist 文件夹并随库一起提供。当您执行npm link 时,dist 文件夹中的所有内容(包括index.scss)都会复制到库的node_modules 文件夹下的文件夹中。然后,您只需按照第 5 点中的说明在消费者应用程序中导入 index.scss。PS 不要跳过第 4 点。否则它将不起作用。
  • 确实,我误读并认为副本是在消费者应用程序中完成的。谢谢指点!您能否解释一下为什么 index.scss 应该是 lib-root 级别,以及当 lib 是单个组件时是否需要它?在这种情况下,我宁愿只公开主题的文件,但我可能错了。
  • @Mozgor index.scss 不必在根目录中。但是在根目录下更容易导入。当你有一个组件时,组件的scss 被编译成css。您仍然可以将scss 复制到 dist 文件夹(如果您愿意,可以在组件的文件夹中)。但是你有两次CSS。这就是为什么我建议有一个额外的 index.scss 文件,其中只有公共组件,即 mixins 和变量。那么你就没有多余的css了。
  • @Xpleria:好的。在“lib”中,我添加了“entryFile”行:“src/public-api.ts”并运行命令 ng build --prod。这会在库项目中创建 dist 文件夹,而不是像以前那样在“项目”文件夹级别创建。如何确保在“项目”文件夹级别创建 dist 文件夹?
【解决方案2】:

在项目上运行ng init,以便将项目初始化为 Angular CLI 项目。

编辑: 我的错,他们似乎从 CLI 中删除了init。你可以试试ng new --src

它可能会覆盖某些文件,因此请在项目的副本上尝试此操作。

【讨论】:

  • "The specified command ("init") is invalid. For a list of available options, run "ng help"."
  • 我的错,似乎他们从 cli 中删除了 init,您可以尝试 ng new --src 它可能会覆盖 so 文件,因此请在项目副本上尝试此操作
【解决方案3】:

我认为人们可能会忽略这样一个事实,即虽然存在封装选项,但全局样式会在样式标签中输出,并且可以在整个项目中级联。

这是我的设置:

  1. 我的全局样式:styles.scss 在样式标签中输出。规则按预期针对所有匹配的类和元素。甚至在组件内。

  2. 组件样式被封装。那是他们的价值支柱。它们覆盖全局变量并与组件系列保持组件特定的样式。

  3. @includes(如 variables.scss、mixins.scss 等)会在需要时显式包含在任何组件 .scss 文件的顶部。

@import '../../../../scss/includes/variables';

我们还需要什么?

【讨论】:

  • 全局 styles.scss 是为 Angular 应用程序提供的,但对于 Angular Libraries 似乎并非如此,OP 试图为其定义全局样式。不幸的是,似乎只有解决方法可以做到这一点。
【解决方案4】:

您是否尝试将组件的封装级别设置为无作为组件元数据的一部分?像这样:

@Component({
  selector: 'app-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  encapsulation: ViewEncapsulation.None
})

ViewEncapsulation 级别是:

  • ViewEncapsulation.Emulated:默认情况下,Angular 模拟 Shadow DOM。
  • ViewEncapsulation.Native:使用浏览器自带的 Shadow DOM。
  • ViewEncapsulation.None:样式是全局的

查看Angular Docs on ViewEncapsulation,我写了blog post on it

【讨论】:

  • @JeffyHouiser 如何将主题从库中引入项目
  • @IamStalker 对不起,我不明白你的问题
  • ViewEncapsulation.None 不应使用 b/c 它仅在使用它的组件初始化后添加全局样式。因此,您可能会遇到奇怪的情况,即应用程序的某个随机部分只有在您转到应用程序的另一个完全随机部分后才会中断。
猜你喜欢
  • 2018-12-12
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 1970-01-01
  • 2018-10-23
  • 2013-05-15
相关资源
最近更新 更多