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

Unable to Use Tailwind without a 'build' Folder #672

Open
iocouto opened this issue Oct 26, 2021 · 10 comments
Open

Unable to Use Tailwind without a 'build' Folder #672

iocouto opened this issue Oct 26, 2021 · 10 comments

Comments

@iocouto
Copy link

iocouto commented Oct 26, 2021

SHORT DESCRIPTION

I'm trying to use Tailwind and CodeKit with a PHP-based CMS site, and can't use a 'build' folder. Without using 'source' and 'build' folders, however, CodeKit seems unable to recognise which classes are actually used in my php templates, and fails to compile Tailwind's CSS files appropriately.

DETAILED DESCRIPTION

I'm working as a Frontend Developer on full-stack dynamic websites that use php-based CMSs. These projects require all my frontend 'theme'/'template' files, as well as my css/js files, to be placed in very specific folders. I'm usually editing html code and editing css classes directly inside a .php template or 'included' partial. These templates/partials are often added to the CMS as a 'plugin', and along with their compiled .css stylesheets, have to be placed in very specific folders in order for me to not cause bugs or give unnecessary extra work to the Backend Developer. So, using a 'build' folder in CodeKit is never an option.

This is not a problem when using "traditional" frameworks - like Bootstrap, Foundation or UIKit: I can just set CodeKit not to use a build folder, and then specify the output directory for all files in the project's settings, carefully, manually. But this approach doesn't seems to work with Tailwind projects.

The Problem
I have a Tailwind-based CodeKit project, where I use the JIT compiler. If I use the 'source' + 'build' folder approach, everything works fine, and I can use all of the JIT compiler features without a glitch. I can make edits to my templates in the 'source' folder, and immediately preview the results in the outputted corresponding file in the 'build' folder.

I then turn off "this project uses a build folder" in 'Build Process' settings. I remove the 'build' folder, and move all the files - php templates, css stylesheets, etc. - out of the 'source' folder, and into the "right" folder, where they are supposed to be, according to the dictates of whatever CMS I'm working with. I then change all the remaining preferences in CodeKit, to set the output paths to the appropriate directories for that CMS - eg., 'output all CSS files to /assets/css'.

Now, however, when I preview my document, the output is broken: none of the Tailwind styles are being compiled into the production stylesheet. Although the stylesheet is still being compiled every time I save a change to my template - CodeKit recognises that there is a change, and recompiles the stylesheet at the expected location - it seems CodeKit fails to 'see' the Tailwind classes I'm using in the template, and none of them get added to the outputted stylesheet.

Is there a way to use CodeKit + Tailwind without using a 'build' folder? Have I overlooked something obvious?

@bdkjones
Copy link
Owner

bdkjones commented Oct 26, 2021 via email

@iocouto
Copy link
Author

iocouto commented Oct 26, 2021

Thank you for the quick feedback, @bdkjones!

I have separate input/output directories for css and js files:

  • files from '/stylesheets' get compiled into '/css'
  • files from '/scripts' get compiled into '/js'

Do you mean, the actual html/php template files also need to have input/output directories?

@bdkjones
Copy link
Owner

bdkjones commented Oct 26, 2021 via email

@iocouto
Copy link
Author

iocouto commented Oct 26, 2021

I think I'm overlooking something obvious: if I have separate directories just for the input and output of CSS files, shouldn't Tailwind be ok? Or does Tailwind have a requirement that all files in my project - including HTML, PHP, JS, etc. - also need to have separate input and output directories/locations of their own?

Right now, using CodeKit's 'build' folder, things seem to work like this:

source
  index.php
  /css
    main.css (<- original)
build
  index.php (<- no change at all)
  /css
    main.css (<- compiled)

Therefore, I expected that this - without a 'build' folder - wouldn't be a problem, either:

index.php
/stylesheets
  main.css (<- original)
/css
  main.css (<- compiled)

@iocouto
Copy link
Author

iocouto commented Oct 29, 2021

Just a follow up: I've reviewed the Tailwind docs, and there does not seem to be a requirement on their side for us to use a 'build' folder. Tailwind seems to take its 'input files' from the purge: entry in its config. Here is the relevant paragraph from the Tailwind JIT docs:

[...] Since JIT mode generates your CSS on-demand by scanning your template files, it’s crucial that you configure the purge option in your tailwind.config.js file with all of your template paths, otherwise your CSS will be empty.

Let's test it out in the terminal:

  1. Create a new, empty tailwind project from scratch:
cd ~
mkdir tailwindtest
cd tailwindtest
npm init -y
npm install tailwindcss@latest postcss@latest autoprefixer@latest --save-dev
npx tailwindcss init -p
  1. Create a basic 'index.html' file on the root of the project folder, to test things out:
<!doctype html>
<html>
  <head>
    <title>Test Page</title>
    <link rel="stylesheet" href="/css/main.css">
  </head>
  <body>
    <h1 class="bg-purple-800 text-yellow-200 text-4xl font-bold p-9 extratopmargin">
      Test Page
    </h1>
  </body>
</html>
  1. Set the required config parameters in 'tailwind.config.js':
module.exports = {
  mode: 'jit',           // activate JIT compiler
  purge: [ './*.html' ], // ...and tell it which files to watch
  darkMode: false, 
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
}
  1. Let's test it out: run tailwindcss in 'watch' mode, asking it to generate the resulting CSS file inside a '/css' folder:
npx tailwindcss -o './css/main.css' --watch

We should see Tailwind create the '/css/main.css' file for us, as requested. The file contains the Tailwind utility classes used in our 'index.html' - we can preview it in a browser. We can try making changes to the classes in 'index.html', and see Tailwind compile 'main.css' as expected. So far so good.

How about if we want to include an external CSS file, with our own styles - as in the example mentioned in my post above? Let's try.

In our simple 'index.html' example above, our <h1> has a class named extratopmargin. Let's pretend this is an often-used custom style, that I'd like to define in my own CSS file, using Tailwind's @apply directive.

  1. Stop the Tailwind watch server in your terminal, if you haven't yet, by typing 'Control-C'.
  2. Create a new folder titled 'stylesheets', and in that create a 'main.css' file with the following content:
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .extratopmargin {
    @apply mt-9;
  }
}
  1. Finally, we get Tailwind to 'read in' our custom CSS file as an 'input' as well, by using the -i flag in the command-line, like this:
npx tailwindcss -i './stylesheets/main.css' -o './css/main.css' --watch

We should see Tailwind generate the '/css/main.css' file as expected, now including our '.extratopmargin' class.

So, in summary: it seems there is no requirement from Tailwind for us to have a 'build' folder. It seems we should be able to keep watch on an arbitrary number of folders, and output the resulting CSS to an arbitrary location.

POSSIBLE CAUSE

I'm going to guess that the cause of this problem is that CodeKit ignores the purge: settings from 'tailwind.config.js' - because it assumes these settings relate to PurgeCSS, and therefore are "unnecessary" here. When using Tailwind's JIT compiler, however, the purge: setting is used to tell it where the 'source' files are (not to configure PurgeCSS, as it is not needed with the JIT compiler).

It would be wonderful if we could set this up properly inside CodeKit, as this is pretty vital when working with projects where using a 'build' folder is not possible - which, when we use a CMS like WordPress, Drupal, Joomla, Grav, Statamic, Kirby, or any number of others, is pretty much all the time...

@bdkjones
Copy link
Owner

bdkjones commented Oct 29, 2021 via email

@iocouto
Copy link
Author

iocouto commented Oct 29, 2021

[...] That’s why the build folder is necessary in this case—so CodeKit knows what’s an output file and what’s an input file.

Can't CodeKit determine that the same way it does for all other (non-Tailwind) projects that don't use a 'build' folder? Couldn't CodeKit use the same processing preferences that are used for other projects?

@bdkjones
Copy link
Owner

bdkjones commented Oct 29, 2021 via email

@iocouto
Copy link
Author

iocouto commented Oct 29, 2021

Thank you for the explanation, @bdkjones!

[...] What MIGHT be possible is to allow you to override CodeKit’s automatic behavior and configure your purge list manually.

That should work. 👍

But are we perhaps seeing a problem where there isn't one? Right now, CodeKit is scanning a 'source' folder for input files, and then producing its output in matching directories in the 'build' folder. Why can't we just use the entire project folder as a 'source', then? Let's try to pinpoint exactly the issues that are stopping us.

Please correct me if I'm wrong, but it seems to me the current process - using the 'build' folder - is something like this:

  1. CodeKit scans the 'source' folder for 'input' files - eg., .html, .php, .kit, .js, etc. - ie. the files that Tailwind will use to pick the CSS styles that are actually being used, so it builds the required CSS stylesheet. These 'input files' are either copied to the 'build' folder without change, or are processed by tools that have nothing to do with Tailwind (eg., .kit files), and whose output location is determined by the settings in CodeKit preferences. So, it seems nothing about these input files actually requires us to use a 'source' folder, or would require any extra configuration if we just used the entire project folder as 'source'.

  2. Now, it seems to me that the CSS files are particularly important for CodeKit in Tailwind projects, because they determine Tailwind's output files - ie., the '.css' stylesheets that are produced by Tailwind. It seems CodeKit will use each '.css' file in our 'source' folder as a "wanted output target" in the 'build' folder - as by default CodeKit will put those output css files in the same location as the original file in the 'source' folder. However, CodeKit is smart enough to use the CSS settings from the app, so if my CSS settings say that I don't want my output CSS files to end up in the same folder as they were in 'source', CodeKit will respect that, and will output the CSS files in whatever folder I specify in my settings.

So, if the location of the outputted CSS files is also being specified by the CSS settings, we should be able to use the entire project folder for the output files. That is, as long as I'm compiling the CSS files to a different path from the original file. In fact, that will be the ONLY situation where I actually need a 'build' folder: if I want my CSS files compiled to exactly the same path (same directory and name) as the original. Now, in your experience, how often do you want that? - specially if you're NOT using a 'build' folder.

It seems CodeKit should be able to simply replace the 'source' folder with the entire project folder, provided that the CSS settings say that .css files should be compiled to a different path - ie., to a different folder, or with a different name.

[...] For the 99% of people who aren’t mashing Tailwind into a particular CMS’s structure, the current approach is fantastic because it’s configuration-free.

Indeed, 'configuration free' is what we all love most about CodeKit, and anything we can do to keep it that way is worth the effort. And trying to minimise configuration - and extra work - is exactly what I'd love for you to help us achieve here.

In my experience, the 'build' folder workflow only works well for some very specific use-cases. It works well, for example, if:

  • you're building a static website, or using a static site generator and uploading your 'build' folder to a service like Netlify
  • you're building your own frontend framework or library, and want to have a 'dist' folder in your repository, separate from your 'src' folder
  • a headless CMS where the frontend is totally separate from the backend, accesses the backend only via API, and can be developed as a totally separate project of its own

In these cases, CodeKit's current 'no config' approach is awesome, and fits perfectly well. But in my experience, those kinds of projects are not the 'typical' project most developers will be engaged in, and that's when having this 'build' workflow stops being 'no config', and actually causes a lot of extra work for everyone involved.

Most of us work with dynamically-generated sites, and which need to use:

  • a CMS with a database backend (WordPress, Drupal, Joomla, ExpressionEngine, ModX, etc.)
  • a flat-file CMS (like Grav, Statamic, Kirby, etc.)
  • a backend framework that has their own frontend template language (like Laravel, CodeIgniter, Phalcon, FatFree, Django, Rails, etc.)
  • a headless CMS where the frontend is not totally decoupled from the backend

...and in all those cases, being forced into a 'build' workflow is far from helpful. As an example, here is what our workflow is like, if we use CodeKit in a Kirby project:

  1. Frontend bug is spotted and reported.
  2. Frontend developer copies the current project locally, and reproduces the error.
  3. Frontend developer then open a 'frontend-only' version of the project, which is setup with the 'source' and 'build' folders, as required by CodeKit.
  4. Frontend developer then starts by making sure the template files in the 'frontend-only' project still reflect the '.php' templates that are being used in production.
  5. Frontend developer then makes the necessary changes/updates/fixes in the 'frontend-only' project, compiling their Tailwind-based styles from their '.html' templates into '.css' stylesheets, with CodeKit.
  6. Frontend developer then passes the modified '.html' templates and newly-compiled '.css' stylesheets to the Backend developer.
  7. Backend developer then manually merges the changed '.html' templates into their '.php' templates and partials.
  8. Backend developer then manually merges the changed '.css' files into the current stylesheets.
  9. Backend developer tests the changes. If anything is not working as expected, then talk to Frontend developer and try again...
  10. When the frontend changes are deemed to be tested and working fine, it's done.

Here is what the workflow would be like, if we didn't have to use a 'build' folder:

  1. Frontend developer copies the current project locally, and reproduces the error.
  2. Frontend developer makes the frontend edits directly in the the .php templates and partials.
  3. Frontend developer recompiles and tests with CodeKit.
  4. If it all works, then it's done!

Apologies for the lengthy post. I hope this helps clarifies why this is such an important point for us. We love CodeKit, have been using it for years, and hope to continue using it forever. But we need to sort out a workflow that makes our job easier, as right now the extra work is forcing us to either use CodeKit without Tailwind, or use Tailwind without CodeKit - and we're very unhappy with either choice. :(

@jamiegrisdale
Copy link

jamiegrisdale commented Jan 7, 2022

@iocouto I've had this working fine just by defining the "Pages to scan" setting in PurgeCSS to template files outside the build folder.

  1. First I have a folder structure with the source and build directories nested in the CMS files like this:
root <-- CMS root
|-- src <-- codekit project root
|    |-- source
|    |    +-- assets
|    |         |-- scss
|    |         +-- js
|    +-- build
|         +-- assets
|              |-- css
|              +-- js
|-- templates
|    |-- layout.php
|    +-- layout.html
+-- htdocs
     |-- index.php
     +-- assets
          |-- css
          +-- js
  1. Then in Settings > Tools > PurgeCSS > Pages to Scan I add entries for whatever files need checking by Tailwind/PurgeCSS:

../templates/**/*.php
../templates/**/*.html

By starting with the ../ you're going a level above the CodeKit project directory.

  1. Finally there's one extra step needed which is to add a build process shell script which just copies the build directory assets to the web root assets directory:

rsync -rtu --delete root/src/build/assets/ root/htdocs/assets

Done, works great.

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

3 participants