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

Struggling to add TailwindCss #32

Closed
fowlercraig opened this issue May 27, 2019 · 27 comments
Closed

Struggling to add TailwindCss #32

fowlercraig opened this issue May 27, 2019 · 27 comments
Labels
plugin New or existing plugins

Comments

@fowlercraig
Copy link

Following the directions in the Tailwind docs, I’ve tried adding the plugin declarations in slater.config.js, but it’s failing to compile properly.

It’s not throwing any errors, so I’m a little confused what’s going wrong.

@Jore
Copy link
Contributor

Jore commented May 28, 2019

Hey mate, could you share your slater.config.js?

@fowlercraig
Copy link
Author

fowlercraig commented May 28, 2019

const path = require('path')

module.exports = {
  themes: {
    development: {
      id: 'xxx',
      password: 'xxx',
      store: 'xxx.myshopify.com',
      ignore: [
        'settings_data.json' // leave this here to avoid overriding theme settings on sync
      ]
    }
  },
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
  ],
  assets: {
    presets: [
      'sass'
    ]
  }
}

Here are their docs: https://tailwindcss.com/docs/installation/

@estrattonbailey estrattonbailey added the plugin New or existing plugins label Jun 2, 2019
@chadmichaelwright
Copy link

Are there any updates on this issue? I greatly appreciate any info or resources that could point me in the right direction to get this functioning properly.

@fowlercraig
Copy link
Author

I've tried tweaking the presets file based on this thread for a quick/dirty fix, but no luck. Maybe someone else can try who's a bit smarter than I: #14

@chadmichaelwright
Copy link

Appreciate the effort and response. Will respond if I find a solution.

@tomaszbujnowicz
Copy link
Contributor

I also would like to use TailwindCSS but haven't found a simple way to add it to the project. @estrattonbailey hope you can help when you find a little while ;)

@curiouscrusher
Copy link

Has there been any movement on this issue?
Would love to use Tailwind or other css frameworks with this project in the future.

@jack-pallot
Copy link

I ran into this issue yesterday and also couldn't work out a way of adding it. Although, I think this forms part of a larger question about how assets should be handled in the future, and if it's worth revisiting options, since Slater is a relatively new project.

With Tailwind, for example, you ideally need to run Purge CSS to reduce the bundle size. All of the additional dependencies and nuances of having a totally extendable Webpack config could potentially be a bit of a support and documentation burden. It might be easier to go with something like Laravel Mix, as it's actively developed, documented, and covers 80% of common use cases.

If not, another option would be the ability to add plugins to the underlying Webpack config and to be able to adjust settings from slater.config.js. Again, while this should be possible, it means every config file has the ability to be different, making support more difficult.

@curiouscrusher
Copy link

@jack-pallot Definitely some good points.

I guess what it boils down to from my perspective is if Slater is going to be oriented at PostCSS life (which it is) then shouldn't there at least be support for (what seems like) a common feature?

I say this from camp SASS as I've only very recently begun looking at what PostCSS life looks like and how it can be leveraged. I'm currently using Slater in SASS mode since it just works better and can support the features necessary for building large-scale themes. However the utility based style of Tailwind and similar frameworks/methodologies is very appealing, especially from a maintenance perspective when you're dealing with multiple themes.

@estrattonbailey
Copy link
Member

Hey all, understand the frustration here. I'm a functional CSS person myself, and I've heard great things about Tailwind.

The main problem here is as @jack-pallot says: Tailwind appears to require some extra config. Another important thing to bring up is that the slater.config.js is not a Webpack or PostCSS config. It's an abstraction on top of both.

I started down the path of "plugins" (called presets atm), as you can see in the docs. Laravel Mix is a good comparison, though I wasn't aware of it when I was building the Slater setup. I've since taken that a step further with another of my libraries (WIP), which could also theoretically serve for easy extensibility.

The real short-term solution here is to dig into the code and learn how the Webpack config is modified. Have a look at the default PostCSS preset to understand. For Tailwind, I imagine someone could copy that file and extend it with Tailwind config. Then it would be as easy as adding to the Slater config file:

module.exports = {
  in: '/src/scripts/index.js'
  assets: {
    presets: [
      'tailwind'
    ]
  }
}

Open to any and all PRs :)

@jack-pallot
Copy link

I'm happy to take a look at getting a preset setup for Tailwind, no promises though, I'll see what I can do.

@curiouscrusher
Copy link

Thanks for the info @estrattonbailey!

I'm happy to dig into it as well if I can get some time, I definitely love working with Slater.
I'm still new to PostCSS so just learning how all the pieces fit together.

@rafaelderolez
Copy link

Has anyone had any luck with this so far? I found this repo (shopify-tailwind-vue) and tried to replicate it but couldn't manage to make it work.

@curiouscrusher
Copy link

@rafaelderolez from my end, due to project priorities I moved back to working from Slate v1, which actually is super easy to add Tailwind to with ~ 5 lines in the config.

@jack-pallot
Copy link

I spent quite a while trying to add a new preset but ultimately couldn't get it to work. I ended up writing a sass equivalent of utilities instead which will work for this particular project. I might revisit at some point because I'm planning to add Purge CSS to my build, but I can't guarantee I'll get any further with it.

@estrattonbailey
Copy link
Member

estrattonbailey commented Nov 21, 2019

Hey all. Understand the troubles, this isn't easy stuff to configure, let alone configure inside a monorepo like this.

Try this. From a slater initialized theme (if you don't have one, run npx slater init /path/to/project):

npm i slater@tailwind @slater/compiler@tailwind --save-dev

Then in your slater.config.js file, specify the tailwind preset:

module.exports = {
  // ... normal config
  assets: {
    presets: [ 'tailwind' ]
  }
}

For those curious, this is what the preset looks like.

Edit: for visibility, CC @tomaszbujnowicz @jack-pallot @curiouscrusher @rafaelderolez @fowlercraig ✌️

@tomaszbujnowicz
Copy link
Contributor

I couldn't make that work together - probably made some mistake somewhere.

Anyway, wanted to have more control over TailwindCSS and PurgeCSS integration.
I took the theme itself, integrated it with TailwindCSS and PurgeCSS. Rewrited the markup so it works with Tailwind CSS class names and here we go:

https://github.com/tomaszbujnowicz/shopify-slater-tailwindcss

I know that it probably doesn't really make sense in the long run but needed to have the TailwindCSS setup ready asap as the new project is on the table. Have fun, maybe someone will find that useful ;)

@n-kort
Copy link
Contributor

n-kort commented Jan 31, 2020

error ./src/styles/main.css 1:0
Module parse failed: Unexpected character '@' (1:0)
You may need an appropriate loader to handle this file type, ...

@estrattonbailey just get this error after adding slater@tailwind etc

@n-kort
Copy link
Contributor

n-kort commented Feb 27, 2020

Looked into this a bit more, and realized that assets.presets[] also accepts functions. So, rather than modifying the compiler I just changed my slater.config.js to this:

const path = require('path')
const ExtractCSS = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')

function tailwindConf ({ config, watch }) {
  config.module.rules.push({
    test: /\.css$/,
    exclude: /node_modules/,
    use: [
      ExtractCSS.loader,
      require.resolve('css-loader'),
      {
        loader: require.resolve('postcss-loader'),
        options: {
          plugins: [
            require('postcss-import'),
            require('tailwindcss'),
            require('postcss-nested'),
            require('postcss-preset-env')({
              stage: 0
            }),
            require('autoprefixer')
          ]
        }
      }
    ]
  })

  config.plugins = config.plugins.concat([
    new ExtractCSS({
      filename: '[name].css'
    }),
    watch && new OptimizeCssAssetsPlugin({
      cssProcessor: require('cssnano'),
      cssProcessorPluginOptions: {
        preset: ['default', { discardComments: { removeAll: true } }],
      },
    })
  ].filter(Boolean))

  return config
}

module.exports = {
  themes: {
    development: {
      id: '...',
      password: '...',
      store: '....myshopify.com',
      ignore: [ 'settings_data.json' ]
    }
  },
  assets: {
    presets: [ tailwindConf ]
  }
}

Remember to npm i -D those postcss plugins along with tailwind.

In the entry CSS file (or anywhere else) you can then use @tailwind, @apply etc etc and it'll pick up the tailwind.config.js in the root.

This creates quite a large CSS file of course, so I add PurgeCSS as a postbuild step.

@iamkevingreen
Copy link
Member

@n-kort I have merged this in, anyone else in the tailwind world feel free to let us know if this worked.

@dong-qian
Copy link

Hi, first, thanks for this awesome tool. I have a question on how to purge tailwindcss on a production build. After I run yarn build. I can see the whole tailwindcss was in the build/assets/index.css. Anything I missed?

@n-kort
Copy link
Contributor

n-kort commented Jun 12, 2020

@qiandongyq easiest is just to use the purge settings in tailwind.config.js:

  purge: {
    enabled: true,
    content: [
      './src/**/*.liquid',
      './src/**/*.js'
    ]
  }

enabled: false if you only want it it for production.

@m-w-d-d
Copy link

m-w-d-d commented Jun 12, 2020

@qiandongyq - I recommend adding:

defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],

To @n-kort 's purge settings as that's helped with Shopify themes I've used Tailwind on.

@dong-qian
Copy link

@n-kort @m-w-d-d Thank you guys so much, it works like charm!!!

@fowlercraig
Copy link
Author

@n-kort Would you mind demonstrating how you're including purgecss?

@n-kort
Copy link
Contributor

n-kort commented Jun 24, 2020

@fowlercraig definitely simplest to use the above in your Tailwind config, but basically the same settings work in a purgecss.config.js file. Then just add a script to your package.json:

"purgecss": "purgecss -c ./purgecss.config.js -o ./build/assets"

The config file looks something like

module.exports = {
  defaultExtractor: content => content.match(/[\w-/:]+(?<!:)/g) || [],
  content: [
    './build/**/*.liquid',
    './build/assets/*.js'
  ],
  css: [
    './build/assets/*.css'
  ],
  whitelistPatterns: []
}

@joniler
Copy link

joniler commented Mar 3, 2021

Looked into this a bit more, and realized that assets.presets[] also accepts functions. So, rather than modifying the compiler I just changed my slater.config.js to this:

const path = require('path')
const ExtractCSS = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')

function tailwindConf ({ config, watch }) {
  config.module.rules.push({
    test: /\.css$/,
    exclude: /node_modules/,
    use: [
      ExtractCSS.loader,
      require.resolve('css-loader'),
      {
        loader: require.resolve('postcss-loader'),
        options: {
          plugins: [
            require('postcss-import'),
            require('tailwindcss'),
            require('postcss-nested'),
            require('postcss-preset-env')({
              stage: 0
            }),
            require('autoprefixer')
          ]
        }
      }
    ]
  })

  config.plugins = config.plugins.concat([
    new ExtractCSS({
      filename: '[name].css'
    }),
    watch && new OptimizeCssAssetsPlugin({
      cssProcessor: require('cssnano'),
      cssProcessorPluginOptions: {
        preset: ['default', { discardComments: { removeAll: true } }],
      },
    })
  ].filter(Boolean))

  return config
}

module.exports = {
  themes: {
    development: {
      id: '...',
      password: '...',
      store: '....myshopify.com',
      ignore: [ 'settings_data.json' ]
    }
  },
  assets: {
    presets: [ tailwindConf ]
  }
}

Remember to npm i -D those postcss plugins along with tailwind.

In the entry CSS file (or anywhere else) you can then use @tailwind, @apply etc etc and it'll pick up the tailwind.config.js in the root.

This creates quite a large CSS file of course, so I add PurgeCSS as a postbuild step.

I LOVE YOU @n-kort. Been beating my head against a wall all day getting Tailwind working and this was the ticket. I owe you a beer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
plugin New or existing plugins
Projects
None yet
Development

No branches or pull requests