vercel / next.js

The React Framework
https://nextjs.org
MIT License
123.07k stars 26.3k forks source link

CSS @import doesn't work on remote URL when imported from another file #59330

Open lancejpollard opened 7 months ago

lancejpollard commented 7 months ago

Link to the code that reproduces this issue

https://github.com/textsurf/tune.land/tree/7900104fe0932ce8780b0c26985f95b6a492d97b

To Reproduce

Have an app which loads stylesheets like this:

// main.css
@import('./foo.css')
@import('./bar.css')
// foo.css
.hello-world {
  background: red;
}
// bar.css
@import url('https://fonts.googleapis.com/css2?family=Noto+Kufi+Arabic:wght@400%3B700&family=Noto+Sans+Armenian:wght@400%3B700&family=Noto+Sans+Bengali:wght@400%3B700&family=Noto+Sans+Canadian+Aboriginal:wght@400%3B700&family=Noto+Sans+Cuneiform&family=Noto+Sans+Devanagari:wght@400%3B700&family=Noto+Sans+Egyptian+Hieroglyphs&family=Noto+Sans+Ethiopic:wght@400%3B700&family=Noto+Sans+Georgian:wght@400%3B700&family=Noto+Sans+Gujarati:wght@400%3B700&family=Noto+Sans+Gurmukhi:wght@400%3B700&family=Noto+Sans+Hebrew:wght@400%3B700&family=Noto+Sans+JP:wght@400%3B700&family=Noto+Sans+KR:wght@400%3B700&family=Noto+Sans+Kannada:wght@400%3B700&family=Noto+Sans+Khmer:wght@400%3B700&family=Noto+Sans+Malayalam:wght@400%3B700&family=Noto+Sans:wght@400%3B700&family=Noto+Sans+Mono:wght@400%3B700&family=Noto+Sans+Oriya:wght@400%3B700&family=Noto+Sans+Runic&family=Noto+Sans+SC:wght@400%3B700&family=Noto+Sans+Sinhala:wght@400%3B700&family=Noto+Sans+Syriac&family=Noto+Sans+Tamil:wght@400%3B700&family=Noto+Sans+Telugu:wght@400%3B700&family=Noto+Sans+Thai:wght@400%3B700&family=Noto+Serif+Tibetan:wght@400%3B700&display=swap');

Add this to _app.tsx:

import '~/styles/main.css'

Current vs. Expected behavior

Current behavior

Current behavior is for the remote import to be injected in the middle of the file, after the contents of foo.css, so you get this error message in the Chrome dev inspector:

Define @import rules at the top of the stylesheet
An @import rule was ignored because it wasn't defined at the top of the stylesheet. Such rules must appear at the top, before any style declaration and any other at-rule with the exception of @charset and @layer.

Screenshot 2023-12-06 at 4 17 21 AM

Expected behavior

The @import should probably be hoisted up to the beginning of the final generated CSS file.

The only workaround is to either put these imports in <link> tags in the _document.tsx head, or to have a imports.css and put all your remote imports in that, and include that first in the _app.tsx. But those seem like hacks, and makes it hard to have reusable CSS files/modules defined in libraries which themselves reference remote CSS stuff. For example, my UI library references CSS fonts and katex stuff and some other remote stuff, and then I load it in my Next.js app with @import '@mylib/styles/x.css, and that itself has remote imports buried deep. So somehow this should work.

Verify canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.1.0: Mon Oct  9 21:32:11 PDT 2023; root:xnu-10002.41.9~7/RELEASE_ARM64_T6030
Binaries:
  Node: 18.16.0
  npm: 9.5.1
  Yarn: 1.22.19
  pnpm: 8.10.0
Relevant Packages:
  next: 13.5.6
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 4.9.5
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure

Additional context

In the link I provided, remove the line at _document.tsx where I add the google font. Locally, it works when loading from the remote import, but in production it doesn't work, and the font is missing b/c of that error in the image I showed above.

Gc-Peanut commented 7 months ago

我也遇到了同样的问题

Gc-Peanut commented 7 months ago

fetchFontFile 是否可从本地加载字体 在使用 import { Noto_Sans_HK } from "next/font/google" 的时候,生产环境因网络问题无法下载字体导致不生效