Amy Blankenship
Amy Blankenship

Reputation: 6961

Keeping CSS out of JS in Angular 2/Angular-CLI

By default, Angular 2 compiles the CSS into JavaScript, especially when using WebPack as in Angular-CLI. I would rather this not happen for a couple of reasons.

The first reason is that when I'm developing, I find it really helps to be able to see in the developer tools exactly what style sheet a specific style rule was coming from and what line number it was on. The second reason is that I think compiling CSS into the code kind of misses the point of good CSS, which is that you can apply a different style sheet and have an entirely different look and feel with the same markup.

Is there a flag somewhere that I can set to leave the CSS in .css files, where IMO it belongs?

Upvotes: 17

Views: 7622

Answers (5)

nilsel
nilsel

Reputation: 61

With angular-cli 1.6.5 you can do this:

ng serve --extract-css

You will still have the style-encapsulation features, but devtools will now point to the component css source file.

Upvotes: 3

shaunak1111
shaunak1111

Reputation: 961

  • Put a wrapper class in html example- <div class="component-1-wrapper"> all yout html here inside component-1-wrapper </div>
  • Structure your sass(scss) in the following way. Since your styles are wrapped inside component-1-wrapper, therefore it will apply only to component-1-wrapperclass .component-1-wrapper{ // all the styles for component-1 here .class-hello{ // styles } }
  • You can compile your css with sass and put all the css(seperated by modules) in seperate folder.Start the filenames by _, sass can import them:

structure

  • You can refer your styles-main.scss in app.ts file @component({ styleUrls:['styles/styles-main.scss']})
  • The style-sheets will be structured this way and individual component's class styles will be applied to particular component since there is a wrapper class in html

Hope it helps!!!!!!

Upvotes: -1

Milad
Milad

Reputation: 28592

This is the whole point of encapsulated components.

A component should have it's own styles encapsulated with it so it can be shipped with the styles.

Imagine you want to publish one of your components to be used by others, shouldn't it have its own styles with it ?

That means Angular needs a way to link those css to the component , thus seperates them into chunks and injects them into head tag.

To solve your problem though , you have couple of options :

1- Not using the Emulated Encapsulation :

Components by default have a property called encapsulation which is set to Emulated , you need to change it to None:

@Component({
   encapsulation:ViewEncapsulation.None
})

Then , you can put all you css in the head tag your self like you'd do with a normal html page.

2- If the problem is theme ing , you can make your component themeable .

You can have a theme attribute for your component and then based on that change the styleing :

@Component({
   selector:'my-component',
   styles:[
    `
       :host{
          [theme="blue"]{

              change what ever you want : 

              h1{
                color:blue; 
              }
           }

       }
    `
  ]
})

And then , using this component would be like :

  <my-component [attr.theme]='"blue"'></my-component> // would be blue theme
  <my-component></my-component> // would be default

Upvotes: 8

brando
brando

Reputation: 8431

I use the angular-cli as well (v1.0.0-beta.22). When I am ready to build for production I run the following command:

ng build -prod -aot

This generates all my production-ready files (bundled, tree-shaken and minified etc). Of particular note is that it will generate two versions of the style sheets.

One in js:

styles.b2328beb0372c051d06d.bundle.js

And another version is plain css:

styles.4cec2bc5d44c66b4929ab2bb9c4d8efa.bundle.css

I run some post-processing on the css file with gulp and use the css version for my production build. I am not sure if the same holds true for lazy loading (where the cli will produced different chunks), but it works for sure when lazy loading is not being used (I haven't launched a production-ready project yet with lazy loading).

I also tried a build with JiT compilation:

ng build -prod

It also produced the raw/minified version of the css style sheet.

Now, I know for sure the folowing does NOT work:

ng build

This will produce all the css embedded within js file, styles.bundle.js.

Since you want to use the raw css file during development, the only workaround I can think of is that you run ng build -prod in order to get the css file. Copy/paste this manually into your assets folder. Run "format" on the file to un-minify the file. Then do a normal build with a modified index.html file referencing your raw css file, and removing the styles.bundle.js script reference. Not pretty, but it might work.

Upvotes: 2

deek
deek

Reputation: 1095

Go to your base Html file(where the root module, main app is injected) and link the CSS stylesheets in your header section.

Webpack will not include it in it's compiled/combined css file which is injected into the page. The css file will still be included at run time in the browser.

<html>

<head>
  <base href="/">
  <meta charset="utf-8">
  <title>dummy</title>
  <meta name="viewport" content="width=device-width">

//was not injected/modified by webpack
  <link rel="apple-touch-icon" sizes="57x57" href="app/images/apple-icon-57x57.png">

//webpack's injected this below from other components's imported/inline css rules
<link href="index-c2cacb5fa3dfbca6116f4e4e63d5c3c7.css" rel="stylesheet"></head>

Upvotes: 5

Related Questions