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

Tailwind problem when working with different folders #781

Closed
Frolipon opened this issue Oct 4, 2022 · 13 comments
Closed

Tailwind problem when working with different folders #781

Frolipon opened this issue Oct 4, 2022 · 13 comments

Comments

@Frolipon
Copy link

Frolipon commented Oct 4, 2022

  • Maizzle Version: 4.2.1
  • Node.js Version: 14.16.0

Hello,

I encounter a problem that I can't reproduce consistently.
Here it is:
I configured a repository "production" as follow:

  • Production
    • Clients
      • client_a
        • src
          • components
          • css
          • images
          • layouts
          • templates
      • client_b
        • src
          • components
          • css
          • images
          • layouts
          • templates
        • etc.

And a second repository "maizzle" which is a fork from
https://github.com/maizzle/maizzle

In the repo "maizzle", I have a config.js as follow:

module.exports = {
	prettify: true,
	prettify: {
		indent_with_tabs: true,
	  },
	inlineCSS: true,
	removeUnusedCSS: true,
	removeUnusedCSS: {
	  removeHTMLComments: false,
	  },
	extraAttributes: {
		a: {
			target: '_blank'
		},
		img: {
			border: '0'
		},
		table: {
			border: '0',
			role: 'presentation',
			cellpadding: '0',
			cellspacing: '0'
		},
	},
}

and a config.local.js as follow:

module.exports = {
	path: '../production/clients/client_a/src/',
	build: {
		tailwind: {
			css: '../production/clients/client_a/src/css/tailwind.css',
		},
		templates: {
			source: '../production/clients/client_a/src/templates',
			destination: {
				path: '../production/clients/client_a/build_production',
			},
			assets: {
				source: '../production/clients/client_a/src/images',
				destination: 'images',
			},
		},
	},
}

So the idea is to have a maizzle repository from where we can build htmls from sources in another folder.

When I run run maizzle build local, I sometimes have a very strange behavior in the built HTML:
Some of the tailwind commands does not work anymore. For example, class="p-15" will indeed give me a style="padding: 15px;", but a class="py-15" won't work.

I tested several things, and if the files (tailwind.css, templates, layouts and components) in the maizzle repo and the production repo are the same, then the maizzle build local will work smoothly. But if the files in the maizzle repo are the default ones, then the maizzle build local will have the strange behavior described.

Note:
The idea behind this is to have a repo for a fork from maizzle to keep upgrading it easily, and without risking any problem with our clients

@Frolipon
Copy link
Author

Frolipon commented Oct 5, 2022

After some more testing, my guess is that Tailwind check the classes present in the maizzle repository, and prepare those classes.
But I think it should check the files (layouts, components and template) in the folder described in the config.local.js file.

I tried adding a tailwind.config.js in the production/clients/client_a folder and in the config.local.js file:

tailwind: {
			css: '../production/clients/client_a/src/css/tailwind.css',
			config: '../production/clients/client_a/tailwind.config.js',
		},

And indeed it takes that tailwind.config.js file into account, but I still have the same problem about the classes.
If in my production/clients/client_a/src/templates/promotion.html I use a class="py-15" but if this class is not used in the maizzle repository, then Tailwind won't take it into account.
And if I add it into the html files in the maizzle repository, then it will be taken into account in the production repository.

Am I missing something in the configuration file? Is it intended? Is it a bug?

@cossssmin
Copy link
Member

Hi there,

This is how the JIT engine in Tailwind works, it only generates classes that it 'sees' used in one of the defined content sources. All you have to do is add that path to Tailwind's content key in tailwind.config.js so it can scan files in there for selectors to generate.

Maizzle configures Tailwind CSS with some default content sources (like your layouts/components/templates folders), but for anything else you need to add the paths to your tailwind.config.js. See our docs for more details.

Tip: don't add content paths that contain binary files, like images. It slows down Tailwind a lot because it has to read each file to scan for selectors to generate, and binaries are very expensive to process.

Note that Maizzle v4.2.2 was released yesterday, and it fixes an issue with the default content sources (not directly related to your issue, but I strongly recommend upgrading to it as it comes with performance improvements).

@Frolipon
Copy link
Author

Hello,

Thank you so much for your help!
I managed to make it work.
Now, my next question is:
I now have in my tailwind.config.js:

content: [
	'../Production/clients/nose/20220628_Transac_re-design/src/templates/**/*.{html,js}',
	'../Production/clients/nose/20220628_Transac_re-design/src/components/**/*.{html,js}',
	'../Production/clients/nose/20220628_Transac_re-design/src/layouts/**/*.{html,js}',
],

Is there a way to parametrize this path?
I would like to keep the writing of the path in one file if possible.
is there any way to use the path define in my config.local.js:

module.exports = {
	path: '../production/clients/client_a/src/',
}

Or the define this path still elsewhere and use the variable in both the config.local.js and tailwind.config.js ?

@cossssmin
Copy link
Member

You could require config.local.js in tailwind.config.js and use that path:

// tailwind config
const localConfig = require('./config.local.js')

module.exports = {
  content: `${localConfig.path}{layouts,templates,components}/**/*.{html,js}`
}

Mind the / at the end of the path in your local config, its presence determines how you write that content value above.

Btw, as you may have noticed - this should also work for the glob pattern:

content: [
-	'../Production/clients/nose/20220628_Transac_re-design/src/templates/**/*.{html,js}',
-	'../Production/clients/nose/20220628_Transac_re-design/src/components/**/*.{html,js}',
-	'../Production/clients/nose/20220628_Transac_re-design/src/layouts/**/*.{html,js}',
+	'../Production/clients/nose/20220628_Transac_re-design/src/{layouts,templates,components}/**/*.{html,js}',
],

@Frolipon
Copy link
Author

Hello,

Unfortunately, I can't make it work.
I don't know if I'm writing something wrong here, but it seems that the content definition doesn't work well.

On my side, it looks like:

//tailwind config
const localConfig = require('../../../maizzle/config.local.js')
//the path relative to my config.local.js file

module.exports = {
  content: `${localConfig.path}src/{layouts,templates,components}/**/*.{html,js}`,
(...)
}

The error I get is:
✖ Cannot read properties of undefined (reading 'push')
If I change to

//tailwind config
const localConfig = require('../../../maizzle/config.local.js')

module.exports = {
	content: ['../production/clients/client_a/src/{layouts,templates,components}/**/*.{html,js}'],
(...)
}

It works once again, so I assume there is something wrong about the way I use the ${localConfig}

But anyway, this doesn't solve the problem of setting a path in a tailwind.config.js file. Because first it was the path to the layouts, components and css. Now it will be the path to the config.local.js file relative to the tailwind.config.js.

Or am I still missing something?

@cossssmin
Copy link
Member

content must be an array, not a string. Your paths are probably not pointing to the correct directory relative to your project root, perhaps this note in the Tailwind docs is relevant:

Paths are relative to your project root, not your tailwind.config.js file, so if your tailwind.config.js file is in a custom location, you should still write your paths relative to the root of your project.

@Frolipon
Copy link
Author

Indeed, I saw that I had to point to the root directory.
But I don't get how to pass the localConfig var to content array. From what I saw in the note, we can only pass strings or patterns.

Sorry if this is obvious, I'm from the email world without much technical knowledge, but I'm trying to improve that!

@cossssmin
Copy link
Member

Sorry about that, I shortened the code for the example.

You need to get the correct key from config.js and then you can pass it to content via a template literal:

// In your tailwind.config.js

// First, get the Maizzle config
const localConfig = require('./config.local.js')

// Pass the `build.templates.destination.path` variable from Maizzle config to Tailwind's `content`
module.exports = {
  content: `${localConfig.build.templates.destination.path}/{layouts,templates,components}/**/*.{html,js}`
}

Mind the added / before {layouts...

@cossssmin
Copy link
Member

Just saw this in Tailwind 3.2 which may be exactly what you need:

tailwindlabs/tailwindcss#9396

I’ll try to publish a release today which will include Tailwind CSS 3.2, just need to run a few more tests 👍

@Frolipon
Copy link
Author

That seems indeed to resolve the problem :-)

I would be happy to test it once it is in the new release!

@cossssmin
Copy link
Member

It's been released in v4.2.0, give it a try.

@Frolipon
Copy link
Author

Hello,

I am on v4.3.0 at the moment, but I have a new problem:
Every time I try to build the html, I have the following error:

Error:` Failed to find 'tailwindcss/components'
  in [
    /xxx/production/clients/client_a/src/css
  ]

If I install the nodes_module in the client_a folder, then it work. But the whole point of this configuration is to avoid that, and have only the node_modules and the maizzle framwork installed in the maizzle repository.

I'm pretty sure it worked a few days ago with the same config (I need to test it with and older npm version).

I tried playing with the

// In tailwind.config.js
content {relative: true,}

but I couldn't make it work.

I also tried with the 
/*  in tailwind.css */
@config "../../tailwind.config.js"

Do you know if some changes were made?

@cossssmin
Copy link
Member

Support for @config will be fixed in Maizzle 5, already got it working locally 👍

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

2 participants