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

Support file globbing for @imports #1181

Closed
jonschlinkert opened this issue Feb 13, 2013 · 70 comments
Closed

Support file globbing for @imports #1181

jonschlinkert opened this issue Feb 13, 2013 · 70 comments

Comments

@jonschlinkert
Copy link
Contributor

See: https://github.com/isaacs/node-glob,
and https://github.com/isaacs/minimatch https://github.com/jonschlinkert/micromatch

I use these often in projects. It would be pretty awesome to be able to do the following and not have to specify individual files:

@import "mixins/*.less";
@import "components/**/*.less"; 

After only a few minutes of using these patterns they become second nature. It might even help with some of the other import issues.


Implemented via plugin: less-plugin-glob.

@lukeapage
Copy link
Member

Cool.. though node only (not browser) and don't think it will help other
issues. Could be useful I guess.. usually you would have a dependency chain
so you wouldnt want everything in alphabetical order.

@matthew-dean
Copy link
Member

Yeah, no way for the browser to know what files to request, so it seems like a non-starter.

@lukeapage
Copy link
Member

well I wouldn't rule it out just because it would only apply for node but also I don't see it as a particularly important feature request.

@jonschlinkert
Copy link
Contributor Author

@agatronic regarding the dependency chain, I was just talking to someone about that same thing at the node meetup yesterday. I think this is something that is useful for component/module libraries, mixins etc. as in the example. And yeah node only was what I was thinking.

@lukeapage
Copy link
Member

I just read that stylus allow you to specify a directory and if you do that it looks for a index.sty - I like that.

as for importing every file in a directory, its only really useful if the files only contain mixins (no content).. because order matters. not sure thats a real-life scenario right now?

@jonschlinkert
Copy link
Contributor Author

I like the index idea. That's a good way to do it.

its only really useful if the files only contain mixins (no content).

We use a lot of component-based development. Most of our Less components have zero dependency on other files. Of course order does matter in CSS and with more traditional design patterns, so I think you're right. Most people probably wouldn't use this the way I would - which mean they wouldn't use it all probably. But the stylus index idea is an interesting solution to this.

@jonschlinkert
Copy link
Contributor Author

This isn't a priority but I just saw this and wanted to add it as a reference: https://github.com/chriseppstein/sass-globbing

@josephspens
Copy link

I'm a huge Sass fan, and I use Chris Eppstein's glob importing plugin all the time (teammates who were on windows machines couldn't use it, so keep that in mind).

I've been looking for an equivalent in LESS, anyone see anything like it?

@jonschlinkert
Copy link
Contributor Author

Yeah I'm a fan of this plugin for sure. I think anyone who has used globbing knows how nice it is to work with, but it's one of those things that seems "nice to have" until you actually use it. I can't imagine trying to do builds without it now. You can use assemble-less, it supports globbing (I'm one of the maintainers of it...)

@jonschlinkert
Copy link
Contributor Author

Btw @josephspens I created this project yesterday for converting SASS to LESS. As a proof-of-concept, I converted the .scss files from bootstrap-sass and foundation to LESS, both examples are in the ./test/ folder. I was actually surprised at how close I got to converting all of the Bootstrap .scss files back to LESS. Try doing a diff between the converted sass files and "native" bootstrap less files (v2.3.1) - it's not feature complete, but it saves a lot of time.

If you do end up having to use LESS on a project, this might be worth checking out. For some language features, it shouldn't be hard to reverse the process to convert LESS to SASS

@jonschlinkert
Copy link
Contributor Author

@lukeapage, you mentioned here #1181 (comment) that this would only be useful for mixin libs, and that was true at the time.

However, now that we have @import (reference), this feature will be useful for every stylesheet that can be referenced.

Also, I thought about the index.less concept and created a request for it: #1339. But I don't think these features are mutually exclusive or even necessarily related. Globbing allows for both include and exclude patterns, so you have a lot of control from the globbing patterns in the import statement itself.

I think the index.less feature would solve an entirely difference challenge, which is more like defining dependencies - really useful for modules, components, themes etc.

@lukeapage
Copy link
Member

@jonschlinkert I agree

@jonschlinkert
Copy link
Contributor Author

@lukeapage can you give me a head-start on which places in the code need to be modified (beyond tree/import/.js?), or suggestions for what I need to consider, e.g. should this be specific to node, etc.? I might give it shot.

@danielchatfield
Copy link
Contributor

This would be a great feature. I currently have a great big long list of stylesheets in my bundle.less file:

@import 'pages/home';
@import 'pages/login';
@import 'pages/404';
//etc

It would be useful to condense this into:

@import 'pages/*';

or similar.

danc86 added a commit to beaker-project/beaker that referenced this issue May 7, 2014
Admins can (either by hand, or in a separate RPM) overwrite the
site.less symlink to point at their own custom Less rules, which will be
included with Beaker's Less sources when generating CSS.

Ideally this would just be a config option of extra filenames which are
appended to the 'css' assets bundle. Unfortunately that doesn't work
because webassets compiles each Less source file separately, which
prevents the site Less rules from overriding or cross-referencing the
Beaker ones.

In future Less might support @import globs [1] which would allow us to
@import site rules from a defined directory. But until then we have to
do this ghost symlink hackery.

[1] less/less.js#1181

Bug: 1012224
Change-Id: I86f6d6987fd66988a46ec7372bbc3a249f015b46
@timmolendijk
Copy link

Stylus allows you to do this -- @import 'partials/*.styl -- and I was using it all the time. Would be very interested in having this in Less as well, to alleviate me from the tedious task of manually bookkeeping imports.

@braco
Copy link

braco commented Oct 29, 2014

This + explicit import + non-duplicates would be really handy:

// Import specific file
@import "extras/specific.less"
// Import all others, specific file is skipped in this glob
@import "extras/*.less"

@jonschlinkert
Copy link
Contributor Author

@lukeapage I'd like to do a plugin for this, can you give me some pointers on where to start? thx

@lukeapage
Copy link
Member

Sorry Jon that I missed your first request for help, it wasn't intentional.
I think we might be best putting it in core (because a plugin would want to
override standard node file access - and you could inherit and implement
but that stops another plugin from building on top of it, unless they are
very careful), anyway I'd at least add support to core for import ing
multiple files from one import. It's possible today, the new bower plugin
does it, but it's a little bit hacky. Will be in touch.

@jonschlinkert
Copy link
Contributor Author

Ha, I didn't realize I had already commented, so that makes two of us lol. no worries at all I know how it is.

might be best putting it in core

Sounds good. I'd be happy to help with that too. No worries either way.

@lukeapage
Copy link
Member

Ok, been thinking and this is how I'd do it.

  1. Add a expandToFilelist to abstract file manager. By default it should
    return an array containing the filename it's given. Not sure if it should
    be synchronous or asynchronous - probably doesn't matter - make it async?
  2. In import manager, call that function once you have a file manager. Then
    loop through all files and do on each what you were doing on 1.
  3. I'd have import manager wait till it had the results from all files
    before calling back to the call back (which is in import visitor) that way
    we can maintain a consistent ordering. The call back would now take an
    array containing all the arguments (e.g full filename must be received once
    per file).
  4. There might be complications in import visitor around the context - not
    sure
  5. An import will now take an array of roots (or maybe an array of roots
    and filenames). It will need to eval all roots in its eval function and
    return a combined root.. or maybe create a new rulesets using an array of
    the evald roots, if that works
  6. Compile and test - should all work
  7. Change node file manager to implement expandToFilelist if the filename
    contains *
  8. Add tests and add tests to the excludes in the Jasmine section of the
    gruntfile, since we cannot implement for browser
    Voila!

@tracker1
Copy link

tracker1 commented Nov 6, 2014

Just wanted to comment, as a workaround, you could use gulp with gulp-concat if you're using gulp as your build tool.

gulp.src([
    'src/styles/main.less'
    ,'src/controls/**/*.less`
])
.pipe(concat('bundle.less')
.pipe(less())
...

This is effectively my directory structure... (though, my structure is a little different). I was hoping this was a built-in feature, as even if node-only would be very useful.

@vmadman
Copy link

vmadman commented Nov 17, 2014

Just thought I'd +1 here... its a pretty common pattern. There's also several easy workarounds for avoiding the order problem.

@just-boris
Copy link

@vospascal answered in my repo

@vospascal
Copy link

;) thnx @just-boris i saw :-) 👍

@srph
Copy link

srph commented Apr 9, 2015

Still waiting for this feature 👍 . Thanks, @just-boris.

@solovets
Copy link

@just-boris thanks! В смысле, спасибо :-)

@michaelbromley
Copy link

This would be a very useful feature for me, since I prefer to bundle all my components in once place, rather than having all Less files in a single location. This leads to Less files existing all over the place, which would be a nightmare to maintain a manual list of imports for.

For anyone using Gulp to build their Less files, I've had success using the gulp-inject plugin to automatically create the @import statements in my main Less file. I did a short write-up of it here: http://www.michaelbromley.co.uk/blog/425/automatic-import-of-lesssass-files-with-gulp

@equinusocio
Copy link

For globbing in less you can simple simple run this in your project,

npm install less-plugin-glob --save-dev

then add this to your Gruntfile in the options group of your less task

plugins: [require('less-plugin-glob')]

The result is something like this:

···
options: {
    compress: true,
    yuicompress: true,
    optimization: 2,
    cleancss: true,
    sourceMap: false,
    sourceMapFilename: 'css/maps/style.css.map',
    plugins: [require('less-plugin-glob')]
},
···

Now in your .less file you can write this:

···
@import "commons/**/*";
@import "basic/**/*";
···

@cody-greene
Copy link

Came here wondering if glob imports were supported, but since I'm using a couple of one-liner shell scripts instead of grunt/gulp for my build process. I ended up just using find & cat and my source stays cleaner than any of the alternatives. Less continues to be awesome.

# src/index.less + src/foo/bar.less + ... = dist/index.css
find -X src -type f -name '*.less' | xargs cat | lessc - | cleancss --s0 >dist/index.css

@egeste
Copy link

egeste commented Jun 2, 2015

+1

@davidcalhoun
Copy link

Really surprised this hasn't happened by now. Gulp has support for this feature at least.

@seven-phases-max
Copy link
Member

@davidcalhoun Read the first post in this thread.

@AddoSolutions
Copy link

Same, as far as I am aware, most people are compiling their LESS files into CSS , I don't know of many sites that are having the browser interpret the LESS directly? For those that wish to debug, can use source maps

@SpencerCarstens
Copy link

@just-boris I can't get your plugin to work... I assume I'm doing something wrong.

Has anyone else gotten it to work?

Not getting any errors... just no output when I try to use globbing.

gulp.task( 'styles', () => {
  return gulp.src( [ 'app/styles/main.less' ] )
    .pipe( $.less( {
      plugins: [ require( 'less-plugin-glob' ) ],
    } ) )
    .pipe( gulp.dest( 'dist/styles' ) );
} );
// main.less
// Each line below is tried on it's own of course.
@import "app/module/waffle.less"; // Works
@import "app/module/**"; // Does not work.
@import "app/module/**/*"; // Does not work.
@import "app/module/**/*.less"; // Does not work.

@seven-phases-max
Copy link
Member

@SpencerCarstens It's better to raise the issue at the plugin own repository.

@SpencerCarstens
Copy link

@seven-phases-max 👍

I was hoping to reach a greater audience, but you are right.

@equinusocio
Copy link

@seven-phases-max You can't integrate the glob-plugin inside less?

@SpencerCarstens
Copy link

It integrates fine, but doesn't seem to do anything.

If I comment out the plugin, my less correctly errors on the import
globing.

When I put it back in, the error stops.

So, I assume it's doing something.

On Wednesday, August 5, 2015, Mattia Astorino notifications@github.com
wrote:

@SpencerCarstens https://github.com/SpencerCarstens You can't integrate
the glob-plugin inside less?


Reply to this email directly or view it on GitHub
#1181 (comment).

Cordially,

Spencer Carstens

@seven-phases-max
Copy link
Member

@equinusocio

You can't integrate the glob-plugin inside less?

If you mean "why to not put this into the core"... Then, well, the current Less approach (less or more set up in several discussions across various threads here) is roughly: "never put a feature to the core, before it becomes absolutely and totally evident the feature belongs there and there's no other ways". That is, if something can be implemented as a plugin it should be implemented as a plugin (that's why for example even long-living-in-the-core clean-css facility was moved from the core to the corresponding plugin).

@equinusocio
Copy link

@seven-phases-max ok, thanks. I like this.

@matthew-dean
Copy link
Member

matthew-dean commented Mar 4, 2016

Closing as implemented in @just-boris 's plugin.

@Julyanvdham
Copy link

+1

1 similar comment
@satodu
Copy link

satodu commented Nov 22, 2017

+1

@quantuminformation
Copy link

Talk about resurrecting old threads

@matthew-dean
Copy link
Member

What are these +1's supposed to indicate? Is the plugin not workable?

@Julyanvdham
Copy link

The +1 indicates that you want or support it too

@matthew-dean
Copy link
Member

Support what? That's what I'm saying. This has been addressed and the issue is closed. So I'm asking what is being +1'd?

@davidxd33
Copy link

I've been getting these emails for over 2 years what's the deal here..

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

No branches or pull requests