nuejs/nue

Support for passing options to LightningCSS

nobkd opened this issue · 5 comments

I want to support all browsers, but use some modern CSS features like light-dark(), which is currently only stable in Firefox.

This is a rule, that can get transpiled by lightningcss to be available in all browsers, if you set a target. E.g.: browser_targets: '>= 0.25%, last 2 versions, Firefox ESR, not dead'

(I'm willing to implement that, as I already have a working draft, that I would just have to clean up. It would add an option to the config, whose name+structure would need discussion)

Edit: Relevant part:

try {
const include = mod.Features.Colors | mod.Features.Nesting
return mod.transform({ code: Buffer.from(css), include, minify }).code?.toString()

  try {
    const targets = browser_targets ? mod.browserslistToTargets((await findModule('browserslist', 'index.js')).default(browser_targets)) : null
    const include = mod.Features.Colors | mod.Features.Nesting
    return mod.transform({ code: Buffer.from(css), include, minify, targets }).code?.toString()

Sounds good!

I have started thinking that Nue should support Lightning CSS natively, so it should be part of the dependencies. I think it's the best way to write CSS today. And having the ability to customize the supported features in the configuration would make sense, provided there are sane defaults. I think light-dark is a good default.

Is there a way to make a solid configuration system without adding "browserslist" as a hard dependency?

I'm not quite sure, how to do that. Also, my approach wasn't feature based, but browser variant/query specific...

For example, if I have this browserslist query:

>= 0.25%, last 2 versions, Firefox ESR, not dead

it creates this array containing all versions and browsers, that should be supported:

[
  "and_chr 121", "and_ff 122", "and_qq 13.1", "and_uc 15.5", "android 121", "chrome 122", "chrome 121",
  "chrome 120", "chrome 119", "chrome 118", "chrome 116", "chrome 109", "edge 121", "edge 120",
  "edge 119", "edge 87", "firefox 123", "firefox 122", "firefox 121", "firefox 115", "ios_saf 17.3",
  "ios_saf 17.2", "ios_saf 17.1", "ios_saf 17.0", "ios_saf 16.6-16.7", "ios_saf 16.3", "ios_saf 16.2",
  "ios_saf 16.1", "ios_saf 16.0", "ios_saf 15.6-15.8", "ios_saf 12.2-12.5", "kaios 3.0-3.1",
  "kaios 2.5", "op_mini all", "op_mob 73", "opera 106", "opera 105", "safari 17.3", "safari 17.2",
  "safari 17.1", "safari 16.6", "safari 15.6", "samsung 23", "samsung 22"
]

and lightningcss' browserslistToTargets converts it into a different variant, which seems to be used internally 🤷 (I think to determine which feature is available for what browser versions (e.g. here))

{
  and_chr: 7929856,
  and_ff: 7995392,
  android: 7929856,
  chrome: 7143424,
  edge: 5701632,
  firefox: 7536640,
  ios_saf: 786944,
  op_mob: 4784128,
  opera: 6881280,
  safari: 984576,
  samsung: 1441792,
}

In conclusion, I'm not quite sure how to do it, but I'll try looking into it, when I find the time.


We could also allow changing include, to enable / disable features.


PS: Have you seen this discussion: #211, primarily this comments: #211 (comment), #211 (comment)

My intuition says that browserlist is too complex and I'd like to go with feature detection only without that dependency. Not sure if that is possible, but to just list the things we want without the granular details might result to simplest outcome.

I'm going to go ahead and add Lightning as a hard dependency and depreciate any other option (Stylus, and my own proprietary pre-processor). On the dev branch soon.

It would probably be best, to just pass a lightning css config object and merge the two.
This could also allow browserslist target support.

Just not completely sure, if that works properly with the yaml file, as one might need js imports from lightning css / other modules.

Maybe similar to the POC marked config?