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

Updated Proposal - Options file for Less.js #1893

Closed
matthew-dean opened this issue Feb 21, 2014 · 4 comments
Closed

Updated Proposal - Options file for Less.js #1893

matthew-dean opened this issue Feb 21, 2014 · 4 comments

Comments

@matthew-dean
Copy link
Member

Passing structured options to Less within a file has previously been discussed in #850 and #1134 (along with other various issues like plugins). My intent is to pick up that work from there (and close those issues) and hope to simplify and clarify where those left off in a single thread, to get us closer to implementation.

So, the goals of an options or settings file are:

  • Enable a way to load plugins
  • Be able to "set" options in a way that supports team development (checking into source code)
  • Make configuration of Less easier
  • Make configuration of Less consistent across platforms

Note: Whether or not Less.js will auto-load the less settings file should be a separate issue. This is just focused on syntax / usage.

Based on discussion in #850 and #1134, the final format is JSON (#1134 started as an inline "less" format, but there are technical and logistical challenges with that approach).

@jonschlinkert did more work to explore the possibilities of the format, so we'd start with something like this, similar to #1134.

Basic usage

{ 
  options: {
    paths: "",
    rootpath: "",
    relativeUrls: "false",
    strictImports: "false",
    compress: "false",
    yuicompress: "true",
    silent: "false",
    lint: "false",
    color: "true"
  }
}

Project (root-file)-level options

It's conceivable that a team might want separate options for separate .less files (in the same working directory), but want to manage one options file. This can be easily managed.

{ 
  options: {
    relativeUrls: false,
    strictImports: false,
    compress: false
  },
  files: {
    "mobile.less": {
      css: "../css/mobile.css",  //not required, but useful in teams
      options: {
        relativeUrls: true,
        compress: true
      }
    },
    "desktop.less": {
      css: "../css/desktop.css",
      sourceMap: "desktop.map",
      options: {
        relativeUrls: false,
        compress: false
      }
    }
  }
}

Root-level "options" applies globally. File-level options override globals. Unspecified options adopt default options (as they do now). Note that if "desktop.less" @imports "mobile.less" within the "desktop.less" file, the "mobile.less" options will not apply. Options apply only when that file is the "root" of the compiled project (and it would be illogical to have a file that is partially compressed and partially uncompressed, for example), with the exception of plugins (explanation follows).

Loading Less API plugins

Plugin loading follows the same pattern of global / file-specific declarations:

{
  plugins: ["../js/less-plugin-colors.js", "../js/myLessPlugin-postgresql.js"] 
  options: { },
  files: {
    "bootstrap.less": {
      css: "../css/bootstrap.css",
      plugins: ["bootstrap/js/custom-less-functions.js"]
    }
  }
}

In the above case, unlike other options, plugins are not "overridden", but instead both global and local plugins would load for the "bootstrap.less" project. Also, unlike other options, plugins would load if "bootstrap.less" is loaded with @import in another file. This allows library authors to use plugins, even if the library is not the "root" of the project.

Context-based (grouped) options

Based on @jonschlinkert's work, the JSON settings can contain "switches" for options, so that option "groups" can be saved and turned off/on.

{
"production": { 
  options: {
    compress: "true"
  },
"dev": { 
  options: {
    compress: "false"
  },
}

Usage could be something like this:

lessc --options "production"

If the root of the options file contains switches, and none are specified, the compiler would select the first one for compiling options (in this case, "production").

Variable overrides / context switching

The options file can also pass variable "overrides" into the less file, similar to @jonschlinkert's context() proposal, but without introducing new Less syntax. The reason is best demonstrated by example:

{
"production": { 
  options: {
    compress: "true"
  },
  vars: {
    "@mode": "production"
  }
"dev": { 
  options: {
    compress: "false"
  },
  vars: {
    "@mode": "dev"
  }
}

// in myproject.less
@mode: "";  // default value is overridden by Less options

.box() when (@mode = "dev") {
  &:after {
    content: 'This site is in development.'
  }
}

So, I think that covers 99% of the options files requirements as we've listed so far. Please provide feedback on syntax and/or discussion on something else needed here (ideally backed up by an already-listed issue), or if there's anything here we don't need. Thanks.

@matthew-dean
Copy link
Member Author

@less/admin

@jonschlinkert
Copy link
Contributor

Great start for discussion, thanks!

@matthew-dean
Copy link
Member Author

To update this, I realized that it doesn't declare all use cases for declaring plugins, since importing external libs would still be difficult to configure for average users if those libs used plugins. So, in addition, I'd add that it would be good to do @rjgotten's idea, from issue #1861:

@import (plugin) "../plugins/my-plugin.js";

As @rjgotten notes, that would allow transparent uptake of a plugin in a really simple way. I wouldn't replace anything above, as I think centralized configuration is good and the preference for other authors; we should just support both.

@stale
Copy link

stale bot commented Nov 14, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Nov 14, 2017
@stale stale bot closed this as completed Nov 28, 2017
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

2 participants