Skip to content
This repository has been archived by the owner on Feb 27, 2019. It is now read-only.

Feature Request: One SCSS file for each component #72

Open
wembernard opened this issue Jul 6, 2016 · 11 comments
Open

Feature Request: One SCSS file for each component #72

wembernard opened this issue Jul 6, 2016 · 11 comments

Comments

@wembernard
Copy link

Description

As a best practice, I would love to be able to have one SCSS file per component such as

src
├── app
│   ├── footer.html
│   ├── footer.scss
│   ├── footer.spec.ts
│   ├── footer.ts
│   ├── header.html
│   ├── header.scss
│   ├── header.spec.ts
│   ├── header.ts
│   ├── main.html
│   ├── main.scss
│   ├── main.spec.ts
│   ├── main.ts

Is it on your roadmap?

@micaelmbagira
Copy link
Member

Hi @wembernard
I am not sure about the question:

  • do you want style to be splitted in one file per component in the generated templates ?
  • or do you want to be able to create your own scss file, other than src/index.scss ? If so, you can do it by with sass @import (Or if you are using Angular 2 and React, you can specify the style directly in the js code)

@wembernard
Copy link
Author

I'd like to have "one file per component" - each component having its own style.

Currently, I'm already using your workaround with @import but having some index.scss with

@import './app/footer.scss'
@import './app/header.scss'
@import './app/main.scss'
...

is kinda cumbersome and requires you to edit this file everytime you rename/delete some .scss file.

@micaelmbagira
Copy link
Member

Well, there is no other way to do so... If you create a .scss file, you'll necessary need to add it into your index.scss.
As I said, the other way is

if you are using Angular 2 and React, you can specify the style directly in the js code

@Swiip
Copy link
Member

Swiip commented Jul 11, 2016

In gulp-angular we had a mechanism for auto injecting sub scss files in the index. It was no so great, and caused ordering problems. Now, modern fmk have their way to include style on each component.

So we're not going to reproduce auto injecting thing. Look at https://angular.io/docs/ts/latest/guide/component-styles.html instead.

@wembernard
Copy link
Author

wembernard commented Jul 11, 2016

@Swiip I know and I loved it 👍 I fixed ordering problems by prefixing files with 10_, 20_ when necessary (which is very occasional).

About styleUrls property from @Component, is there a way to use a SCSS there "natively"? In that case, there is indeed no need for such feature ;)

@wembernard
Copy link
Author

Ok, I found how to make this work. Here is an example:

@Component({
  selector: 'home',
  template: require('./home.component.html'),
  styles: [ String(require('./home.component.scss')) ]
})

Interesting notes:

  • As you may notice, we use the same way we include with template option.
  • The trick here is the use of String() on require(). If you don't, you'll get a Uncaught (in promise): Expected 'styles' to be an array of strings..
  • The webpack conf already takes care of compiling your SCSS into CSS so you don't have to worry.

If you agree with this solution, I suggest to add this example in your generator :)

@Swiip
Copy link
Member

Swiip commented Jul 13, 2016

Perfect, that was what I got in mind !

+1 for keeping this as an example

@zckrs
Copy link
Member

zckrs commented Sep 21, 2016

Reopened to keep example

@zckrs zckrs reopened this Sep 21, 2016
@PostImpatica
Copy link

The suggested solution is causing the the ecapsulation to drop. I removed "style" from the css loader and replaced it with css-to-string(-loader). Now I can use styles: [require('./home.scss')], like normal and encapsulation works. the main index.scss doesn't work but I don't care, I wasn't using it anyway.

@PostImpatica
Copy link

if you want to load both, change the index.scss file to index.global.scss then use the following:

`test: /global.(css|scss)$/,
        loaders: [
         'style',
      'css',
      'sass',
      'postcss'
    ]
  },
  {
    test: /\.(css|scss)$/,
    exclude: /global.(css|scss)$/,
    loaders: [
      'css-to-string',
      // 'style',
      'css',
      'sass',
      'postcss'
    ]
  },`

Afterwards, the index.global.scss file will load globally (I assume that's what's going on anyway) and the other scss files loaded in your modules will have encapsulation.

@teresapr
Copy link

I'm using an additional require expression for webpack, it is working, even if I think is not most elegant solution. The goal was to keep Angular2 syntax as clean as possible, ie not using require inside component:

 styles: [require('./footer.scss').toString()],
 template: require('./footer.html')

but rather this way:

`import {Component} from "@angular/core";

// for webpack
require('./footer.scss');

@Component({
     selector: 'footer',
     templateUrl: 'app/footer/footer.html',
    styleUrls: ['app/footer/footer.scss'],
})
export class FooterComponent {}`

Webpack is working fine this way.

Maybe someone is having a better solution?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants