sveltejs / svelte-preprocess

A ✨ magical ✨ Svelte preprocessor with sensible defaults and support for: PostCSS, SCSS, Less, Stylus, Coffeescript, TypeScript, Pug and much more.
MIT License
1.73k stars 147 forks source link

CompileError [ParseError]: :global() must contain a selector #613

Open lewispham opened 9 months ago

lewispham commented 9 months ago

Describe the bug I'm using stylus as the css preprocessor. This syntax is no longer working and throwing an error instead. It looks like the processed code does not add the necessary brackets for keyword :global.

:global
    div
        display block
    p
         display inline-block

Logs

    '5: \n' +
    '6: <style lang="stylus">:global div,\n' +
    '                        ^\n' +

To Reproduce Try the above code

Expected behavior No error occurs.

Stack trace Stack trace goes here...

Information about your project:

Additional context It used to work.

andy0130tw commented 9 months ago

I also ran into this bug earlier this day. Tried downgrading this plugin (4.x ~ 5.0.3) and Svelte (3.x) but have no success. For anyone looking into this issue, I created a minimal reproduction.

https://stackblitz.com/edit/svelte-preprocess-global-fail

The dependencies are:

  {
    "@sveltejs/vite-plugin-svelte": "^2.4.6",
    "postcss": "^8.4.30",
    "sass": "^1.68.0",
    "svelte": "^4.2.0",
    "svelte-preprocess": "^5.0.4",
    "vite": "^4.4.9"
  }

And the Vite config:

export default defineConfig({
  plugins: [
    svelte({
      preprocess: [
        vitePreprocess({style: false}),
        /* add minimal preprocessors for demonstrating the bug */
        sveltePreprocess.scss(),
        sveltePreprocess.globalStyle(),
      ]
    }),
  ],
})
andy0130tw commented 9 months ago

I trace down the source code, and the issue is caused by the following lines in src/processors/globalStyle.ts:

if (!attributes.global) {
  return { code: content };
}

Literally, it skips the entire transformation if the style tag is not marked as global. Historically, the global styles feature of this preprocessor only supported global blocks, so it sounded logical. This is no longer correct if we need to support :global selectors inside the style body.

Also notice that the test suite does not cover this processor. Although the transformer behaves correctly, it is not run at all.

A quick solution is to remove the lines listed above. But beware that the transformation then runs through every style tag even if it does not contain any relevant selector, which impacts the performance.