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

when i import the css file in less file, vite would throw error:no found file,but if i change the .css into .less would no error #3293

Closed
Jeromy-L opened this issue May 7, 2021 · 17 comments · Fixed by #7147
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)

Comments

@Jeromy-L
Copy link

Jeromy-L commented May 7, 2021

Describe the bug

when i import css file in the less file, it would throw the error
image

Reproduction

repoduction:

https://github.com/Jeromy-L/test-vite/tree/test2

branch :test2

System Info

Output of npx envinfo --system --npmPackages vite,@vitejs/plugin-vue --binaries --browsers:

System:
    OS: macOS 11.1
    CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
    Memory: 118.15 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 12.18.3 - ~/.nvm/versions/node/v12.18.3/bin/node
    npm: 6.14.6 - ~/.nvm/versions/node/v12.18.3/bin/npm
  Browsers:
    Chrome: 90.0.4430.93
    Safari: 14.0.2

Used package manager:

Logs

4:18:49 ├F10: PM┤ [vite] Internal server error: Failed to find 'base.css'
  in [
    /Users/xxx/Documents/project/test-vite/client/views
  ]
  Plugin: vite:css
  File: /Users/xxx/Documents/project/test-vite/client/views/Test.vue?vue&type=style&index=0&lang.less
      at /Users/xxx/Documents/project/test-vite/node_modules/vite/dist/node/chunks/dep-8dd46f43.js:65:13
      at async Promise.all (index 0)
      at async LazyResult.runAsync (/Users/xxx/Documents/project/test-vite/node_modules/vite/node_modules/postcss/lib/lazy-result.js:358:11)
      at async compileCSS (/Users/xxx/Documents/project/test-vite/node_modules/vite/dist/node/chunks/dep-2c03f3f9.js:18942:27)
      at async TransformContext.transform (/Users/xxx/Documents/project/test-vite/node_modules/vite/dist/node/chunks/dep-2c03f3f9.js:18574:50)
      at async Object.transform (/Users/xxx/Documents/project/test-vite/node_modules/vite/dist/node/chunks/dep-2c03f3f9.js:43780:30)
      at async transformRequest (/Users/xxx/Documents/project/test-vite/node_modules/vite/dist/node/chunks/dep-2c03f3f9.js:59429:29)
      at async /Users/xxx/Documents/project/test-vite/node_modules/vite/dist/node/chunks/dep-2c03f3f9.js:59566:32
  vite:time 61ms  /client/views/Test.vue?vue&type=style&index=0&lang.less +13ms

@sodatea sodatea added bug p3-minor-bug An edge case that only affects very specific usage (priority) and removed pending triage labels May 7, 2021
@sodatea
Copy link
Member

sodatea commented May 7, 2021

Bug in Vite Less Plugin. Need to enable the relativeUrls option.

@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

Bug in Vite Less Plugin. Need to enable the relativeUrls option.

so what can i do to solve this problem?

@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

Bug in Vite Less Plugin. Need to enable the relativeUrls option.

i think i add the config into vite.config.js then will solve

css: {
    preprocessorOptions: {
      less: {
        relativeUrls: true,
      }
    }
  },

@sodatea sodatea added p2-edge-case Bug, but has workaround or limited in scope (priority) and removed p3-minor-bug An edge case that only affects very specific usage (priority) labels May 8, 2021
@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

Bug in Vite Less Plugin. Need to enable the relativeUrls option.

and i have a problem that why enable the relativeurls will make it work?

@sodatea
Copy link
Member

sodatea commented May 8, 2021

Not sure if it's a less bug, but here's my guess:

  1. Less treats @import URLs differently than other URLs, because it needs to know whether it's a less file (which needs to be compiled) or CSS file (which needs to be kept as-is)
  2. So when compiling the @import rule, it scans and then re-generates the URL.
  3. When CSS is used in the browser, base.css is equivalent to ./base.css (both are relative to the location of the stylesheet).
  4. So less chose the more concise version, base.css <- whether this step is a bug or feature will depend on how Less.js mainatiners see it
  5. Vite tries to resolve base.css, but as it's JavaScript-centric, it uses the resolution logic of Node.js, which does not consider base.css and ./base.css equivalent. So it can't find base.css. Thus the error.

Now we have two one ways to work around this issue:
1. The somehow pedantic way: use a different resolution algorithm for URLs in stylesheets and make it closer to the CSS spec;
2. The easy way: force Less to generate URLs starting with ./. That's why we need the relativeUrls option. Webpack less-loader also uses it.

@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

Not sure if it's a less bug, but here's my guess:

  1. Less treats @import URLs differently than other URLs, because it needs to know whether it's a less file (which needs to be compiled) or CSS file (which needs to be kept as-is)
  2. So when compiling the @import rule, it scans and then re-generates the URL.
  3. When CSS is used in the browser, base.css is equivalent to ./base.css (both are relative to the location of the stylesheet).
  4. So less chose the more concise version, base.css <- whether this step is a bug or feature will depend on how Less.js mainatiners see it
  5. Vite tries to resolve base.css, but as it's JavaScript-centric, it uses the resolution logic of Node.js, which does not consider base.css and ./base.css equivalent. So it can't find base.css. Thus the error.

Now we have to ways to work around this issue:

  1. The somehow pedantic way: use a different resolution algorithm for URLs in stylesheets and make it closer to the CSS spec;
  2. The easy way: force Less to generate URLs starting with ./. That's why we need the relativeUrls option. Webpack less-loader also uses it.

so if use ./base.less, doesn't it equivalent to base.less ?
and I am confused about the third point,i think vite node service solve the style , not in browser, doesn't it?
and the 5 points, why './base.less' no occur this problem?

@sodatea
Copy link
Member

sodatea commented May 8, 2021

i think vite node service solve the style , not in browser, doesn't it?

Less is quite an old project.

It can run in the browser and was originally designed to be used as a standalone tool. Compiled files are concatenated at most. So the default logic works well in the browser context.

@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

i think vite node service solve the style , not in browser, doesn't it?

Less is quite an old project.

It can run in the browser and was originally designed to be used as a standalone tool. Compiled files are concatenated at most. So the default logic works well in the browser context.

do you mean vite use less.js? not compile less file to css file?

@sodatea
Copy link
Member

sodatea commented May 8, 2021

Of course vite needs to call the less.js API to compile a less file.

I was just talking about why less equate base.css with ./base.css by default.
It's because they are equivalent in the browser. So when we use it in Node, we need to work around this behavior.
That's why relativeUrls is needed.

@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

i think vite node service solve the style , not in browser, doesn't it?

Less is quite an old project.

It can run in the browser and was originally designed to be used as a standalone tool. Compiled files are concatenated at most. So the default logic works well in the browser context.

and it seem work while I change the code

@import "./base.css";

into

@import url("./base.css");

@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

Of course vite needs to call the less.js API to compile a less file.

I was just talking about why less equate base.css with ./base.css by default.
It's because they are equivalent in the browser. So when we use it in Node, we need to work around this behavior.
That's why relativeUrls is needed.

image
Probably the document mentioned here
https://vitejs.dev/guide/features.html#css-pre-processors
but I am still confused about this description

@sodatea
Copy link
Member

sodatea commented May 8, 2021

That's why this issue is identified as a bug…

@sodatea
Copy link
Member

sodatea commented May 8, 2021

The documentation describes what the correct behavior should be and I'm here talking about why Vite failed to get the correct result.

@Jeromy-L
Copy link
Author

Jeromy-L commented May 8, 2021

The documentation describes what the correct behavior should be and I'm here talking about why Vite failed to get the correct result.

only enable the relativeUrls option can solve the problem, the other way not solve, so this should be the less bug? not the vite bug?

@sodatea

This comment was marked as outdated.

@sodatea

This comment was marked as outdated.

@sodatea
Copy link
Member

sodatea commented Mar 1, 2022

After further investigation, I think I got it wrong.
Vite did configure the CSS resolver correctly - it has a preferRelative option enabled.

And after a closer reading of the less documentation and source code, I think rewriteUrls: 'local' might be a better fix than relativeUrls: true.

@github-actions github-actions bot locked and limited conversation to collaborators Mar 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
p2-edge-case Bug, but has workaround or limited in scope (priority)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants