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

fix(less): always use root file as base when resolving id #17857

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

smeng9
Copy link
Contributor

@smeng9 smeng9 commented Aug 10, 2024

Description

Closes #13143

Since we called the rebaseUrls functions to rebase everything to the root file,
Next time when we use resolvers.less we must also pass the root file instead of the current dir.

Copy link

stackblitz bot commented Aug 10, 2024

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@smeng9
Copy link
Contributor Author

smeng9 commented Aug 10, 2024

Still needs a test case

@smeng9 smeng9 marked this pull request as draft August 10, 2024 05:07
@smeng9 smeng9 marked this pull request as ready for review August 10, 2024 14:13
const resolved = await resolvers.less(filename, path.join(dir, '*'))
const resolved = await resolvers.less(filename, rootFile)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct? The filename should always be resolved from the file that imports it, not the rootFile. The problem I'm seeing is that Less is treating @import url() weirdly.

With @import url('../../less/ommer.less'); in the test, the filename becomes less/ommer.less. But with @import '../../less/ommer.less';, filename becomes ../../less/ommer.less.

I think we need to figure out why this happens first.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it doesn't look like the test fails in main. When Vite fails to resolve it, it'll fallback to Less to load it itself (super.loadFile), and it'll work again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference between @import url('../../less/ommer.less'); and @import '../../less/ommer.less'; is the first one gets everything in url() rebased, the second one does not get rebased.

Also what do you mean

it doesn't look like the test fails in main.

Do you want to make vite resolve it instead of falling back to less?

The test case without the fix indeed fails in main when called with pnpm run test-build
Screenshot 2024-08-14 at 3 34 30 PM

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case without the fix indeed fails in main when called with pnpm run test-build

My bad looks like it does. I was running the playground manually and seeing that the text was darkorange even without this PR's changes.

Do you want to make vite resolve it instead of falling back to less?

Ideally Vite should always be able to resolve it yes.

However after the import in line 2535 we rebased the url to the rootfile. Do you mean we should rebase the file to the current file instead of rootfile? Then next time the file name will be relative to the file that imports it instead of relative to the root file.

I think I see the issue now. I didn't expect rebaseUrls to be the culprit, but that function should really not rebase any urls related to @import ""; and @import url("") (seems to start from #7147). The goal of rebaseUrls is to make sure the url() or data-uri() would still reference the correct file path as that reference will be left as is after compiling to a single file.

@import is different because they don't get left in that single file, their contents are bundled instead, unless it's importing an external URL, data URL, or something, but in that case you wouldn't need to rebase it either.

Maybe I'm missing something, but if what I'm getting is correct. The fix is to remove this:

// fix css imports in less such as `@import "foo.css"`
if (hasImportCss) {
rebased = await rewriteImportCss(content, rebaseFn)
}

and update this to not capture @import url(:

export const cssUrlRE =
/(?<=^|[^\w\-\u0080-\uffff])url\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/

I'm not sure if this would break other tests, feel free to let me know though if the issue/fix is getting overwhelming and I can help make a fix too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tested the different fix you suggested but it seems breaks the original test case from #7147

@smeng9
Copy link
Contributor Author

smeng9 commented Aug 14, 2024 via email

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

Successfully merging this pull request may close these issues.

less use @import url() When this style file also imported by other files, an error will be reported
2 participants