Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use LESS files #165

Closed
jbazinga opened this issue Dec 17, 2015 · 24 comments
Closed

How to use LESS files #165

jbazinga opened this issue Dec 17, 2015 · 24 comments

Comments

@jbazinga
Copy link

I would like to use less files in project.

UPDATE - Solution:

  • install npm dependencies: npm install --save-dev less less-loader
  • add less extension to resolve.extensions section:
resolve: {
    // ensure loader extensions match
    extensions: ['','.ts','.js','.json', '.less', '.css', '.html']
  },
  • add a loader like: { test: /.less$/, exclude: /node_modules/, loader: 'raw-loader!less-loader' }
  • and now can use like:
@Component({
  styles: [ require('./filename.less') ],
...
})

The problem:

I tried this config in webpack.config.js:

{ test: /\.less$/, loader: "raw-loader!less-loader"}

and use it as home.ts:

@Component({
  selector: 'home',
  directives: [ FORM_DIRECTIVES ],
  pipes: [],
  styles: [ require('./home.less') ],
  template: require('./home.html')
})

but when I try to npm start, I got the following error:

ERROR in ./src/app/home/home.less
Module build failed: visitors[i].run is not a function
 @ /home/ubuntu/workspace/browserclient/src/app/home/home.less (line null, column -1)
 near lines:
 @ ./src/app/home/home.ts 23:21-43

My less file is very basic (copy it from lesscss.org startpage)

@base: #f938ab;

.box-shadow(@style, @c) when (iscolor(@c)) {
  -webkit-box-shadow: @style @c;
  box-shadow:         @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
  .box-shadow(@style, rgba(0, 0, 0, @alpha));
}
.box {
  color: saturate(@base, 5%);
  border-color: lighten(@base, 30%);
  div { .box-shadow(0 0 5px, 30%) }
}

Thanks

@asafyish
Copy link

In webpack:

{
        test: /\.less$/,
        exclude: /node_modules/,
        loader: 'raw-loader!less-loader'
}

Then in your component:

@Component({
  styles: [ require('./filename.less') ],
})

Angular2 expects a string in the styles array, because it modifies the string to encapsulate the styling. Using style-loader/css-loader loads the css and inject to the html, without encapsulating, and doesn't return a string, raw-loader just load the file as string and pass it to less-loader, which also return a string.

@jbazinga
Copy link
Author

Yes, I know it, and I use the same config, what you mentioned, but this is still not working!

@zarkosusnjar
Copy link

Besides what @asafyish mentioned In package.json you need deps:

"less": "^2.5.3",
"less-loader": "^2.2.1",

Then in component itself I use:

const STYLES  = require('!raw!less!./dashboard.less');

@View({
  styles:     [ STYLES ],
  template: `<h1>Dashboard</h1>`
})

Cheers!

@PatrickJS
Copy link
Owner

@jbazinga
Copy link
Author

Thanks a lot, updated the issue text with the final solution.

@manavsehgal
Copy link

Opened #199 to consolidate these issues.

@matthewlsawyer
Copy link

I found an issue with the raw-loader loading less styles into a component. Images, references by the less source via a url will not be resolved by webpack.

For example, the component:

@Component({
    selector: 'test',
    template: require('./template.html'),
    styles: [require('./style.less')],
    directives: [...],
    pipes: [...],
    providers: [...]
})

And in style.less:

.my-background {
    background-image: url('./my-image.png');
}

Webpack config:

{test: /\.less$/, loader: 'raw-loader!less-loader'},
{test: /\.(png|jpg|gif)$/, loader: 'file-loader'}

The raw-loader will not try to resolve this url, that seems to be the responsibility of the css-loader. As far as I'm aware the css-loader doesn't work with angular components.

@SDohle
Copy link

SDohle commented Jun 30, 2016

I found an issue with the raw-loader loading less styles into a component. Images, references by the less source via a url will not be resolved by webpack.

Hi,
is this bug fixed? Or does anybody know a workaround for this problem?

@IvanBisultanov
Copy link

Hi, it's working for me with stylus&postcss.

package.json

    "autoprefixer": "^6.3.6",
    "stylus": "^0.54.5",
    "stylus-loader": "^2.1.1",
    "postcss-flexbugs-fixes": "^2.0.0",
    "postcss-gradient-transparency-fix": "^1.0.2",
    "postcss-loader": "^0.9.1"

webpack.common.js

var autoprefixer = require('autoprefixer');
var postcssFlexBugsFixes = require('postcss-flexbugs-fixes');
var postcssGradientTransparencyFix = require('postcss-gradient-transparency-fix');
{
        test: /\.css$/,
        loaders: ['to-string-loader', 'css-loader', 'postcss-loader', 'stylus-loader']
      },
postcss: function () {
    return [autoprefixer, postcssFlexBugsFixes, postcssGradientTransparencyFix];
  },

app.component.ts

  styles: [ require('!raw!postcss!stylus!./app.style.styl') ],

@matthewlsawyer
Copy link

matthewlsawyer commented Jun 30, 2016

I ended up writing my own loader for this, which is kind of a hack that extracts the raw css from the output of the css-loader.

I called it component-style-loaderand chained it with css-loader and less-loader so I get the desired functionality of url parsing via the css-loader.

{ test: /\.less$/, loader: 'component-style-loader!css-loader!less-loader' }

@tariknz
Copy link

tariknz commented Jul 19, 2016

@matthewlsawyer where can I find the component-style-loader? I'm stuck with this issue too.

@matthewlsawyer
Copy link

@tariknz I wrote it myself and we are currently using it at my company. Let me see if it is OK to open source it and I will respond here.

@tariknz
Copy link

tariknz commented Jul 19, 2016

@matthewlsawyer yeah that would be cool. I ended up using the ExtractTextPlugin but would be good to see how you did it.

@matthewlsawyer
Copy link

matthewlsawyer commented Jul 19, 2016

@tariknz @SDohle @bbottema I created a gist of the file we use. I created it by reverse engineering the output of the css-loader and converting it into a new export. If there is enough need of something like this I can publish on npm.

https://gist.github.com/matthewlsawyer/002d16d7d9295a9706a8c78198bc9376

@tariknz How did you use the ExtractTextPlugin to achieve this? I was under the impression that Angular2 scoped the css per component using data attributes on the DOM and injecting them into the css.

@tariknz
Copy link

tariknz commented Jul 21, 2016

@matthewlsawyer yeah you're correct it did create a global style-sheet for me by using this plugin. Which I'm still wondering if this an acceptable approach or not.

Used it here if you're interested: https://github.com/tariknz/wallofcolours

Thanks a lot for the gist.

@zaikin-andrew
Copy link

zaikin-andrew commented Aug 7, 2016

Hi guys.
Do you have any problem with @import other less files into component's less-file? Like variables?
If I use @import statement I have in browser console

Uncaught Error: Cannot find module "./menu.style.less"

Any idea?

@LeiwenL
Copy link

LeiwenL commented Aug 31, 2016

@zaikin-andrew Hi !
If you have these error maybe your path in your import isn't good. When I try to include for example my file "variable.less" with the @import, if the path is not correct, I have the same error !
Be careful to include @import "../../variable.less"; for example.

@zaikin-andrew
Copy link

@LeiwenL The issue was in mistake in the custom mixin into imported less file :) If loader can't compile a file it just doesn't give this file.

@watzon
Copy link

watzon commented Aug 31, 2016

Anyone know if there's a way to do this without the require('file.less')?

@watzon
Copy link

watzon commented Aug 31, 2016

Never mind I figured it out:

{
    test: /\.less$/,
    exclude: /node_modules/,
    loaders: ["raw-loader", "less-loader"]
}

and

@Component({
  selector: 'app',
  template: '<h1>My First Angular 2 App!!!</h1>',
  styleUrls: [ 'app.component.less' ]
})

@ndamnjanovic
Copy link

ndamnjanovic commented Sep 12, 2016

What if I have one import.less (outside component), and I want to compile it into single .css file?

Mentioned import.less has imports for every less file, like this:

import 'settings.less';
import 'variables.less';
import 'homepage.less';
import 'landing-page.less'

If I just use loader, add new entry point and extensions, I see that it gets compiled to css, but it is saved as .js file.

entry: {
   'polyfills': './src/polyfills.ts',
   'vendor': './src/vendor.ts',
   'main': './src/main.browser.ts',
   'css': './src/assets/less/import.less'
},
{
  test: /.less$/,
  exclude: /node_modules/,
  loader: 'raw-loader!less-loader'
}

I would like to have .css file. Is that possible?

@derricksimpson
Copy link

@ndamnjanovic Did you get it figured out? I would like to know this as well.

@ndamnjanovic
Copy link

ndamnjanovic commented Jan 27, 2017

@derricksimpson it was a while ago, but we didn't make it at the end. our designer is doing it separately, not sure if it's not possible, or we just didn't have enough knowledge at that time.

@JunkyDeLuxe
Copy link

Nobody had fixed this issue ?
styleUrls: ['./login.component.less'],

and in webpack
use: ['raw-loader', 'css-loader', 'less-loader']

Same error chrome "display Uncaught Error: Expected 'styles' to be an array of strings."

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

No branches or pull requests