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

CSS optimisations #2936

Closed
Inqnuam opened this issue Feb 19, 2023 · 4 comments
Closed

CSS optimisations #2936

Inqnuam opened this issue Feb 19, 2023 · 4 comments

Comments

@Inqnuam
Copy link

Inqnuam commented Feb 19, 2023

Hello @evanw
Is is possible to deduplicate and move all @import and @font-face rules to the top of css bundle as you do with @charset?

@evanw
Copy link
Owner

evanw commented Feb 19, 2023

Please provide an example of what you want the input and output to be. There isn't enough information here to know what you mean.

@Inqnuam
Copy link
Author

Inqnuam commented Feb 19, 2023

// index.ts
import "./style1.css";
import "./style2.css";
import "./style3.css";
/* style1.css */
@charset "utf-8";
@import url("https://fonts.googleapis.com/css?family=Oswald:300,400,700");
@import url(https://fonts.googleapis.com/css?family=Roboto:400,500);

@font-face {
  font-family: "VeraSeBd";
  src: url(https://mdn.github.io/css-examples/web-fonts/VeraSeBd.ttf);
}

.class1 {
  height: 909px;
}
/* style2.css */
@charset "utf-8";

@font-face {
  font-family: "VeraSeBd";
  src: url("https://mdn.github.io/css-examples/web-fonts/VeraSeBd.ttf");
}

.class2 {
  width: 300px;
}
/* style3.css */
.class3 {
  color: red;
}
@import url(https://fonts.googleapis.com/css?family=Roboto:400,500);

Current css bundle output

@charset "UTF-8";
@import "https://fonts.googleapis.com/css?family=Oswald:300,400,700";
@import "https://fonts.googleapis.com/css?family=Roboto:400,500";

/* style1.css */
@font-face {
  font-family: "VeraSeBd";
  src: url(https://mdn.github.io/css-examples/web-fonts/VeraSeBd.ttf);
}
.class1 {
  height: 909px;
}

/* style2.css */
@font-face {
  font-family: "VeraSeBd";
  src: url(https://mdn.github.io/css-examples/web-fonts/VeraSeBd.ttf);
}
.class2 {
  width: 300px;
}

/* style3.css */
.class3 {
  color: red;
}
@import url(https://fonts.googleapis.com/css?family=Roboto:400,500);

Excepted/optimised output

@charset "UTF-8";
@import "https://fonts.googleapis.com/css?family=Oswald:300,400,700";
@import "https://fonts.googleapis.com/css?family=Roboto:400,500";

/* style1.css */
@font-face {
  font-family: "VeraSeBd";
  src: url(https://mdn.github.io/css-examples/web-fonts/VeraSeBd.ttf);
}
.class1 {
  height: 909px;
}

/* style2.css */
.class2 {
  width: 300px;
}

/* style3.css */
.class3 {
  color: red;
}

@evanw
Copy link
Owner

evanw commented Feb 20, 2023

The problem you're having with the @import rule is because your @import is invalid. Bundling it with esbuild gives the following warning:

▲ [WARNING] All "@import" rules must come first [invalid-@import]

    style3.css:5:0:
      5 │ @import url(https://fonts.googleapis.com/css?family=Roboto:400,500);
        ╵ ~~~~~~~

  This rule cannot come before an "@import" rule

    style3.css:1:0:
      1 │ .class3 {
        ╵ ^

Moving it up to the top of the file where it should be fixes your problem for me, so you should make that change on your end. That's not something that esbuild should fix itself. Invalid @import rules in the input should remain invalid @import rules in the output, otherwise the unbundled and bundled CSS renderings would be different, which would be a bug with esbuild.

The @font-face rules appear to not be deduplicated because they contain an external url() reference and esbuild treats two external references as unequal. That should be something that esbuild can fix. When that's fixed, multiple duplicate @font-face rules should be collapsed into a single rule.

@evanw evanw closed this as completed in 47e54fe Feb 20, 2023
@Inqnuam
Copy link
Author

Inqnuam commented Feb 20, 2023

Awesome!
Thank you!

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

No branches or pull requests

2 participants