Angular 6 library shared stylesheets

六眼飞鱼酱① 提交于 2019-12-03 05:43:51

问题


How can you setup a index.scss and import global stylesheets for variables, mixins, etc, to an angular 6 library?

Angular CLI generates a lib with a root component & component scss, but the styles added or imported to the root component are not available to children components. Which makes sense by default to encapsulate the styles, but I just can't find any information or examples on how to set this up yet.

The angular.json "styles": [...] paths that can be used for this with "projectType": "application", don't seem to work with "projectType": "library" either.

Thanks in advance for your help!


UPDATE: My project was initiated using angular cli v6.0.5, following this guide: https://medium.com/@tomsu/how-to-build-a-library-for-angular-apps-4f9b38b0ed11

TL;DR for the guide:

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

This is the file structure angular 6 generates:

    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

Package Versions:

    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

回答1:


For global styles, I've answered it in this question.

For mixins and variables also there's a workaround.

  1. Create an index.scss file in your library's root folder. If you follow this guide from Angular, then your path will be my-project/projects/my-library/index.scss. This is also the folder where your package.json is.

So, index.scss will be the file with your variables and mixins

$grey: #222;
@mixin mymixin {
    background: #222;
}
  1. Include this in you library scss files using import
@import '../../index.scss';

or whatever relative path your component scss file is at.

  1. Now in order to have this file in your app project, copy it post build to the dist directory. To do this, edit your angular library's project's package.json file (NOT THE LIBRARY'S).
{
    "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. Now, very important, DO NOT use ng build to build your library, instead use npm run build. This will automatically execute the copy command. Now the index.scss file is exported along with your library in the my-project/dist folder.

  2. Include the index.scss in your app project's scss files

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

Now you have all your library mixins in all of the projects you installed your library.

Cheers!

PS Workarounds are not the most elegant solutions, but when nothing else works, they work around!




回答2:


Have you tried setting the encapsulation level of the component to none as part of the component metadata? Like this:

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

The ViewEncapsulation levels are:

  • ViewEncapsulation.Emulated: The default, Angular emulates a Shadow DOM.
  • ViewEncapsulation.Native: Use the browser's own Shadow DOM.
  • ViewEncapsulation.None: Styles are Global

Check out the Angular Docs on ViewEncapsulation and I wrote a blog post on it.




回答3:


I think people may be missing the fact that while encapsulation options exist, global styles are output in style tags and can cascade throughout your project.

Here is my setup:

  1. My global styles: styles.scss is output in style tags. The rules target all matching classes and elements as expected. Even within components.

  2. Component styles are encapsulated. That is their value prop. They overwrite globals and keeps component-specific styles with the component family.

  3. @includes such as variables.scss, mixins.scss etc. are included explicitly at the top of any component .scss files when needed.

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

What else would we need?




回答4:


Run ng init on the project, so that it will initialize the project as an Angular CLI project.

Edit: My bad, it seems they removed init from the CLI. You can try ng new --src

It might overwrite some files, so try this on a copy of the project.



来源:https://stackoverflow.com/questions/50582227/angular-6-library-shared-stylesheets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!