Re: [csswg-drafts] [CSS Import Once] @import-once, or some syntax for importing a stylesheet only once (#6130)

> Can you give more detailed examples where vanilla CSS could have been more re-usable and modular but that this was prevented by this specific aspect of `@import`?
> 
> I feel like there is some step or aspect that I am missing.



> I don't think we can say : "tools do this, so it's needed".
> I think it needs to be demonstrated on it's own why it would be useful.

It is no accident! To reproduce the main problem with today's `@import`, try making `a.css`, `b.css`, and `c.css` where `b.css` depends on features (overrides things, or uses variables (in the future uses mixins and functions)) from `a.css`, and where `c.css` depends on `b.css`. Pretend these files are in a library call `css-lib` they installed locally.

Now, user needs features from `b.css`, so they *should* be able to write this:

```css
/*my-feature-1.css*/
@import '/node_modules/css-lib/b.css'

/* override things from b, use variables from b or a */
```

```css
/*some-page.css*/
@import './my-feature-1.css'
```

For now, it works fine. There's no problem yet.

Later, the user learns that they want to use feature `c` from `css-lib`, and they try to do that in another file:

```css
/*my-feature-1.css*/
@import '/node_modules/css-lib/b.css'

/* override or use things from b */
```


```css
/*my-feature-2.css*/
@import '/node_modules/css-lib/c.css'

/* override or use things from c */
```

```css
/*other-page.css*/
@import './my-feature-1.css'
@import './my-feature-2.css'
```

Now what the user did not realize while trying to modularize their code is that `b.css` is loaded _twice_ due to how `@import` currently works. This causes at least one problem:

If they try to use `my-feature-1.css` and `my-feature-2.css` on the same page, they'll get differing and potentially unexpected results depending on the order in which they imported `my-feature-1.css` and `my-feature-2.css`. The import of `c.css` in `my-feature-2.css` will undesirably _reset_ the overrides for `b.css` that the user defined in `my-feature-1.css`. Essentially, by writing two features, one that depended on `b`, and one that depended on `c`, and then trying to use both feaatures on the same page, the last feature *undid* the first feature!

Another problem is, in order to solve the above issue, `@import` statements have to be hoisted out of the files that depend on the things they depend on. Instead, the app author has to carefully `@import` all things separately, before running `my-feature-1` and `my-feature-2`. Essentially, there's no such thing as a module *graph* that will automatically resolve dependencies and run them in order.




Today's `@import` is more like a pre-processor that _includes_ the imported content inline (that's the behavior, at least, although technically at runtime there are separate sheets, but it is the behavior we're referring to).

Imagine if with JavaScript modules that multiple imports of the same `b.js` file resulted in multiple executions of `b.js`.

Imagine if with JS we did not get modules, but instead got `#include` which would simply include other files inline, and we'd still have to include all main scripts as non-module script tags. We'd be back in the C/C++ caves holding wooden clubs and trying to invent `#ifndef` again.

Basically the ask here is to have something more aligned with modern *modules* concepts and automatic dependency graph resolution, making it possible to easily modularize code and share libraries.

-----

Perhaps what we need is to start aligning with ES Modules. We already have CSS Modules. Maybe we could expand on that by adding new a new `import` feature behaves more like modules?

-- 
GitHub Notification of comment by trusktr
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/6130#issuecomment-1965827281 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 27 February 2024 05:41:04 UTC