'How to add global style to angular 6/7 library
I was trying to add global styles in the same way like in angular app, but it totally does not work.
My libraries' name is example-lib, so I added styles.css
to /projects/example-lib/
. I added styles in main angular.json
file:
...
"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
],
},
...
But when I tried build library using command:
ng build example-lib
I got error:
Schema validation failed with the following errors:
Data path "" should NOT have additional properties(styles)
I guess that is the other way to add global styles in separate library. Anyone can help me?
Solution 1:[1]
I have a workaround for this. Just create the root component of your library without view encapsulation and all its styles will be then global.
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';
Now your my-library.component.scss and core.scss are global
styles/core.scss
body {
background: #333;
}
core.scss is optional, I just like to keep the root files clean.
Update: In case you want your mixins and variables too, then follow this answer.
Solution 2:[2]
As @codeepic already pointed out, there is currently a standard solution.
In ng-package.json add
"assets": ["./styles/**/*.css"]
The provided paths should be the paths to your files. At the same time, they will be the paths inside your /dist folder.
On build, the files will be copied to /dist. Users of your library will be able to add them to their global styles as follows.
/* styles.css */
@import url('node_modules/<your-library-name>/styles/<file-name>');
This way you can copy any type of files.
P.S. When used with CSS, do not forget that you can create an index.css file that can be imported just like node_modules/<your-library-name>/styles
.
Solution 3:[3]
From Compiling css in new Angular 6 libraries:
install some devDependencies in our library in order to bundle the css:
- ng-packagr
- scss-bundle
- ts-node
Create 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();
Add _theme.scss inside the /src directory of the library that actually contains and imports all the css that we want to bundle.
Add postbuild npm script to run the css-bundle.ts
Include it in the styles tag in your Application in the angular.json
Solution 4:[4]
From this issue solution
Install cpx
and scss-bundle
as Dev dependencies to your package.json
. Then add the following entries in your package.json "scripts" property:
"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\"",
...
}
Replace "mylib" with your real library name and then just run in your terminal build-mylib
. That would compile your scss assets to your dist folder.
You use this global styles in your actual Angular project just import them in your angular.json
file within your project settings:
"styles": [
"src/styles.scss",
"dist/my-shiny-library/_theme.scss"
],
(use dist if your project is in the same workspace, or node_moduled if its an imported library)
Solution 5:[5]
1- be sure you are putting your styles inside the library
example:
projects/your-lib-name/assets/styles.css
2- then in your ng-package.json (in the lib for sure) put the assets rule
{
"$schema": ... ,
"dest": ... ,
"assets": [ "./assets/*" ],
"lib": ...
}
3- in your application, you can use this asset
"styles": [
"../your-lib-name/assets/styles.css"
]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | |
Solution 4 | Chris Stillwell |
Solution 5 | ahmad-g-mustafa |