Skip to content
This repository has been archived by the owner on Mar 18, 2021. It is now read-only.

Gridsome: dynamic class bindings not working [Purging issue] #14

Open
tonyketcham opened this issue Feb 22, 2021 · 2 comments
Open

Gridsome: dynamic class bindings not working [Purging issue] #14

tonyketcham opened this issue Feb 22, 2021 · 2 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@tonyketcham
Copy link

tonyketcham commented Feb 22, 2021

Describe the problem

In Gridsome, the following code is not working as expected (where isFalse equals false):

 <h2
   class="mb-2 text-4xl font-medium"
   :class="[isFalse ? 'text-gray-50' : 'text-gray-700']"
 >

You'd expect text-gray-700 to be applied in this case, however, the element just inherits the parent text color without applying the class. I tried in both compiled and interpreted modes with rebuilding the app and clearing browser cache but was met with unstable behavior where about 1 in 10 times the dynamic class would be applied.

How I've installed WindiCSS

// gridsome.config.js
...
  configureWebpack: (config) => {
    config.module.rules.push({
      test: /\.vue$/,
      use: [
        {
          loader: 'vue-windicss-preprocess',
          options: {
            config: 'tailwind.config.js', // tailwind config file path OR config object (optional)
            compile: true, // false: interpretation mode; true: compilation mode
            globalPreflight: true, // set preflight style is global or scoped
            globalUtility: true, // set utility style is global or scoped
            prefix: 'windi-', // set compilation mode style prefix
          },
        },
      ],
    });
  },
...

Browser: Brave - Version 1.20.103 Chromium: 88.0.4324.152 (Official Build) (64-bit)

Semi-workaround

Using vue-windicss-preprocess in combination with gridsome-plugin-tailwindcss makes dynamic class bindings work just fine. I haven't found any issues with that setup besides when trying to use the windi/plugins, which spits out a bunch of errors where it's searching for functions in tailwind and PostCSS instead of Windi CSS, leading to the app not building.
UPDATE: trying to reproduce this from scratch, the gridsome-plugin-tailwindcss now isn't working alongside Windi as a workaround

@voorjaar voorjaar added enhancement New feature or request good first issue Good for newcomers labels Feb 22, 2021
@tonyketcham
Copy link
Author

tonyketcham commented Feb 22, 2021

Diving deeper, I'm pretty sure this is a class purging problem. If you have compile: false and a certain class is declared only once in your app, in the dynamic class binding, it gets incorrectly purged from the build when it should be included. If you use a class in a dynamic binding and that class has been declared elsewhere in the regular class attribute, then it works. But for example, if the only time text-gray-700 is declared in your app is in that dynamic class binding, it gets purged. If compile: true, it doesn't matter if you have the class declared elsewhere, it gets purged 100% of the time.

I encountered a similar issue when configuring Tailwind for Sapper a while back and adding this defaultExtractor to the purge options of the Tailwind config was the solution:

// considers dynamic class bindings when purging unused classes
// credit: https://github.com/matebek https://dev.to/matebek
defaultExtractor: (content) => [
  ...(content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []),
  ...(content.match(/(?<=class:)[^=>\/\s]*/g) || []),
],

@voorjaar I'd be happy to help in any way I can. Could you point me in the direction of where I should look at applying something similar to that defaultExtractor under the hood?

@tonyketcham tonyketcham changed the title Gridsome: dynamic class bindings not working Gridsome: dynamic class bindings not working [Purging issue] Feb 22, 2021
@voorjaar
Copy link
Member

Diving deeper, I'm pretty sure this is a class purging problem. If you have compile: false and a certain class is declared only once in your app, in the dynamic class binding, it gets incorrectly purged from the build when it should be included. If you use a class in a dynamic binding and that class has been declared elsewhere in the regular class attribute, then it works. But for example, if the only time text-gray-700 is declared in your app is in that dynamic class binding, it gets purged. If compile: true, it doesn't matter if you have the class declared elsewhere, it gets purged 100% of the time.

I encountered a similar issue when configuring Tailwind for Sapper a while back and adding this defaultExtractor to the purge options of the Tailwind config was the solution:

// considers dynamic class bindings when purging unused classes
// credit: https://github.com/matebek https://dev.to/matebek
defaultExtractor: (content) => [
  ...(content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || []),
  ...(content.match(/(?<=class:)[^=>\/\s]*/g) || []),
],

@voorjaar I'd be happy to help in any way I can. Could you point me in the direction of where I should look at applying something similar to that defaultExtractor under the hood?

I think this method is not what I want. We have an htmlparser for parsing vue's grammar, and currently the directive is not supported. Add some directive support, it should be fine.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

2 participants