maizzle / framework

Quickly build HTML emails with Tailwind CSS.
https://maizzle.com
MIT License
1.24k stars 49 forks source link

Support tailwindlabs/tailwindcss-jit #422

Closed holgerw closed 3 years ago

holgerw commented 3 years ago

Is it planned to generate minimal css with the new tailwindlabs/tailwindcss-jit instead of purging from the traditional huge set of Tailwind classes?

In my use case the files generated by Maizzle become templates consumed by another templating system (.eex / Elixir). As those .eex templates should be up to date during development on each edit, I do a maizzle build production of all templates on each save. For this use case it would be relevant to improve the build times with tailwindlabs/tailwindcss-jit.

I would be happy to contribute with a PR if you have a hint where to start.

cossssmin commented 3 years ago

We'll definitely add it as some point, JIT looks great and I can see many other benefits of using it in Maizzle.

However, it's still experimental so we'll need to wait for a (more) stable version, or until it gets into Tailwind core. Even then, it'll very likely be an option that your need to turn on in Maizzle, mainly because of the fact that you lose the ability to rapidly prototype in the browser (since you no longer have all classes generated).

jbtheard commented 3 years ago

JIT has just been added to Tailwind 2.1. I have used JIT on a react project and confirm the engine is fast enough to still prototype almost instantly.

cossssmin commented 3 years ago

Yes we'll definitely add support for it, just need a bit more time to make sure we don't break anything and that it works as expected.

cossssmin commented 3 years ago

Played a bit with this today and there's good news and bad news.

Good news is you can simply enable it yourself if using Tailwind CSS v2.1.0 or above:

module.exports = {
  mode: 'jit',
  purge: [
    'src/**/*.*',
  ],
}

Bad news is that core plugins are not disabled anymore. This is a showstopper for HTML email, because you'll get color classes with opacity variables like this:

.text-red-400 {
  --tw-text-opacity: 1;
  color: rgba(248, 113, 113, var(--tw-text-opacity));
}

CSS variables have poor support in email, so this means your CSS colors will not work in some of the most important email clients, like Gmail, Outlook, or Yahoo!

I've opened https://github.com/tailwindlabs/tailwindcss/issues/4071, let's wait and see what the team says.

cossssmin commented 3 years ago

A workaround for using JIT while developing locally, but falling back to AOT when building for production, would be to enable JIT based on NODE_ENV:

module.exports = {
  mode: process.env.NODE_ENV === 'local' ? 'jit' : 'aot',
  purge: [
    'src/**/*.*',
  ],
}

However this won't work right away, because we're not setting process.env.NODE_ENV in the to-disk generator correctly. Will take care of that right now and publish a patch.

cossssmin commented 3 years ago

Released v3.3.1 so you can now use the workaround explained above.

cossssmin commented 3 years ago

Using Tailwind's own purging has now been implemented in #432, and we'll soon publish a new release.

Remember, to use JIT you will (currently) need to:

  1. enable it only for maizzle serve or maizzle build (and not for any other environment, because of https://github.com/tailwindlabs/tailwindcss/issues/4071)
  2. also specify the purge option in your tailwind.config.js, in simplified array syntax (it throws an error and Maizzle build hangs if you omit it or set it to an object, see https://github.com/tailwindlabs/tailwindcss/issues/4094)

Example:

module.exports = {
  mode: process.env.NODE_ENV === 'local' ? 'jit' : 'aot', // all `maizzle build` commands that specify an environment name will use 'aot'
  purge: [
    'src/**/*.*',
  ],
  // ...
}
cossssmin commented 3 years ago

Another way of using JIT only when developing locally is to specify a custom Tailwind config object for your production builds:

// tailwind.config.js

module.exports = {
  mode: 'jit',
  purge: [
    'src/**/*.*',
  ],
  // ...
}
// config.production.js

const omit = require('lodash/omit')

// Remove 'mode' and 'purge' keys from Tailwind config in production
const twconfig = omit(require('./tailwind.config'), ['mode', 'purge'])

module.exports = {
  build: {
    tailwind: {
      config: twconfig,
    },
  // ...
}

This way you rely on your Maizzle config files instead of the NODE_ENV, if that matters.

Using this myself in a project with >50 emails where for some reason having purge: ['src/**/*.*'] in tailwind.config.js slows down the build incredibly. Removing the purge key brings things back to normal by defaulting to Maizzle's purge settings:

https://github.com/maizzle/framework/blob/87e73bbd56c547688dba79dcc807acc8081be1c9/src/generators/tailwindcss.js#L22-L29

Note: as mentioned in my previous comment, we currently can't use object syntax for purge if using mode: 'jit'.