Middleman + TailwindCSS + Webpack
Mario
Posted on July 2, 2019
I really enjoy using Middleman for some websites that I maintain. For one of my projects I wanted to include TailwindCSS and started googling how to do that. I found this guide but it seemed bit outdated.
This got me inspired to write an updated version.
So, in this guide I'm trying to describe how I managed setting up a middleman project and integrate TailwindCSS using Webpack.
It uses these versions:
- Middleman
4.3.4
- Tailwind
1.0.4
- Webpack
4.35.2
Disclaimer: I am not an expert with Webpack etc. So the following instructions may be inaccurate, incomplete or misleading. I hope it's not too bad though, please comment if you feel something is terribly wrong.
Here we go...
Setup a Middleman project
Firstly, install Middleman and create a project
gem install middleman
middleman init project
cd ./project
middleman serve
Once middleman serve
is running you should see a default page on http://localhost:4567
. You may abort the process again since we're going to change some configurations now...
Also, from now on this guide assumes that the working directory is the project's root directory.
(These instructions were taken from the Middleman installation page)
Add Livereload (Optional)
Livereload automatically reloads the page in the browser every time we change something in the code, which can be useful later.
- Add
gem 'middleman-livereload'
to./Gemfile
- Add
activate :livereload
to./config.rb
- Run
bundle install
(These instructions were taken from the Middleman Basics page)
Add npm packages
Now we get to the first part where I don't have much knowledge about. After some experimenting I concluded this list of packages
yarn init
yarn add autoprefixer css-loader mini-css-extract-plugin postcss postcss-import postcss-loader style-loader tailwindcss webpack webpack-cli
(You may substitute yarn
with npm
. Use npm install
instead of yarn add
)
Prepare CSS file
Middleman comes with SCSS, but I decided to not use SCSS together with Tailwind. That's why I renamed the stylesheet's filename:
mv ./source/stylesheets/site.css.scss ./source/stylesheets/site.css
Then I changed the content of ./source/stylesheets/site.css
to this:
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
body {
@apply bg-red-500;
}
This imports the Tailwind definitions and applies a rule to the body
tag using Tailwind's @apply
directive. At the end of this guide we expect the background color of the page to be red(-ish).
(This instruction was taken from the Tailwind's installation page)
Create postcss.config.js
Next we're going to create a file ./postcss.config.js
with this content:
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('autoprefixer'),
]
}
(This instruction was taken from the Tailwind's installation page)
Configure webpack
To me, configuring webpack was the most difficult part. There are a lot of examples for this on the interwebs and as a JS-noob I couldn't make clear which way is the best. But here's what I came up with.
Create a file ./webpack.config.js
with this content:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin()
],
entry: {
application: './source/javascripts/site.js',
styles: './source/stylesheets/site.css',
},
output: {
path: __dirname + '/.tmp/dist',
filename: '[name].js',
},
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',
'postcss-loader',
]
}
]
}
}
While I created this file I made several observations that I'd like to share:
- The keys in
entry: { ... }
(application
andstyles
) will be used as filenames. So there will be a file namedapplication.js
and one namedstyles.js
(yes... the styles file's extension is going to be.js
, I guess it won't be used though, may be I can get rid of it somehow?) -
output.path
apparently has to be/.tmp/dist
(!), otherwise Middleman won't use it in development? - Lastly, the rule for
.css
files is more or less copy/pasted fromMiniCssExtractPlugin
project page. I assume this plugin is responsible for processing/creating astyles.css
file in the output path? Note that this plugin replaces a plugin namedextract-text-webpack-plugin
.
You see, in this area I have multiple question marks. So if you have corrections, I invite you to post them in the comments.
Activate Webpack as :external_pipeline
Now let's hook up webpack to the Middleman pipeline.
Add these lines to ./config.rb
activate :external_pipeline,
name: :webpack,
command: build? ? './node_modules/webpack/bin/webpack.js --bail' : './node_modules/webpack/bin/webpack.js --watch -d --color',
source: ".tmp/dist",
latency: 1
This ensures that webpack runs as soon as anything changes in the project during development or when we build the project.
(This instruction was taken from the Middleman Documentation)
Change stylesheet and javascript paths in ./source/layouts/layout.erb
Remember that we configured webpack so we get a file named application.js
and one named styles.css
as outputs? We need to change these filenames in the head
section of the page.
In ./source/layouts/layout.rb
change
<%= stylesheet_link_tag "site" %>
<%= javascript_include_tag "site" %>
to
<%= stylesheet_link_tag "styles" %>
<%= javascript_include_tag "application" %>
Moment of truth...
Run
middleman serve
Check whether the background of the page at http://localhost:4567
is red(-ish). If so, this guide is trustworthy and you can happily start using Tailwind in your project. If not, put the blame on me and share your experience.
Credits
Cover image by Marco Verch
Posted on July 2, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.