These are chat archives for less/less.js

3rd
Dec 2015
Matthew Dean
@matthew-dean
Dec 03 2015 00:04
@zephraph The best person to ask is Luke Page, since he did the visitor rewrite.
Zephraph
@zephraph
Dec 03 2015 00:05
I think I have a good handle on things now.
Matthew Dean
@matthew-dean
Dec 03 2015 00:06
The lack of a documented Less API is not ideal.
Zephraph
@zephraph
Dec 03 2015 00:06
Indeed.
I actually wrote a postcss plugin for part of my asset pipeline just because the barrier of entry to writing a less plugin was so high.
I'm more comfortable with it now, but it was very much a trial by fire scenario.
Matthew Dean
@matthew-dean
Dec 03 2015 00:07
I'm currently working on a Less-to-PostCSS plugin (for PostCSS).
Zephraph
@zephraph
Dec 03 2015 00:08
I really like postcss, but I'm hesitant to try to port any of our actual code over to it just because of how fragmented it would be.
With that being said, less' lack of good linting utilities is extremely problematic.
Matthew Dean
@matthew-dean
Dec 03 2015 00:09
All I did was figure out just where a evaluated Less AST was generated, and hooked into that. Then I'm iterating through the Less AST and converting them to PostCSS nodes.
PostCSS only has like, what, 4 or 5 node types?
So, basically, you designate Less as the parser, and also include less as a plugin.
Zephraph
@zephraph
Dec 03 2015 00:10
Something like that... Sounds exciting.
Matthew Dean
@matthew-dean
Dec 03 2015 00:10
Which then outputs a PostCSS tree, with which you can do anything.
Zephraph
@zephraph
Dec 03 2015 00:11
Like hook into stylelint!
Matthew Dean
@matthew-dean
Dec 03 2015 00:11
Sure.... exceeeept.... this is an evaluated tree. Meaning it's a CSS AST, not a LESS AST
Zephraph
@zephraph
Dec 03 2015 00:11
Ahh, well, that's a big except.
Matthew Dean
@matthew-dean
Dec 03 2015 00:12
Hmm. Well, what other way would there be to do it?
Zephraph
@zephraph
Dec 03 2015 00:12
Stylelint has support for scss.
Matthew Dean
@matthew-dean
Dec 03 2015 00:13
I think if you wanted to Lint Less, then that would be a Less plugin, not a PostCSS one
Zephraph
@zephraph
Dec 03 2015 00:13
Right, agreed, that would definitely be a good way to do it.
Matthew Dean
@matthew-dean
Dec 03 2015 00:13
All that would need to change is to pass the un-evaluated AST to plugins.
Zephraph
@zephraph
Dec 03 2015 00:13
It's either write a parser to work with a pre-existing linter or write a linter.
Matthew Dean
@matthew-dean
Dec 03 2015 00:14
But.... isn't a linter checking for bad less code? So.... how would linting help if Less had already rejected it?
Zephraph
@zephraph
Dec 03 2015 00:14
Heh, that isn't the point at all.
well, it could be.
But that's not what I want to use it for.
Matthew Dean
@matthew-dean
Dec 03 2015 00:15
I don't use linters much. How would it work?
Zephraph
@zephraph
Dec 03 2015 00:15
A good linter helps enforce code quality.
For example, say that your organization decided that there should be no elements nested more than 3 layers deep.
Or perhaps you don't want nesting period.
A linter could help you enforce that.
We use eslint internally for a similar purpose with javascript.
Matthew Dean
@matthew-dean
Dec 03 2015 00:16
In the case of Less, though, the original code is, I think, stripped once it's converted to a node.
But.... it wouldn't necessarily have to be. You could store raw input with the node just like PostCSS's raws.
Isn't that what you would need?
Zephraph
@zephraph
Dec 03 2015 00:17
I assume, yes.
Matthew Dean
@matthew-dean
Dec 03 2015 00:18
Hmm.....
Zephraph
@zephraph
Dec 03 2015 00:19
I was going to go the route of extending postcss' parser with a custom tokenizer and just use stylelint as a basis for building rules.
Matthew Dean
@matthew-dean
Dec 03 2015 00:19
Most of Less's API wasn't "designed". That is, much of it only kinda exists an API just because there was a decision to expose everything on the "less" object. Plugins were more directly designed, but not a lot of changes happened to existing functions.
Zephraph
@zephraph
Dec 03 2015 00:20
Heh, yeah, there's definitely some room for improvement.
Matthew Dean
@matthew-dean
Dec 03 2015 00:21
Well, how about doing that on postcss-less? If you can create a custom PostCSS parser that has an AST that is a representation of Less's AST (but PostCSS style), then there should be a way to directly create Less nodes based on that. Basically the reverse of what I've done.
Because then you wouldn't have to make the postcss-less plugin first. You could essentially put the linter first (or anything else), and the postcss-less would basically transform the PostCSS nodes to Less nodes, process those into CSS, and then convert the Less AST output to PostCSS.
If postcss-less worked, I was thinking that could be a future step anyway, to have the plugin anywhere in the PostCSS stack. Because then, at THAT point, there's no need for Less's Plugins (Type A), and you could just use Less's Type B Plugins, which are still quite useful.
(That is: inline @plugin "newfunctions" definitions)
Zephraph
@zephraph
Dec 03 2015 00:24
I haven't seen those.
Matthew Dean
@matthew-dean
Dec 03 2015 00:24
@zephraph No one has lol. They haven't been documented yet.
Zephraph
@zephraph
Dec 03 2015 00:25
Well, I've been down in the nitty gritty of less code too, I just didn't notice it.
Matthew Dean
@matthew-dean
Dec 03 2015 00:25
Basically, you can create custom functions, and those functions follow Less's scoping rules.
Zephraph
@zephraph
Dec 03 2015 00:25
Interesting.
Matthew Dean
@matthew-dean
Dec 03 2015 00:26
So that, if you are the author of a Less library, you can create Less plugins via code. And those just work for everyone without them needing to "initialize" or "install" a plugin.
They work by default.
Zephraph
@zephraph
Dec 03 2015 00:26
So they just @import them?
Matthew Dean
@matthew-dean
Dec 03 2015 00:30
No. Took me forever to find the relevant PRs -
less/less.js#2479
less/less.js#2522
The original proposal was @import (plugin), but was settled with the cleaner @plugin "plugin.js"
There's an open call for documentation at: less/less-docs#328
I think plugins Type A (I'm just calling them that, they're not diffentiated), should be deprecated and just support Type B (with @plugin)
Zephraph
@zephraph
Dec 03 2015 00:32
Aside from not having to do any manual work to get this installed, what does it give me the ability to do?
Matthew Dean
@matthew-dean
Dec 03 2015 00:32
And for anything more advanced, move to third-party plugin systems (a la PostCSS)
Well, I think at the moment, it really just gives the ability to add custom functions.
so that you can do: { blah: custom(val1, val2, val3); }
with custom being whatever name of the function you define
Zephraph
@zephraph
Dec 03 2015 00:33
I see. That's definitely useful, but I don't think that really negates the need for the type A plugins.
Matthew Dean
@matthew-dean
Dec 03 2015 00:34
no, but if there were a solid postcss-less plugin, I don't see why they would be needed
Since Less pre and post-processing plugins do similar things to PostCSS, just with a much more difficult and undocumented API.
That said, the other way to solve it is just to develop a sane Less API.
Zephraph
@zephraph
Dec 03 2015 00:35
So, sure, I see your point about post-processing. But what about visitor plugins that let you do things that need to be done before anything is processed?
Like, I just wrote a plugin that looks for @api: test test1 test2 and creates variables @test, @test1, etc that are set to some default value.
Matthew Dean
@matthew-dean
Dec 03 2015 00:36
That's true. I guess if it's not just simple AST conversion, and you want to more intricately manipulate Less nodes, there's value in it.
Hmm, then what about a simpler Less API?
Zephraph
@zephraph
Dec 03 2015 00:38
I'd be totally in favor of that, haha.
Let me post my plugin to github and I'll link you to it.
Matthew Dean
@matthew-dean
Dec 03 2015 00:38
It's open source. If you want it, then you're the person for the job. ^_^
Zephraph
@zephraph
Dec 03 2015 00:39
Heh, well I'm going through the middle of a pretty significant refactor effort at work so I doubt I have the time to dedicate to it.
We are somewhat dedicated to Less though.
Sass just isn't dynamic enough.
So I'm definitely invested in seeing it thrive.
The plugin itself isn't really finished, but yeah, I thought it was interesting.
I'm working on a theming system at work so I needed a way to define a ruleset that would just be removed if it wasn't used.
So I'll have a stylesheet that will have like @fontSize: null at the top and a { font-size:@fontSize } later in the file. In between those two parts I import a theme file with specific variables in it.
After it's all generated out I use a postcss plugin that I wrote to strip out any values that are null.
That way, I can define a pretty fully featured "visual api", but not bloat the final stylesheets with values that I don't need.
The define api plugin is to remove the need for me to write @variable: null; over and over and over at the start of the file.
Zephraph
@zephraph
Dec 03 2015 00:51
Instead all I do is write @api: fontSize borderRadius headerFont etc.
If less actually supported null values like sass did I wouldn't have had to go through that much trouble >_>. But, it wasn't so bad.
Learned a lot about postcss in the process.
Matthew Dean
@matthew-dean
Dec 03 2015 01:20
It seems like there should be a better way.
Zephraph
@zephraph
Dec 03 2015 01:20
Haha, yeah, you're telling me.
Matthew Dean
@matthew-dean
Dec 03 2015 01:22
what about a conditional detached ruleset?
seems strange to want to remove a variable
Zephraph
@zephraph
Dec 03 2015 01:23
Are you familiar with semantic-ui?
Matthew Dean
@matthew-dean
Dec 03 2015 01:24
A bit
Zephraph
@zephraph
Dec 03 2015 01:24
Well, we're using a very similar setup as far as how we structure things.
We have this idea of definition files. All it does is define the things that you can style via variables.
The thing is, not all of our brands will need to use every single definition, right?
For example, one brand puts a border on their headline text, but none of the others do at this point.
So for the brand that uses it all they have to do is set @headlineBorder to whatever.
But the other brands don't have border in the final stylesheet at all.
If every brand got the defaults for everything there would be a massive amount of bloat.
We've got like 6 huge sites running off all this, heh, so not including what isn't needed is highly important.
But so is giving everyone the ability to use whatever they want.
Matthew Dean
@matthew-dean
Dec 03 2015 03:19
The way I've solved that in the past is the reverse concept. I start out with a set of components that are activated by variables. So, by default, nothing is added. Then, setting components to "true" includes that component in the output.