【问题标题】:How to add global style to angular 6/7 library如何将全局样式添加到 Angular 6/7 库
【发布时间】:2019-04-21 23:27:25
【问题描述】:

我试图以与 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)

我猜这是在单独的库中添加全局样式的另一种方法。谁能帮帮我?

【问题讨论】:

  • 路径从src开始,请提供您的项目结构
  • 另外,您可以创建一个SCSS 文件并将其导入到您项目的原始style.scss 中。
  • 您找到解决方案了吗?

标签: css angular styles angular-library


【解决方案1】:

正如@codeepic已经指出的,目前有a standard solution

ng-package.json添加

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

提供的路径应该是您的文件的路径。同时,它们将是您的 /dist 文件夹中的路径。
在构建时,文件将被复制到 /dist。您的库的用户将能够将它们添加到他们的全局样式中,如下所示。

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

这样您可以复制任何类型的文件。

附:与 CSS 一起使用时,不要忘记您可以创建一个可以像 node_modules/&lt;your-library-name&gt;/styles 一样导入的 index.css 文件。

【讨论】:

    【解决方案2】:

    来自Compiling css in new Angular 6 libraries

    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. 在库的 /src 目录中添加 _theme.scss,该目录实际上包含并导入我们要捆绑的所有 css。

    4. 添加 postbuild npm 脚本以运行 css-bundle.ts

    5. 将它包含在 angular.json 中应用程序的样式标签中

    【讨论】:

    • 你能解释一下包括什么吗? > 将其包含在 angular.json 中应用程序的样式标签中
    • @OPV 打开 angular.json 并转到样式属性(应该在 build > options 属性中)并将其添加为数组项。你可以在这里查看更多信息:truecodex.com/course/angular-6/…
    • css-bundle.ts 链接已失效。
    • 感谢@Episodex 提及这一点。用内容更新了答案。
    【解决方案3】:

    来自this issue solution

    cpxscss-bundle 作为开发依赖项安装到您的package.json。然后在你的 package.json “scripts” 属性中添加以下条目:

    "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)

    【讨论】:

      【解决方案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.scsscore.scss 是全球性的

      styles/core.scss

      body {
          background: #333;
      }
      

      core.scss 是可选的,我只是想保持根文件干净。


      更新:如果您也想要混入和变量,请关注this answer

      【讨论】:

      • 这应该如何工作?我是否必须将每个库组件包装在 lib-my-library 中?
      • 不,样式是全局的。意思是,它们适用于所有元素,无论它们属于哪个组件。由于encapsulation: ViewEncapsulation.None这一行,样式没有被封装。
      • 感谢@NeilPatrao - 工作就像一个魅力。您知道现在是否有更好的方法,或者您使用空组件的解决方法仍然是最干净的解决方案吗?
      • @codeepic 嗨,查看这个答案stackoverflow.com/a/57219374/1393400 它正是您正在寻找的解决方案。
      • @NeilPatrao - 只需检查angular.io/guide/creating-libraries 官方库文档上的信息,看起来从 ng-packagr 版本 9 开始,您可以配置工具以自动复制资产。更多信息:angular.io/guide/…
      猜你喜欢
      • 1970-01-01
      • 2022-01-23
      • 2019-03-25
      • 2022-08-20
      • 2021-11-07
      • 2021-03-06
      • 2019-07-09
      • 2017-08-27
      • 1970-01-01
      相关资源
      最近更新 更多