how to add Tailwind CSS with PostCSS purge to rails 5? - ruby

i would like to add tailwindcss to a new rails 5.2.5 project. since i like tailwind but know about the heavy weight, i also would like to have a purge css module.
i followed the instructions of several set up guides, as well as the official documentation. also i tried to install tailwind via gems (https://github.com/rails/tailwindcss-rails, https://github.com/IcaliaLabs/tailwindcss-rails) but since all the solutions out there are based on rails 6 nothing works. also i have no idea what webpack actually does, so i would rather dont use it but instead use tailwind via the asset pipeline, but also with class purging.
i am a bit lost during the build process. is there a convenient guide on how to set up tailwind at rails 5 instead of rails 6? i really enjoy the automagical approach of most gems but cant find a convenient solution.
thank you!

It is possible to add tailwind to the Asset Pipeline without using Webpacker, and without tailwindcss-rails either.
If you use the new Tailwind CLI you can build tailwind classes, connect them to the asset pipeline and purge unused classes on the fly.
The general instructions for using the Tailwind CLI are in the installation section which is currently in their docs you will need node installed to have access to the npx command.
Once you understand the general approach use the following steps:
Update the generated tailwind.config.js to turn on Just In Time compiling and to configure class purging in rails
module.exports = {
mode: 'jit',
purge: [
'./app/**/*.html.erb',
'./app/helpers/**/*.rb',
'./app/assets/javascripts/**/*.js'
],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {},
plugins: [],
}
Make sure that you add all the path's where you will declare Tailwind classes otherwise purge may remove classes that you are using (read Writing purgeable HTML tailwind docs for more details)
During development run the watcher process so that your CSS is being continually built based on the HTML you write
npx tailwindcss --no-autoprefixer -o ./vendor/assets/stylesheets/tailwind.css -w
Note that I am placing the generated tailwind styles into vendor/assets but you can place them anywhere the asset pipeline looks for css.
Also, I still use autoprefixer-rails gem so that I can apply the correct prefixes across both tailwind and my project css. In this case you need to set --no-autoprefixer in the tailwind watch command so you are not running it twice.
Then import the tailwind styles into your app/assets/stylesheets/application.scss with #import 'tailwind'
Provided the file is in your assets path the styles will be imported.
Make sure you have a deployment option to re-compile your tailwind.css file as the JIT compilation may is not guaranteed (this is suggested by Tailwind). This will depend on how you deploy but I run the following during deploy:
NODE_ENV=production npx tailwindcss --no-autoprefixer -o ./vendor/assets/stylesheets/tailwind.css
That should be it.
I run this approach with Rails 6.1 but it doesn't use anything special and I expect it should run with Rails 5 projects.
Finally, you may be interested in using the Tailwind #apply feature to set some default styling with Tailwind classes. This is also possible with this setup. To do it you need to have an extra file for the base classes which is used during the Tailwind compilation. The important thing here is not to add this file into your application.scss as the Asset Pipeline will not understand #apply.
I add the few styles that I do to a app/assets/stylesheets/tailwind/base.css file.
I then amend the compilation watcher to npx tailwindcss --no-autoprefixer -i ./app/assets/stylesheets/tailwind/base.css -o ./vendor/assets/stylesheets/tailwind.css -w which will gather all the base styles set and compile them into the tailwind output file.
Good luck with it.

Related

webpack to allow import of all sass files? i.e #import 'components/**/*'

I'm currently using css-loader, node-sass, sass-loader and style-loader packages within webpack to compile my sass files, here is how my loader looks at the moment:
{
test: /\.scss$/,
loader: 'style!css!sass'
}
I want to use folder structure like this for my styles
styles
components/
main.sass
and somehow within main.sass I want to import everything from components folder so something like #import './components/**/*' is this possible via webpack?
You can prefix a Sass import with '~' to tell the Sass loader to use webpack's require() resolution on the import. Once webpack is in charge of the import you have some flexibility.
If you do a dynamic require, e.g. require('~./components/' + someVar + '.scss'), webpack can't evaluate the variable at build time and it bundles all the possible files in that directory, and the actual resolution of the require() happens at runtime (which can lead to errors at runtime if you've asked for something that doesn't exist). Not sure off the top of my head if that would give you what you need (all the files bundled) or if you would still need to explicitly require() each partial -- but if that's the case you could easily loop through all the files in the directory and require each one.
More on how you can leverage webpack's dynamic requires and loading context.

Laravel Elixir: How to minify files?

I want to use Laravel Elixir to minify my css/files files. But I don't want to use the mix-methode and merge them. All I want is to generate a "custom.min.js" file from my original "custom.js". Is there a way to do this with Elexir?
EDIT:
To make it a bit clearer: My biggest issue is that I have two folders in "resources/assets": js and css. So I basically want to minify all files in there and have them minified in "public/js" and "public/css".
Quote from the Laravel documentation:
Note: All tasks will assume a development environment, and will exclude minification. For production, use gulp --production.
This means if you want the files to be minified run gulp --production instead of just gulp. It's a better practise than enabling compression directly in the gulp file and makes sure you can debug your compiled files while developing the application.
If you want them to be placed in public/assets/css use the path as a second parameter:
mix.less('app.less', 'public/assets/css');
gulp --production.
Jeffrey way replied on the issue here: https://laracasts.com/discuss/channels/elixir/elixir-doesnt-minify
Or you can find it on the documentation. Enjoy coding!
If you just want to copy .css files, without using LESS or SASS, and don't want to combine files (i.e. you want something like a copy() method with minification ability) you can use method for combining, styles(), by calling it for every .css file and passing filename string without array, for example:
mix.styles('some.css');
mix.styles('node_modules/bootstrap/dist/css/bootstrap.css', null, './');
Same can be done for .js files using scripts() method:
mix.scripts('some.js');
mix.scripts('node_modules/bootstrap/dist/js/bootstrap.js', null, './');
And then you can use gulp (doesn't minify, creates .map files) or gulp --production (creates minified files) as mentioned in above posts.
Straight from the Laravel/Elixir docs:
Elixir is built on top of Gulp, so to run your Elixir tasks you only need to run the gulp command in your terminal. Adding the --production flag to the command will instruct Elixir to minify your CSS and JavaScript files:
Run all tasks... gulp
Run all tasks and minify all CSS and JavaScript... gulp --production
docs: https://laravel.com/docs/5.3/elixir#running-elixir

gulp, wiredep and custom sass file

So I made a library that I can bower install using a direct link. I can use this library from another internal application by adding the library name in the dependency of the bower.json file. When other internal application does a bower update, the changes I made on the library will be applied to their application. This part is working very well.
Now, I'd like the other software devs to have freedom to change the styles. They can create css file directly and that will work. However, it's a hackish route. I can provide them the same settings file that I use.
So i tried putting that file in the main section of the bower.json but wiredep is processing it. I put it in exclude and the error is gone when I run gulp.
"main": [
"dist/stylesheet.css",
"src/_settings.scss"
],
this is the code that prevented it from being parsed by wiredep
wiredep: {
directory: 'bower_components',
exclude: ['css/foundation.css','src/_settings.scss']
}
Am I right that I'll have to create a new gulp task and put 'src/_settings.scss' as gulp.src like this
gulp.task('sasstask2', function () {
return gulp.src('src/_settings.scss')
.pipe($.sass())
.pipe(gulp.dest('src/css'));
});
I also like the generate css to be injected to index.html but not sure how to do it? Will wiredep automatically inject it to index.html?

Angular generator without Ruby

The angular generator has a dependency on compass and thus ruby when using SASS.
Two questions:
Is it possible/practical to remove the ruby dependency by using something like node-sass?
If so, how do I accomplish #1 and still use angular generator to generate controllers, routes, services, etc in the future?
If you are using the Yeoman Angular generator and you wish to use SASS/SCSS without depending on Ruby, you could use the grunt-sass Grunt module.
Yeoman is essentially a project set-up with Grunt so you can just add whichever Grunt modules you need. If you are unfamiliar with Grunt, you can read the documentation here.
Essentially, you can set up the Grunt configuration for your SASS task, then register the task in your generated project's Gruntfile.js:
grunt.initConfig({
sass: {
options: {
sourceMap: true
},
dist: {
files: {
'main.css': 'main.scss'
}
}
}
});
grunt.registerTask('default', ['sass']);
You should note that this Grunt module uses Node SASS for CSS compilation instead of Compass, so you may be missing out on some Compass mixins you may be used to.

Sencha Theming with Compass and Sass not working

I am trying to build a custom theme. I added the $base-color and $base_gradient properties to my resources/sass/app.scss and compiled it by issuing compass compile from the folder. The compilation worked and replaced the css/app.csss. However I am not seeing the changes reflected in my application. How do I change the theme with sass and compass?
Base gradient takes a - not a _
Then check that your var are defined after the line (should not matter for base-color but better to put them after)
#import 'sencha-touch/default/all';
Your vars should be defined like this :
$base-color: #7A1E08;
$base-gradient: 'glossy';
Check that you are in the [app-folder]/resources/sass/app.css and not in the sdk folder
When compiling you should see the following line
overwrite ../css/app.css
Empty your browser cache then reload your app.

Resources