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

[BUG] support for @tailwindcss/jit #2916

Closed
4 tasks done
bhvngt opened this issue Mar 19, 2021 · 23 comments
Closed
4 tasks done

[BUG] support for @tailwindcss/jit #2916

bhvngt opened this issue Mar 19, 2021 · 23 comments

Comments

@bhvngt
Copy link

bhvngt commented Mar 19, 2021

Bug Report Quick Checklist

  • I am on the latest version of Snowpack & all plugins.
  • I use package manager pnpm.
  • I run Snowpack on OS Mac
  • I run Snowpack on Node.js v14+

Describe the bug

When I change the postcss config files by replacing tailwindcss to @tailwindcss/jit, build breaks with following error

[snowpack] ! building source files...
[snowpack] ✘ file:///temp/snowpack-tailwind-jit/src/app.css
node:internal/process/promises:227
          triggerUncaughtException(err, true /* fromPromise */);
          ^

Error: ENOENT: no such file or directory, stat 'stdin'
    at Object.statSync (node:fs:1127:3)
    at trackModified (/temp/snowpack-tailwind-jit/node_modules/@tailwindcss/jit/src/lib/setupContext.js:187:26)
    at /temp/snowpack-tailwind-jit/node_modules/@tailwindcss/jit/src/lib/setupContext.js:652:38
    at /temp/snowpack-tailwind-jit/node_modules/@tailwindcss/jit/src/index.js:34:49
    at LazyResult.runOnRoot (/temp/snowpack-tailwind-jit/node_modules/postcss/lib/lazy-result.js:303:16)
    at LazyResult.runAsync (/temp/snowpack-tailwind-jit/node_modules/postcss/lib/lazy-result.js:355:26)
    at LazyResult.async (/temp/snowpack-tailwind-jit/node_modules/postcss/lib/lazy-result.js:205:30)
    at LazyResult.then (/temp/snowpack-tailwind-jit/node_modules/postcss/lib/lazy-result.js:190:17) {
  errno: -2,
  syscall: 'stat',
  code: 'ENOENT',
  path: 'stdin',
  __snowpackBuildDetails: { name: '@snowpack/postcss-transform', step: 'transform' }
}

To Reproduce

  1. git clone https://github.com/bhvngt/snowpack-tailwindcss-jit
  2. snowpack build

Expected behavior

Build should not break

Anything else?

@danielkoek
Copy link

Just remove the "@snowpack/plugin-postcss" from the list of plugins and it works no bother 👍

so in your snowpack.config.js the plugins would look like this instead:

plugins: [
"@snowpack/plugin-svelte",
"@snowpack/plugin-dotenv",
"@snowpack/plugin-typescript",
],

Tested it here locally and you get the nice svetle logo and the colors and everything working!

@FredKSchott
Copy link
Owner

I think the issue is inside of plugin-postcss, which would explain why the error goes away when you remove the plugin. This is actually related to the change we made recently inside of that plugin, pushed a quick fix up to solve: 8ac85f6

Will get that out in a patch releases, so that all you should need to do is reinstall your deps to get latest versions.

@bhvngt
Copy link
Author

bhvngt commented Mar 20, 2021

@danielkoek while removing plugin-postcss does create the build, it stops processing tailwind classes. Since my app.svelte was built from a template, tailwind classes were used in only few areas for the purpose of testing. Those don't show up.

Thanks @FredKSchott for the patch. I tried that patch. With that the build works out fine. However, the snowpack dev mode is not working out well with tailwind/jit. It picks up classes that were present before snowpack dev was trigger. After that hot reloads does not pickup any new tailwind classes.

@FredKSchott FredKSchott reopened this Mar 21, 2021
@rohfle
Copy link

rohfle commented Mar 21, 2021

Not sure if this helps, but when running snowpack dev with the 8ac85f6 patch, the correct styling (and changes to styling) is present if using @apply such as:

<style>
  .button {
    @apply bg-blue-500 text-white inline-block p-2 rounded;
  }
</style>

but not when using class attribute styling such as:

<div class="bg-blue-500 text-white inline-block p-2 rounded">Button</div>

I have created a repro repo in svelte here: https://github.com/rohfle/repro-snowpack-bug-2916
(see https://github.com/rohfle/repro-snowpack-bug-2916/blob/main/src/App.svelte)

@danielkoek
Copy link

@rohfle That has nothing to do with snowpack or this bug, but with JIT, you are missing a purge rule, in your case:

purge: ["./src/**/*.svelte"]
Otherwhise it will look at it all and purges all ;)

(btw you should also change your main.css in App.css and import that instead)

Tried it here locally and worked out grand

@rohfle
Copy link

rohfle commented Mar 21, 2021

Thanks @danielkoek - I missed the detail in the readme. I have updated the repro now. Now I have the same behaviour as @bhvngt above

[...] However, the snowpack dev mode is not working out well with tailwind/jit. It picks up classes that were present before snowpack dev was trigger. After that hot reloads does not pickup any new tailwind classes.

For example, if I change the background of the element in App.svelte from

<div class="bg-red-500 text-white inline-block p-2 rounded">Button</div>

to a new class such as

<div class="bg-pink-500 text-white inline-block p-2 rounded">Button</div>

this does not produce a pink button until snowpack dev is restarted, but changing the <style> @apply produces a pink button on save.

@rohfle
Copy link

rohfle commented Mar 22, 2021

Files defined by the purge rule in tailwind.config.js are not being watched for changes, so any svelte changes will not trigger reprocessing of App.css.

This is whats happening:

  • @snowpack/plugin-postcss transforms App.css (which contains @tailwind base etc). Postcss starts with the full tailwind styles, then shakes the tree to create a reduced css file. This reduced file has only the classes found in files defined by the purge rule above.
  • When a svelte file change is detected, @snowpack/plugin-svelte processes the file. If the file contains a <style> tag, it will be processed by svelte-preprocessor using the postcss plugin.
  • Because the class attributes in the svelte file are only used during the purge in App.css, and there is no file change in App.css, the new classes will not be added

You can reproduce this with the repro repo by

  • Changing a class attribute as above, observe the missing color in the browser, then
  • Open App.css, make a change (just a space or return will do) and save
    This will cause the missing color to come through

Is there any way to retrigger processing of a file based upon changes to other paths?

Edit: There are onChange() and markChanged() in plugins docs. The latest @snowpack/plugin-svelte uses these to update dependencies when a file changes, but App.css is not present in these dependencies

@rohfle
Copy link

rohfle commented Mar 22, 2021

I have created a temporary plugin to fix the issue at

All it does is watch for changes to svelte files and then marks src/App.css as changed. But it works

To use:
npm install --save-dev @rohfle/snowpack-plugin-watchappcss

then add @rohfle/snowpack-plugin-watchappcss to your plugins in snowpack.config.js

@jschaf
Copy link

jschaf commented Mar 24, 2021

Thank you for the work-around! I adapted it very slightly to work with all tsx files instead of .svelte files.

I found snowpack doesn't support local plugins so I added a dev dependency using the file: prefix which seemed lighter weight than publishing an NPM package.

snowpack-css-refresh-plugin/index.js

const path = require('path');

/**
 * Snowpack plugin that reloads all CSS changes with PostCSS any time any .tsx 
 * file changes.
 *
 * This plugin is necessary because adding a React className like bg-blue won't
 * trigger a CSS refresh. As a workaround, pessimistically assume that any time
 * the tsx file changes that the CSS changes to trigger PostCSS.
 *
 * For details, see https://github.com/snowpackjs/snowpack/issues/2916.
 *
 * @param {import('snowpack').SnowpackConfig} snowpackConfig
 * @param {import('snowpack').SnowpackPlugin & { init?: (cfg: import('snowpack').SnowpackConfig) => void }} _pluginOptions
 */
const plugin = (snowpackConfig, _pluginOptions) => {
  const appCssPath = path.join(snowpackConfig.root || process.cwd(), 'src/App.css');
  return {
    name: '@local/snowpack-css-refresh-plugin',
    onChange({filePath}) {
      if (!filePath.endsWith('.tsx')) {
        return;
      }
      this.markChanged(appCssPath);
    },
  };
};

module.exports = plugin;

package.json

  "devDependencies": {
    "@local/snowpack-css-refresh-plugin": "file:./dev/snowpack-css-refresh-plugin"
  }

@Xeevis
Copy link

Xeevis commented Mar 29, 2021

I've created a simple plugin that will automatically monitor all template files watched by the the TailwindCSS JIT and will refresh all CSS processed by the Snowpack that import TailwindCSS. Nothing is hardcoded so ideally it should work for all scenarios without extra configuration.

Please see the NPM package or github repository for install instructions and let me know if it works for you.

@sarimarton
Copy link

Neither @jschaf nor @Xeevis 's solution works for me properly. It compiles the tailwind classnames on dev start, but not on file change, so changing a tw class most of the time has the same effect as removing it.

Am I missing something?

postcss.config.js

module.exports = {
  plugins: {
    // tailwindcss: {},
    '@tailwindcss/jit': {},
    autoprefixer: {}
  }
}

snowpack.config.js

/** @type {import("snowpack").SnowpackUserConfig } */
module.exports = {
  plugins: [
    '@snowpack/plugin-react-refresh',
    '@snowpack/plugin-dotenv',
    '@snowpack/plugin-typescript',
    '@snowpack/plugin-postcss',
    // '@jadex/snowpack-plugin-tailwindcss-jit',
    '@local/snowpack-css-refresh-plugin'
  ],
  // ...
}

tailwind.config.js

module.exports = {
  purge: ['./public/**/*.html', './src/**/*.{js,jsx,ts,tsx}'],
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {}
  },
  variants: {
    extend: {}
  },
  plugins: []
}

@Xeevis
Copy link

Xeevis commented Apr 4, 2021

@sarimarton make sure your NODE_ENV is set to development (this determines mode for TailwindCSS JIT). This can be done various ways on various platforms, but simple solution to work everywhere is to use cross-env.

npm install cross-env --save-dev

And in your package.json add it to the script like so

"scripts": {
  "dev": "cross-env NODE_ENV=development snowpack dev",
  "watch": "cross-env NODE_ENV=development snowpack build --watch",
  "build": "cross-env NODE_ENV=production snowpack build"
},

Then run it with npm run dev or pnpm dev, depending on what you use.

Also note JIT only appends new classes on save. When changing and removing classes from template files it will not remove them from generated css file, these will be purged next time you run dev or build. This is a feature of the TailwindCSS JIT (performance reasons).

@sarimarton
Copy link

@Xeevis Still not working... (here's my repo: https://github.com/sarimarton/github-issue-browser)

@Xeevis
Copy link

Xeevis commented Apr 4, 2021

@sarimarton sorry to hear you have problems with my plugin, problem was in the path matching. Purge had relative path, while snowpack passes absolute therefore the glob didn't match. Can you please update to 0.1.1 if it resolves your issue?

npm update @jadex/snowpack-plugin-tailwindcss-jit@latest

@sarimarton
Copy link

@Xeevis It works now! Thank you very much!

@drwpow
Copy link
Collaborator

drwpow commented Apr 30, 2021

We’ve updated the Snowpack docs to reference the new Tailwind JIT compiler: https://www.snowpack.dev/guides/tailwind-css/#nav-primary

I believe everything is working as expected, but please let me know if you have any issues, or if you encounter any bugs please open a new ticket with specific details and steps to reproduce. Thanks!

@drwpow drwpow closed this as completed Apr 30, 2021
@aaronjensen
Copy link
Contributor

@drwpow It's awesome to see progress here, thanks! That said, it's probably worth addressing #3041 because jit is pretty much unusable if you have to restart snowpack every time you add a new class. I was hoping that because it was documented now it would be usable, but that doesn't appear to be the case.

@pReya
Copy link

pReya commented Apr 30, 2021

@drwpow This is not about missing documentation, but rather about a bug when using the jit mode. Were there any changes to snowpack to fix this? Otherwise I'd assume this still exists.

@drwpow
Copy link
Collaborator

drwpow commented Apr 30, 2021

@drwpow It's awesome to see progress here, thanks! That said, it's probably worth addressing #3041 because jit is pretty much unusable if you have to restart snowpack every time you add a new class. I was hoping that because it was documented now it would be usable, but that doesn't appear to be the case.

@drwpow This is not about missing documentation, but rather about a bug when using the jit mode. Were there any changes to snowpack to fix this? Otherwise I'd assume this still exists.

Totally understandable—I agree that there’s probably something within Snowpack that needs to be improved. But since I think HMR reloading is separate from this original ticket of “doesn’t work at all,” I’d like to track this separately rather than have this just be a long discussion of everything Tailwind JIT-related. Would either of you mind opening a new issue to outline the HMR case (along with a suggested setup, so I can make sure I’m testing it as you would)?

We’re very interested in having a good Snowpack + Tailwind story, but as someone that doesn’t use Tailwind myself, having your setups & config outlined would be the most helpful to make sure that happens.

@aaronjensen
Copy link
Contributor

It's not about HMR, it's about reloading period. You must restart snowpack to see changes if the change introduced a new class. I'm not sure it's worth opening a new ticket as #3041 describes it and contains a repro (though I haven't explicitly tested that repro).

@aaronjensen
Copy link
Contributor

@pReya It's working for me aside from the issue I referred to. I did have to remove this from my snowpack config, which I had forgotten about:

-    [
-      "@snowpack/plugin-build-script",
-      { cmd: "postcss", input: [".css"], output: [".css"] },
-    ],

@aaronjensen
Copy link
Contributor

aaronjensen commented Apr 30, 2021

Actually the repro in #3041 doesn't have JIT. I'll open a new issue.

New issue: #3246

@jfrancos
Copy link

Thanks @Xeevis that plugin helped me a lot!

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

No branches or pull requests