Как добавить глобальный стиль в библиотеку angular 6/7

Я пытался добавить глобальные стили так же, как и в приложении angular, но это совершенно не работает.

Имя моей библиотеки - example-lib, поэтому я добавил styles.css в /projects/example-lib/. Я добавил стили в главный angular.json файл:

...
"example-lib": {
  "root": "projects/example-lib",
  "sourceRoot": "projects/example-lib/src",
  "projectType": "library",
  "prefix": "ngx",
  "architect": {
    "build": {
      "builder": "@angular-devkit/build-ng-packagr:build",
      "options": {
        "tsConfig": "projects/example-lib/tsconfig.lib.json",
        "project": "projects/example-lib/ng-package.json",
        "styles": [
          "projects/example-lib/styles.css" <!-- HERE 
        ],
      },
...

но когда я попытался построить библиотеку с помощью команды:

ng build example-lib

У меня ошибка:

Schema validation failed with the following errors:
  Data path "" should NOT have additional properties(styles)

Думаю, это другой способ добавить глобальные стили в отдельную библиотеку. Кто-нибудь может мне помочь?


person Jaroslaw K.    schedule 19.11.2018    source источник


Ответы (4)


У меня есть обходной путь. Просто создайте корневой компонент вашей библиотеки без инкапсуляции представления, и все его стили станут глобальными.

my-library.component.ts

import { Component, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'lib-my-library',
  templateUrl: './my-library.component.html',
  styleUrls: ['./my-library.component.scss'],
  encapsulation: ViewEncapsulation.None
})
export class MyLibraryComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

my-library.component.html

<!-- html content -->

my-library.component.scss

@import './styles/core.scss';

Теперь ваши my-library.component.scss и core.scss являются глобальными.

styles / core.scss

body {
    background: #333;
}

core.scss не является обязательным, я просто хочу, чтобы корневые файлы были чистыми.


Обновление: если вам тоже нужны миксины и переменные, следуйте этому ответу.

person Xpleria    schedule 27.03.2019
comment
Возможно, это простой способ сделать это. Пальцы вверх! - person carkod; 16.04.2019
comment
Как это должно работать? Должен ли я оборачивать каждый компонент библиотеки в lib-my-library? - person Adam M Thompson; 10.06.2019
comment
Нет, стили глобальные. Это означает, что они применяются ко всем элементам, независимо от того, к какому компоненту они принадлежат. Стили не инкапсулируются из-за этой строки encapsulation: ViewEncapsulation.None. - person Xpleria; 11.06.2019
comment
Спасибо @NeilPatrao - отлично сработало. Знаете ли вы, есть ли лучший способ сейчас, или ваш обходной путь с пустым компонентом по-прежнему остается самым чистым решением? - person codeepic; 14.04.2020
comment
@NeilPatrao Хорошо - я сделал, как вы описали выше, и это работает как шарм для Storybook, но теперь, когда я хочу использовать глобальные стили из библиотеки в приложении, которое использует библиотеку, мне нужно где-то разместить - в идеале в app.component. html - это компонент ‹global-styles› ‹/global-styles›, и это действительно хакерский метод. Я бы предпочел импортировать .scss с глобальными стилями библиотеки в файл styles.scss в приложении, но стили библиотеки не отображаются через общедоступную библиотеку -api - person codeepic; 17.04.2020
comment
@codeepic привет, ознакомьтесь с этим ответом stackoverflow.com/a/57219374/1393400, у него есть именно то решение, которое вы ищете . - person Xpleria; 18.04.2020
comment
Хорошо - я уже изучал ваш ответ, на который вы меня указали. Добро пожаловать, чтобы разобраться в этом дерьме. Я думаю, мне придется добавить шаг copy .scss в сборку, как вы предлагаете. Это действительно странно, что команда Angular не поддерживает глобальные стили для библиотек из коробки без того, чтобы разработчикам приходилось прибегать к обходным путям. - person codeepic; 19.04.2020
comment
@NeilPatrao - просто проверяем информацию в angular.io/guide/creating-libraries документах официальной библиотеки. и похоже, что начиная с версии 9 ng-packagr вы можете настроить инструмент для автоматического копирования ресурсов. Подробнее: angular.io/guide/ - person codeepic; 19.04.2020
comment
@codeepic спасибо, что указали на это, я обновил другой ответ - person Xpleria; 20.04.2020
comment
это гениальное решение :) - person Datum Geek; 25.09.2020

Из Компиляция css в новых библиотеках Angular 6:

  1. установите некоторые devDependencies в нашу библиотеку, чтобы связать css:

    • ng-packagr
    • scss-пакет
    • ts-узел
  2. Создайте css-bundle.ts:

    import { relative } from 'path';
    import { Bundler } from 'scss-bundle';
    import { writeFile } from 'fs-extra';
    
    /** Bundles all SCSS files into a single file */
    async function bundleScss() {
      const { found, bundledContent, imports } = await new Bundler()
        .Bundle('./src/_theme.scss', ['./src/**/*.scss']);
    
      if (imports) {
        const cwd = process.cwd();
    
        const filesNotFound = imports
          .filter(x => !x.found)
          .map(x => relative(cwd, x.filePath));
    
        if (filesNotFound.length) {
          console.error(`SCSS imports failed \n\n${filesNotFound.join('\n - ')}\n`);
          throw new Error('One or more SCSS imports failed');
        }
      }
    
      if (found) {
        await writeFile('./dist/_theme.scss', bundledContent);
      }
    }
    
    bundleScss();
    
  3. Добавьте _theme.scss в каталог / src библиотеки, которая фактически содержит и импортирует все CSS, которые мы хотим связать.

  4. Добавьте сценарий postbuild npm для запуска css-bundle.ts

  5. Включите его в тег стилей в вашем приложении в angular.json

person yazantahhan    schedule 20.02.2019
comment
Не могли бы вы объяснить, что включают в себя? ›Включите его в тег стилей в своем приложении в angular.json. - person OPV; 10.01.2020
comment
@OPV откройте angular.json и перейдите к свойству стилей (должно быть внутри свойств сборки ›options) и добавьте его как элемент массива. Дополнительную информацию можно найти здесь: truecodex.com/course/angular-6/ - person yazantahhan; 12.01.2020
comment
css-bundle.ts ссылки мертвы. - person Episodex; 01.04.2021
comment
Спасибо @Episodex за упоминание об этом. Обновил ответ содержанием. - person yazantahhan; 01.04.2021

Как уже указывал @codeepic, в настоящее время существует стандартное решение.

В ng-package.json добавьте

"assets": ["./styles/**/*.css"]

Предоставленные пути должны быть путями к вашим файлам. В то же время это будут пути внутри вашей папки / dist.
При сборке файлы будут скопированы в / dist. Пользователи вашей библиотеки смогут добавлять их в свои глобальные стили следующим образом.

/* styles.css */
@import url('node_modules/<your-library-name>/styles/<file-name>');

Таким образом вы можете копировать файлы любого типа.

P.S. При использовании с CSS не забывайте, что вы можете создать файл index.css, который можно импортировать так же, как node_modules/<your-library-name>/styles.

person Romanov Eugene    schedule 05.04.2021

Из этого решения проблемы

Установите cpx и scss-bundle как зависимости Dev в свой package.json. Затем добавьте следующие записи в свойство "scripts" package.json:

"scripts": {
  ...
  "build-mylib": "ng build mylib && npm run build-mylib-styles && npm run cp-mylib-assets",
  "build-mylib-styles": "cpx \"./projects/mylib/src/lib/style/**/*\" \"./dist/mylib/style\" && scss-bundle -e ./projects/mylib/src/lib/style/_style.scss -d ./dist/mylib/style/_styles.scss",
  "cp-mylib-assets": "cpx \"./src/assets/**/*\" \"./dist/mylib/assets\"",
  ...
}

Замените «mylib» на свое настоящее имя библиотеки, а затем просто запустите в своем терминале build-mylib. Это скомпилирует ваши ресурсы scss в папку dist.

Вы используете эти глобальные стили в своем реальном проекте Angular, просто импортируйте их в свой angular.json файл в настройках проекта:

"styles": [
  "src/styles.scss",
  "dist/my-shiny-library/_theme.scss"
],

(используйте dist, если ваш проект находится в той же рабочей области, или node_moduled, если это импортированная библиотека)

person Daniel Llano    schedule 31.05.2019