I am trying to get tailwind to purge CSS on my files, but I can't seem to get it working.
To provide some context, I have a public folder that contains a CSS folder and a views folder. I am trying to purge the single ejs file within the views folder.
Here is my tailwind.config.js
module.exports = {
purge: {
enabled: true,
content: ['./public/**/*.ejs']
},
theme: {},
variants: {},
plugins: [],
}
Here is my postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
Here is my script I'm running from my package.json
"tw-prod": "tailwind build public/css/tailwind.css -o public/css/style.css"
I have also tried the following, without any luck
"tw-prod": "postcss public/css/tailwind.css -o public/css/style.css"
And finally here is some code from my app.js which may help diagnose my problem
app.use(express.static("public"));
app.set("view engine", "ejs");
app.set('views', path.join(__dirname, '/public/views'));
Each time I run the build script, the size of the stylesheet remains the same at 3.81mb. Can anyone tell me what I'm doing wrong here, please?
Did you try running the script with NODE_ENV=production?
like
NODE_ENV=production npx tailwindcss -i ./src/tailwind.css -o ./dist/tailwind.css
EDIT:
Instead of running
"tw-prod": "tailwind build public/css/tailwind.css -o public/css/style.css"
run this
"tw-prod": "NODE_ENV=production tailwind build public/css/tailwind.css -o public/css/style.css"
Tailwind requires the NODE_ENV to be set for the purge function to kick in and do its job.
Read more about this here
PS: BTS postcss file now comes configured by default that I guess takes care of this purging functionality
Related
I want sass linter in Gatsby's project
plugins: [
`gatsby-plugin-styled-components`,
{
resolve: `gatsby-source-contentful`,
options: {
},
},
{
resolve: "gatsby-plugin-eslint",
options: {
},
},
`gatsby-plugin-sass`
],
How to include it?
I want to detect incorrect CSS rules etc...
ESlint is a JavaScript linter, so it can't analyze nor lint your Sass code.
However, you can use Stylelint to parse SCSS, Saas, or CSS files.
You can follow the default configuration steps in their GitHub:
Install it by:
npm install --save --dev #primer/stylelint-config
Add a stylelintrc.json file in the root of your project (it can be a .yml or .js format too if needed)
Add your configuration rules. You can inherit from the default ones by using the extends rule as:
{
"extends": "stylelint-config-standard",
"rules": {
"indentation": "tab",
"number-leading-zero": null
}
}
Customize your commands to trigger your lint rules (change the file extension accordingly):
npx stylelint "**/*.css"
Resources:
https://stylelint.io/user-guide/get-started
https://dev.to/stories_of_ren/switching-from-sass-lint-to-stylelint-5f8c
Has anyone managed to get Tailwind.css working with Gatsby.js?
Configuring postCSS plugins with Gatsby is a bit tricky... If anyone has managed to get Tailwind up and running with Gatsby, I'd love to know how!
I managed to get this working (including hot reloading) thanks to this post.
Basically I had to install postcss and autoprefixer additionally:
npm install autoprefixer postcss-cli
I added a postcss.config.js to the root of my Gatsby site folder with this content (tailwind.js is my Tailwind config - yours might be named differently):
const tailwindcss = require('tailwindcss');
module.exports = {
plugins: [
tailwindcss('./tailwind.js'),
require('autoprefixer'),
],
};
Then I added a CSS watch and build script to my package.json, and included these scripts in my default develop and build scripts:
"scripts": {
"build:css": "postcss src/layouts/index.css -o src/layouts/generated.css",
"watch:css": "postcss src/layouts/index.css -o src/layouts/generated.css -w",
"build": "npm run build:css && gatsby build",
"develop": "npm run watch:css & gatsby develop",
...
}
(Please note the input (index.css) and output (generated.css) filenames and locations for my css are specific to my project. Feel free to use your own convention.)
Let me know, if this works for you.
As a supplement to morgler's answer, here is a similar solution I ended up with (which includes Sass and PurgeCSS).
I went with a CLI solution because gatsby-plugin-postcss-sass currently runs PostCSS before Sass (which breaks Tailwind), and Gatsby's PostCSS plugins are a bit difficult to configure via Webpack at the moment.
I included Sass so I can break main.sass into more manageable partials, and added PurgeCSS so I can remove any unused Tailwinds classes in production. I've found that PurgeCSS is more effective than PurifyCSS, which is why I opted not to use gatsby-plugin-purify-css.
To begin, create a src/styles folder with the following structure (feel free to customize this for your project and adapt the settings below accordingly):
src/
styles/
builds/
after-postcss/
main.css
after-purgecss/
main.css
after-sass/
main.css
// other subfolders for sass partials...
main.sass
Install the necessary dependencies:
npm i node-sass-chokidar postcss-cli purgecss
Add the following to gatsby-node.js (to disable Gatsby's default PostCSS plugins):
const ExtractTextPlugin = require('extract-text-webpack-plugin')
exports.modifyWebpackConfig = ({ config, stage }) => {
switch (stage) {
case 'develop':
// Remove postcss from Gatsby's dev process:
config.removeLoader(`css`)
config.loader(`css`, {
test: /\.css$/,
loaders: [`style`, `css`]
})
break
case 'build-css':
// Remove postcss from Gatsby's build process:
config.removeLoader(`css`)
config.loader(`css`, {
test: /after-purgecss\/main\.css/,
loader: ExtractTextPlugin.extract([`css?minimize`])
})
break
}
return config
}
Add a postcss.config.js file to the project root:
const tailwind = require('tailwindcss')
const cssnext = require('postcss-cssnext')
module.exports = {
plugins: [
// your file's name or path may differ:
tailwind('./src/styles/tailwind.config.js'),
cssnext()
// add any other postcss plugins you like...
]
}
Add the following scripts to package.json:
"scripts": {
"watch:sass": "node-sass-chokidar --source-map true src/styles/main.sass -o src/styles/builds/after-sass -w",
"watch:postcss": "postcss src/styles/builds/after-sass/main.css -o src/styles/builds/after-postcss/main.css -w",
"watch:styles": "npm run watch:sass & npm run watch:postcss",
"build:sass": "node-sass-chokidar src/styles/main.sass -o src/styles/builds/after-sass",
"build:postcss": "postcss src/styles/builds/after-sass/main.css -o src/styles/builds/after-postcss/main.css",
"build:purgecss":
"purgecss --css src/styles/builds/after-postcss/main.css --con public/index.html src/**/*.js -o src/styles/builds/after-purgecss",
"build:styles": "npm run build:sass && npm run build:postcss && npm run build:purgecss",
"develop": "gatsby develop & npm run watch:styles",
"build": "npm run build:styles && gatsby build"
// ...
},
In development, run npm run develop instead of gatsby develop. The watch: scripts will run Sass + PostCSS (in that order) whenever a change is made to main.sass or any of its imports.
To build the site, run npm run build instead of gatsby build. The build: scripts will run Sass + PostCSS (without the watch tasks) + PurgeCSS (in that order).
Add the following to layouts/index.js to import the after-postcss version of main.css during development and the after-purgecss version during production:
switch (process.env.NODE_ENV) {
case `development`:
require('../styles/builds/after-postcss/main.css')
break
case `production`:
require('../styles/builds/after-purgecss/main.css')
break
}
Hope that helps someone! If anyone knows how to convert this into a Webpack equivalent that works with Gatsby, please feel free to post it here.
I recently added it on top of the Gatsby starter default and wrote a detailed step by step guide.
https://www.michaelfasani.com/2020/installing-tailwind-css-on-top-of-the-gatsby-starter-default/
That's my setup and is working perfectly fine with Gatsby:
tailwind.config.js
module.exports = {
mode: "jit",
purge: [
"./src/pages/**/*.{js,ts,jsx,tsx}",
"./src/components/**/*.{js,ts,jsx,tsx}",
],
package.json
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
"build": "gatsby build",
"serve": "gatsby serve",
"clean": "gatsby clean",
"tw:build": "tailwindcss build ./src/styles/global.css -o ./public/styles/global.css",
"tw:prod": "cross-env NODE_ENV=production postcss build ./src/styles/global.css -o ./public/styles/global.css",
"tw:watch": "onchange \"tailwind.config.js\" \"src/**/*.css\" -- npm run tw:build"
},
You can also use cssnano it's an awsome extension for purging tailwind css
postcss.config.js
const cssnano = require("cssnano");
module.exports = {
plugins: [
require("tailwindcss"),
cssnano({
preset: "default",
}),
require("autoprefixer"),
],
};
Also the devDependencies that are needed for the latest Tailwind version are these:
package.json devDependencies
"devDependencies": {
"autoprefixer": "^10.3.6",
"gatsby-plugin-postcss": "^4.14.0",
"postcss": "^8.3.9",
"postcss-cli": "^9.0.1",
"tailwindcss": "^2.2.17"
}
}
Also make sure to include these on top of the global.css file:
#tailwind base;
#tailwind components;
#tailwind utilities;
In my package.json I've changed a few things:
"scripts": {
"build-css": "node-sass-chokidar ./static/style.scss ./static/style.css",
"watch-css": "npm run build-css && node-sass-chokidar ./static/style.scss ./static/style.css --watch --recursive",
"dev": "npm-run-all -p watch-css next",
"next": "next",
"build": "next build",
"start": "next start"
},
Because I much prefer a single SASS file containing all styles, until a solution is found to make a require('./style.scss'); work server-side and client-side.
The stylesheet is parsed and output as a single CSS-file while developing, just fine. I just need to reload the entire page to see my changes. That's a little bit of a drag, of course.
So I created a next.config.js file and added this:
const path = require('path');
const glob = require('glob');
const node_modules_dir = path.resolve(__dirname, 'node_modules');
module.exports = {
webpack: (config, { dev }) => {
config.module.rules.push(
{
test: /\.(css|scss)/,
exclude: [node_modules_dir],
loaders: [
'style-loader',
'css-loader',
'postcss-loader'
]
}
);
return config
}
};
And next.js is running in my terminal just fine, and the SCSS-file is parsed into a CSS-file just fine, too. Just, no client-side live-reload. I was expecting adding this to the config file would be sufficient to live-reload a CSS-file.
In my components/Page I've added this line:
<Head>
<title>{title}</title>
<link rel="stylesheet" type="text/css" href="/static/style.css" />
</Head>
But I'm not too familiar with hot-reload/live-reload inner workings.
What am I doing wrong?
I'm trying to use Webpack instead of Gulp as a task runner, in this case simply compiling all SCSS files as I was doing it with Compass before. The main objectives are:
run Autoprefixer and generate separate CSS file for each SCSS that is not a partial
don't bundle images or concatenate CSS files
keep image urls as is, e.g. background-image: url(assets/image.png)
don't throw errors if images cannot be found
#1 is solved and working, however it stops working and throws an error as soon as the SCSS links to an image as in #3 above:
ERROR in ./~/css-loader!./~/postcss-loader!./~/sass-loader/lib/loader.js!./scss/style.scss
Module not found: Error: Can't resolve './assets/image.png' in 'C:\Users\robro\projects\...\my-project\dev\styles\scss
# ./~/css-loader!./~/postcss-loader!./~/sass-loader/lib/loader.js!./scss/style.scss 6:15328-15369
# ./scss/style.scss
I'd like to "simply" ignore that error and not having to copy the missing files to my local hard drive. That's mostly just me being stubborn, thinking "Compass didn't need those images to be present, why does Webpack?"
Here's my setup:
webpack.config.js
const ExtractTextPlugin = require("extract-text-webpack-plugin");
var ExtractCSS = new ExtractTextPlugin('css/[name]');
module.exports = {
entry: {
'style.css': './scss/style.scss',
'admin.css': './scss/admin.scss'
},
output: {
filename: './css/[name]'
},
module: {
rules: [
{
test: /\.scss$/,
use: ExtractCSS.extract({
fallback: "style-loader",
use: [
"css-loader",
"postcss-loader",
"sass-loader"
]
})
},
{ test: /\.(jpg|jpeg|png|svg|gif|woff|woff2|otf|ttf)$/, use: 'ignore-loader' }
]
},
plugins: [
ExtractCSS
],
watch: true
};
package.json
{
"dependencies": {},
"devDependencies": {
"css-loader": "^0.26.1",
"extract-text-webpack-plugin": "^2.0.0-rc.3",
"ignore-loader": "^0.1.2",
"node-sass": "^4.5.0",
"postcss-loader": "^1.3.0",
"sass-loader": "^6.0.0",
"style-loader": "^0.13.1",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.3.0"
}
}
As you can see, i tried using ignore-loader to stop sass-loader from complaining about missing images, but to no avail. To be honest, I'm not even sure this is how it's intended to be used.
As soon as I remove any line that links to images from the SCSS, everything is working just fine: style.css and admin.css get built, autoprefixed and dropped into css/ folder. Now I want to keep it that way, but also use styles like background-image: url(assets/image.png) without webpack complaining about those images not being present on the file system.
Case closed: Webpack is NOT a task runner. Blog posts naming Webpack as a successor to Grunt or Gulp or fail to explicitly point out that these tools may have some overlapping features but in the end have very different goals. Grunt and Gulp are task runners and Webpack is an asset bundler. Trying to make Webpack not bundle your assets defeats it's main purpose and one's better off choosing a different tool.
I am trying to take my front-end workflow a step higher with Grunt tasks.
I have set up a couple of tasks in my Gruntfile.js. For now there are only grunt-contrib-sass and grunt-contrib-watch so that .css files are automatically recompiled whenever I make a change to my .sass files.
What I want to achieve is the following:
I want to add a task that would listen to my local server that was started with UniServerZ/XAMPP/WAMP or any other provider. I want to trigger a reload each time I edit any file in the server base directory.
I know that it is quite easy to set up such a task with, e.g. 'grunt-express' which starts a local server for you, but I really want to listen to a server started with UniServerZ/XAMPP/WAMP.
I will be grateful to see example configuration for such scenario if it is possible to achieve it.
Here is how I did it with Wamp 2.2 on Windows 7.
First, you need grunt-contrib-watch properly setup with livereload. I also use grunt-sass and not grunt-contrib-sass, because grunt-sass use Libsass. LibSass is a C/C++ port of the Sass engine, and it is faster.
To install them, use these commands :
npm install grunt-contrib-watch --save-dev
npm install grunt-sass --save-dev
Here is an example of Gruntfile :
module.exports = function(grunt) {
grunt.initConfig({
watch: {
sass: {
files: 'folder/to/your/sass/**/*.sass',
tasks: ['sass:dist'],
options: {
livereload: true,
},
},
//Watch your theme files
livereload: {
files: ['pathToTheme/*.php', 'pathToTheme/img/**/*.{png,jpg,jpeg,gif,webp,svg}'],
options: {
livereload: true
},
}
},
sass: {
options: {
includePaths: ['where/to/find/additional/#import/scss/files'],
outputStyle: 'nested',
imagePath: 'how/to/rewrite/image/path',
sourceMap: true
},
dist: {
files: {
'output/file.css': 'input/file.scss'
}
}
},
});
// Default task
grunt.registerTask('default', ['watch']);
// Load NpmTask
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
};
You could save yourself some time with load-grunt-tasks, and remove the manual loading of task :
require('load-grunt-tasks')(grunt); // npm install --save-dev load-grunt-tasks
Then I use the livereload plugin for firefox (or chrome or safari).
Start the grunt watch task, open your site on localhost, and click on the icon in your browser. Now if you edit a watched file, the page should update accordingly.
A solution exist to add the livereload js in your Wordpress automatically (in function.php):
if (in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))) {
wp_register_script('livereload', 'http://localhost:35729/livereload.js?snipver=1', null, false, true);
wp_enqueue_script('livereload');
}