tailwindlabs / tailwindcss

A utility-first CSS framework for rapid UI development.
https://tailwindcss.com/
MIT License
82.63k stars 4.18k forks source link

Rails (Webpacker) doesn't like this #3946

Closed wdiechmann closed 3 years ago

wdiechmann commented 3 years ago

What version of @tailwindcss/jit are you using?

v0.1.3

What version of Node.js are you using?

14.16.0

What browser are you using?

Chrome

What operating system are you using?

macOS 10.15.7

Reproduction repository

https://gist.github.com/wdiechmann/1a5baa91b880005c6a9edbcca938616f

Adam,

I'm in awe of the work you're doing - and a customer to TailwindUI which is brilliant!

Couldn't help but try out the new JIT - but as it turns out, my 'stack' doesn't quite tackle it too good 😢

You most certainly have bigger fish to fry - just wanted to let you know the work is appreciated!

/Walther

bvalentino commented 3 years ago

@wdiechmann try without postcss-preset-env. It's a known issue: https://github.com/tailwindlabs/tailwindcss-jit/issues/59 I have this tailwindcss-jit running fine in Rails 6 app with Webpack 4.44.2.

This is my postcss.config.js for reference:

module.exports = {
  plugins: [
    require('postcss-import'),
    require('@tailwindcss/jit')('./app/javascript/stylesheets/tailwind.config.js'),
    require('postcss-100vh-fix'),
    require('postcss-flexbugs-fixes')
  ]
}
wdiechmann commented 3 years ago

Hmm - this reminds me of DLL Hell back in '06 (which ultimately had me ditch Windoze for macOS)

hermes_1    | ERROR in ./app/javascript/stylesheets/application.scss (./node_modules/css-loader/dist/cjs.js??ref--4-1!./node_modules/postcss-loader/src??ref--4-2!./node_modules/sass-loader/dist/cjs.js??ref--4-3!./app/javascript/stylesheets/application.scss)
hermes_1    | Module build failed (from ./node_modules/postcss-loader/src/index.js):
hermes_1    | Error: PostCSS plugin postcss-100vh-fix requires PostCSS 8.
hermes_1    | Migration guide for end-users:
hermes_1    | https://github.com/postcss/postcss/wiki/PostCSS-8-for-end-users

Am I wrong to remember that Tailwind expressively asks for anything < PostCSS 8 with this

"tailwindcss": "npm:@tailwindcss/postcss7-compat"
dospuntocero commented 3 years ago

same happened to me, i'm using vue3 with a rails app, and i tested some variations, i have postCSS 8+ running and even that way the error says the same

nbelzer commented 3 years ago

After spending a few hours yesterday night trying to make this work I wanted to share the path I was able to follow to make this work in my Rails project, hopefully I can save someone else those hours.

As this project seems to require PostCSS 8 I started out upgrading my Rails 6.1 app to PostCSS 8 according to the instructions as outlined here (see the related commit for more details). As the guide there didn't get me all the way to a working version I decided to include a write-up of the steps I took.

  1. Upgrade webpacker to the latest version (I used v6.0.0-beta.6) both in your Gemfile and package.json
    
    # In your gemfile
    gem 'webpacker', '6.0.0.beta.6'

In your package.json

"@rails/webpacker": "^6.0.0-beta.6"

2. Make sure to install these new versions.
```bash
$ bundle install
$ yarn install

# If you didn't make any changes to the files mentioned you can
# overwrite, otherwise you need to inspect them to properly
# update them.
$ bundle exec rails webpacker:install
  1. Webpacker 6 introduces a new folder structure for assets which you can see here. While there seems to be an option to change the source_path I decided to simply update to this new structure.
    # For me this meant moving the following files:
    app/javascript/channels/consumer.js -> app/packs/channels/consumer.js
    app/javascript/channels/index.js -> app/packs/channels/index.js
    # Note that I am not using sass (which I believe is default when setting up a rails application).
    app/javascript/stylesheets/application.css -> app/packs/entrypoints/application.css
    app/javascript/packs/application.js -> app/packs/entrypoints/application.js
    app/javascript/stylesheets/tailwind.config.js -> tailwind.config.js
    // Moving the tailwind.config.js file to the root of the project
    // also requires us to update postcss.config.js.
    -    require('tailwindcss')("./app/javascript/stylesheets/tailwind.config.js"),
    +    require('tailwindcss'),
  2. This also requires us to modify our layouts/application.html.erb template as follows:
    -    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    +    <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>   
  3. At this point we are ready to upgrade to PostCSS 8 and include the normal version of TailwindCSS.
    # Changes in your package.json
    -    "tailwindcss": "npm:@tailwindcss/postcss7-compat"
    +    "tailwindcss": "^2.0.4",
    -    "postcss": "^7",
    +    "postcss": "^8.2.8",
  4. For me this wasn't enough to get through bin/rails assets:precompile without errors, if I recall correctly the error I got is that webpacker couldn't read the symbol @ in the css file (used for @import "tailwindcss/base for example). There were several changes I made to resolve this (I'm not sure all of them are necessary):
    /* In app/packs/entrypoints/application.css I updated the @import syntax to @tailwind. */
    -@import "tailwindcss/base";
    -@import "tailwindcss/components";
    -@import "tailwindcss/utilities";
    +@tailwind base;
    +@tailwind components;
    +@tailwind utilities;
    // In app/packs/entrypoints/application.js I removed the css import.
    // When leaving it in (and update it to ./application.css) webpacker hangs on Compiling...
    -import "stylesheets/application"
    # In package.json, specifically in the devDependencies I added these dependencies.
    +    "css-loader": "^5.1.3",
    +    "mini-css-extract-plugin": "^1.3.9",
    +    "postcss-flexbugs-fixes": "^5.0.2",
    +    "postcss-import": "^14.0.0",
    +    "postcss-loader": "^5.2.0",
    +    "postcss-preset-env": "^6.7.0",
    // In postcss.config.js I moved the tailwindcss plugin below postcss-import.
    -    require('tailwindcss'),
     require('postcss-import'),
    +    require('tailwindcss'),
     require('postcss-flexbugs-fixes'),
  5. At this point I was able to successfully call bin/rails assets:precompile or simply run bin/rails server to continue development.
  6. To setup @tailwindcss/jit I followed the steps as outlined on the README. This meant installing the packages, replacing the plugin in postcss.config.js and adding the correct purge options to your tailwindcss.config.js.

From this point onwards all should work fine, assuming you started from a similar situation as me (a new rails template). You might notice that during frontend development (when using bin/rails server) you are no longer able to use 'new' tailwind classes (classes that you haven't used before in your application). This is because webpacker compiles on demand when any of the assets has changed:

In development, Webpacker compiles on demand rather than upfront by default. This happens when you refer to any of the pack assets using the Webpacker helper methods. This means that you don't have to run any separate processes. Compilation errors are logged to the standard Rails log. However, this auto-compilation happens when a web request is made that requires an updated webpack build, not when files change. Thus, that can be painfully slow for front-end development in this default way. Instead, you should either run the bin/webpack --watch or run ./bin/webpack-dev-server. ... Once you start this webpack development server, Webpacker will automatically start proxying all webpack asset requests to this server. When you stop this server, Rails will detect that it's not running and Rails will revert back to on-demand compilation if you have the compile option set to true in your config/webpacker.yml. [source]

However as we are not changing the original assets (stylesheets), we won't get a recompilation of our now JIT compiled TailwindCSS whenever we add a 'new' class to one of our templates. As mentioned in the quoted section above you can, in addition to running bin/rails server run bin/webpack --watch which will recompile the css for you while webpacker proxies all requests for webpack assets to this new process.

Quite a few steps, mostly to upgrade to PostCSS 8, but in the end you get a more pleasant developer experience in the web dev tools and faster compilation times whenever you have to build the assets (for example on your CI server).

Merovex commented 3 years ago

@nbelzer is it possible to share the repo? I've spent...quite a few hours trying to upgrade a recently started rails app. The problem I've encountered is webpack never finishes, so the page never serves. I know everything but tailwindcss-jit works as when I set the postcss.config.js to look for tailwindcss, it compiles a nice 8Mib CSS file.

Edit:

When I set TAILWIND_MODE=build, it does not hang:

TAILWIND_MODE=build rails s works.

taylorthurlow commented 3 years ago

When I set TAILWIND_MODE=build, it does not hang

I've been on a goose chase for the last 2 or 3 hours trying to figure out why only in development NODE_ENV, running webpack would succeed, but would not exit. Thanks!

choilive commented 3 years ago

@nbelzer This was really helpful. For some reason, none of the tailwind styles seem to be added in the pack did you encounter a similar problem? I am not seeing any other errors.

UPDATE: Turns out I missed some stuff when updating to Webpacker 6. I used this guide to fill in some of the gaps. https://dev.to/andrewmcodes/webpacker-6-postcss-loaders-4ajd I did not need to do step 6 of @nbelzer thoughtfully written guide. I might create a start project for people looking to use Webpacker 6, Rails 6.1 and Tailwind JIT. Life on the bleeding edge..

nyrf commented 3 years ago

@nbelzer Could you give a repo? I can update postcss to 8 and use tailwindlabs works well, but when to use tailwindcss-jit, it seems can't generate right cssl.

Update: Now it wokrs well, remeber to set purge in tailwind.config.js

module.exports = {
  purge: [
    './app/**/*.html.erb',
    './app/**/*.html.haml',
    './app/helpers/**/*.rb',
    './app/javascript/**/*.js',
    './app/javascript/**/*.vue',
    './app/javascript/**/*.jsx'
  ],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {}
  },
  variants: {
    extend: {}
  },
  plugins: []
}
TimSullivan commented 3 years ago

I was able to get JIT working with puma-dev without upgrading webpacker by adding this line to config/webpack/development.js:

process.env.TAILWIND_MODE = process.env.TAILWIND_MODE || 'build'
nikgoy commented 3 years ago

this helped me https://github.com/rails/webpacker/blob/4af3db06fcada9c025e1e3f3d84504ed0d169bc4/docs/v6_upgrade.md

mcmire commented 3 years ago

Reviewing the OP's post, I am wondering whether the issue at the time was less to do with Webpacker and more to do with the fact that @tailwindcss/jit was being used in conjunction with PostCSS 7. Now that the JIT is integrated into Tailwind proper, you may be able to use @tailwindcss/postcss7-compat just fine.

bradlc commented 3 years ago

Please can someone provide a reproduction repository with Rails/webpacker already set up, otherwise it's not going to be possible to debug the issue, thanks!

adamwathan commented 3 years ago

Going to close this as there hasn't been any activity on it in a while and lots of stuff has changed that sounds like it might have resolved it. If this is still an issue for anyone please feel free to open a new issue with a reproduction and we can figure it out 👍

Please note that we do not monitor closed issues, so if you comment here after this issue has been closed we won't see it and you won't get a reply. Instead just open a new issue — we will see that for sure! ❤️