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

Component Framework global components are not correctly loaded when using pug + scoped style #138

Open
7 tasks done
Shinigami92 opened this issue Jul 28, 2022 · 3 comments

Comments

@Shinigami92
Copy link
Member

Describe the bug

With Quasar I'm using the @quasar/vite-plugin v1.1.1 and the plugin property autoImportComponentCase: 'pascal'
When using this in combination with a template lang=pug and style scoped I get warnings and a blank white page with no rendered content.

At Quasar Land (Discord) we (@yusufkandemir, @patak-dev and me) already found out that there is a new incompatibility coming from @vitejs/plugin-vue >= v3 and that the template also gets applied a scoped query param where as when not using pug it does not.

image https://discord.com/channels/415874313728688138/902518756436226079/1002122942852902964

image https://discord.com/channels/415874313728688138/902518756436226079/1002127704138715176


Current workaround:
Using a css class named like the component and use that instead of scoped keyword.

Reproduction

https://stackblitz.com/edit/vitejs-vite-llrb6t?file=src%2FApp.vue,package.json,src%2Fmain.ts,vite.config.ts&terminal=dev

System Info

System:
    OS: macOS 12.4
    CPU: (10) arm64 Apple M1 Max
    Memory: 4.91 GB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.4.0 - ~/.nvm/versions/node/v18.4.0/bin/node
    npm: 8.12.1 - ~/.nvm/versions/node/v18.4.0/bin/npm
  Browsers:
    Chrome: 103.0.5060.134
    Safari: 15.5
  npmPackages:
    @vitejs/plugin-vue: ~3.0.1 => 3.0.1 
    vite: ~3.0.3 => 3.0.3

Used Package Manager

pnpm

Logs

No response

Validations

@yusufkandemir
Copy link

The value of the autoImportComponentCase doesn't affect the behavior. (as long as you match it in your code of course)

Also, let me move over my text from Discord to here so that it's more readable and copyable.

If you use scoped css but not pug, it still works.

For some reason, when you pug and scoped css at the same time, the template also gets &scoped=... in the resource URL. And, the regex targeting the template can't match it, so the auto-loading gets disabled on that template.

HTML + Regular SCSS:
template: http://localhost:5173/src/App.vue
style: http://localhost:5173/src/App.vue?vue&type=style&index=0&lang.scss

HTML + Scoped SCSS:
template: http://localhost:5173/src/App.vue
style: http://localhost:5173/src/App.vue?vue&type=style&index=0&scoped=7a7a37b1&lang.scss

Pug + Regular SCSS:
template: http://localhost:5173/src/App.vue?vue&type=template&lang.js
style: http://localhost:5173/src/App.vue?vue&type=style&index=0&lang.scss

Pug + Scoped SCSS:
template: http://localhost:5173/src/App.vue?vue&type=template&scoped=7a7a37b1&lang.js
style: http://localhost:5173/src/App.vue?vue&type=style&index=0&scoped=7a7a37b1&lang.scss

The solution is to update to regex to allow it, but the question is whether this behavior of Vite is intended or not.

https://github.com/quasarframework/quasar/blob/bb44635a8e97210937eb3539968a6b6aa37ae778/vite-plugin/src/vue-transform.js#L6

export const vueTransformRegex = /\.vue(?:\?vue&type=(?:template|script)(?:&setup=true)?&lang\.(?:j|t)s)?$/

When using Pug + Scopes SCSS, if it's intended for the template resource query to also get scoped, I'll update the regex above to allow it. Do you know if it's intended?

Also, by any chance, do you know if there is a more future-proof solution than just doing this in our Vite plugin:

transform (src, id) {
  if (vueTransformRegex.test(id) === true) {
    return {
      code: vueTransform(src, opts.autoImportComponentCase),
      map: null // provide source map if available
    }
  } else if // ...

or perhaps loosen up the regex, or have a better way of following the changes on this kind of stuff? Any input is welcome!

@sapphi-red
Copy link
Member

the question is whether this behavior of Vite is intended or not.

This is intended. When lang or src attribute is not defined on <template>, it is inlined in the main request. So the URL ends with .vue.
https://github.com/vitejs/vite/blob/cd69358177dd3d93bc19084ad0ee09f6b85c047c/packages/plugin-vue/src/main.ts#L253-L255
When using pug, it is not inlined and scope=$id was added for build --watch (vitejs/vite#7989).
When the template is inlined in the main request, this is not needed. So pug one includes scoped=7a7a37b1 but html one does not include it.

do you know if there is a more future-proof solution than just doing this in our Vite plugin

I think doing something similar to this would be more future-proof.
https://github.com/vitejs/vite/blob/cd69358177dd3d93bc19084ad0ee09f6b85c047c/packages/plugin-vue/src/index.ts#L180-L197

const f = id => {
  if (id.endsWith('.vue')) return true

  const { query } = parseVueRequest(id)
  return (
    query.vue &&
    (query.type === 'script' || query.type === 'template')) &&
    ('lang.ts' in query || 'lang.js' in query)
  )
}

@patak-dev
Copy link
Member

@sapphi-red I wonder if plugin-vue should export some utilities to handle these cases. It could be easier to change internals later

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

No branches or pull requests

4 participants