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

Importers #1392

Closed
ghost opened this issue Jun 29, 2013 · 7 comments
Closed

Importers #1392

ghost opened this issue Jun 29, 2013 · 7 comments

Comments

@ghost
Copy link

ghost commented Jun 29, 2013

I've just created a ticket on the Ruby bindings repo here cowboyd/less.rb#65 but thinking that the issue may come down to Less itself.

Less assumes that @import statements should look for a file on the filesystem, which is not always the case for example when their content is stored in a database.

Sass has the notion of 'Importers' (http://sass-lang.com/docs/yardoc/Sass/Importers.html), does Less have anything like this? ...otherwise it's a case of hacking up something to catch the filesystem calls and reroute them which is a horrible solution.

A much cleaner solution would be:

var parser = new(less.Parser)({
  importer: function(filename) {
    return db.findMyFile(filename);
  },
  filename: 'style.less' // Filename, for better error messages
});

parser.parse('@import("from-bd.less"); p { .a-mixin; }', function (e, tree) {
  tree.toCSS({ compress: true });
});
@matthew-dean
Copy link
Member

Yep. You can write a file importer exactly as you describe by overriding the less.Parser.importer function. You'll notice in the browser build that the browser environment does just that.

However, that behavior is not currently consistent or centralized for all types of file operations. For instance, the data-uri handler assumes a Node file environment and does not have any of the same kinds of hooks as @import statements.

Moving forward, LESS will (hopefully) eventually have a more graceful environment plugin model that allows you to handle file operations however you wish.

@ghost
Copy link
Author

ghost commented Jul 5, 2013

@matthew-dean Shouldn't this ticket remain open? As you say, the behaviour is not consistent or centralised.

@matthew-dean
Copy link
Member

Sorry for the delay. As far as your specific issue, writing a file importer is possible today. But I agree, there are places where there is a file request that doesn't actually use the same file import method. Reopening.

@matthew-dean matthew-dean reopened this Dec 15, 2013
@jonschlinkert
Copy link
Contributor

I think this is a good call. agreed that this would be useful

@matthew-dean
Copy link
Member

Btw, if this helps, Crunch currently has an importer that looks like this:

less.Parser.importer = function(path, paths, callback, env) {
        var entryPath = (paths.entryPath && paths.entryPath != "")
            ? paths.entryPath : env.rootpath;
        var file = Paths.project.resolvePath(entryPath).resolvePath(path);

        // Adopted from the Node.js implementation
        if(file.exists) {
                var fileStream = new air.FileStream();
                fileStream.open(file, air.FileMode.READ);
                var fileData = fileStream.readUTFBytes(fileStream.bytesAvailable);
                fileStream.close();

                new (less.Parser)({
                    rootpath: env.rootpath,
                    relativeUrls: false,
                    filename : file.nativePath
                }).parse(fileData, function(e, root) {
                        callback(e, root, fileData);
                });
        } else {
                if( typeof (env.errback) === "function") {
                        env.errback.call(null, path, paths, callback, env);
                } else {
                        callback({
                                type : 'File',
                                message : "'" + file.nativePath + "' wasn't found.\n"
                        }, env.rootpath, file.nativePath);
                }
        }

};

You can create your importer, and basically do whatever you want in that operation. And then you just return the fileData to the callback.

@matthew-dean
Copy link
Member

I should note that this importer was originally based on an older version of LESS when the API / callback / error-handling structure was all very different (although updated and somewhat tested with 1.5.1), so please don't take it as a best example. I'd love it if @lukeapage reviewed this.

@lukeapage
Copy link
Member

You can now use less and plugin your own file manager which can handle file system calls.

http://lesscss.org/usage/#developing-less-how-to-run-less-in-other-environments

This was finished in v2.

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

3 participants