First of all, congrats in the new 1.4 release, the new purge option is awesome!
Recently I used it in a project built with Parcel and worked like a charm. However, I cannot make it work in another project built with webpack. Previously I was using the webpack PurgecssPlugin configuration, now I removed it and expected it to work with the following configuration:
// tailwind.config.js
module.exports = {
purge: ['./src/**/*.html', './src/**/*.tsx'],
theme: {},
variants: {},
plugins: [],
};
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
// ...
},
{
test: /\.css$/,
use: [
{loader: MiniCssExtractPlugin.loader},
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: false,
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: [require('tailwindcss'), require('autoprefixer')],
},
},
],
},
],
}
}
I've tried removing the other loaders in case they interfered in any way, with no luck.
Am I missing something? 🤔
Thanks in advance.
Same - can I help?
Can you create a project that reproduces to help me troubleshoot?
@adamwathan Sure! Here it is: https://github.com/lewislbr/tailwind-purge-webpack
The issue is that webpack doesn't set process.env.NODE_ENV for some stupid reason:
https://github.com/webpack/webpack/issues/7074
So just update your production build scripts to set it yourself:
rm -rf dist && NODE_ENV=production webpack --mode=production
Thanks for looking into this @adamwathan, that is the issue indeed! For some reason declaring NODE_ENV=production in the script didn't worked for me, so I did this instead in webpack.config.js:
module.exports = (env, options) => {
const isDevelopment = options.mode !== 'production';
process.env.NODE_ENV = options.mode;
// ...
I can also confirm that the webpack-workaround by manually assigning process.env.NODE_ENV = argv.mode; (or export NODE_ENV=production in the shell before calling webpack) fixes this issue.
I guess this can be closed.
Maybe an entry in the "Controlling File Size" docs could help lots of other people? Although this is not a tailwindcss issue in itself, I found the postcss-import note in the "Installation" documentation pretty useful as well.
Yeah, it can be closed. And the idea to add an entry in the docs is really great 👌
For what it's worth, am having the same problem (no purge functionality unless enabled is set to true) in a non-webpack, non-bundler repo, although it's still very much a work in progress so not public yet.
Contents of tailwind.config.js:
module.exports = {
purge: {
content: [
'./src/**/*.js',
'./src/**/*.11ty.js',
],
},
theme: {
fontFamily: {
body: ['Public Sans', 'system-ui'],
code: ['Roboto Mono', 'monospace'],
},
},
variants: {},
plugins: [],
}
...of postcss.config.js:
module.exports = {
plugins: [
require('postcss-import'),
require('tailwindcss'),
require('postcss-preset-env')({ stage: 1 }),
require('postcss-clean'),
],
}
...and scripts in package.json:
"test": "echo \"Error: no test specified\" && exit 1",
"clean": "rm -rf _site",
"start": "npm-run-all clean --parallel dev:*",
"dev:postcss": "postcss src/assets/css/index.css -d _site/css/ --config ./postcss.config.js -w",
"dev:eleventy": "ELEVENTY_ENV=development npx @11ty/eleventy --watch --quiet",
"dev:bsync": "browser-sync start --server ./_site -w --no-open --no-notify --no-ghost-mode",
"build": "npm-run-all clean --parallel prod:*",
"prod:postcss": "postcss src/assets/css/index.css -d _site/css/ --config ./postcss.config.js",
"prod:eleventy": "ELEVENTY_ENV=production npx @11ty/eleventy --output=./_site",
"testProd:postcss": "postcss src/assets/css/index.css -d _site/css/ --config ./postcss.config.js -w",
"testProd:bsync": "browser-sync start --server ./_site -w --no-open --no-notify --no-ghost-mode",
"testProd:eleventy": "ELEVENTY_ENV=production npx @11ty/eleventy --output=./_site --watch",
"testProd:setProd": "NODE_ENV=production",
"testbuild": "npm-run-all clean --parallel testProd:*"
Probably a case of PEBKAC on my part but I found the similarities here curious. (I also couldn't get it to work in a webpack-using repo with a similar testProd:setProd script as above.)
@brycewray I had a similar problem, I thought cause maybe vue-cli, but final thing that fixed it was adding export before NODE_ENV=production in build script.
export NODE_ENV=production
Thanks, @humenick! Unfortunately, however, that didn't work for me; still no purge happening unless I set enable to true. Perhaps there's an issue in here somewhere beyond just webpack, but it's early in the TW/Purge "marriage," so that's certainly understandable.
@brycewray Try updating your build script like this perhaps?
"build": "NODE_ENV=production npm-run-all clean --parallel prod:*",
@adamwathan Thanks! And sorry, I should've been clearer: actually this is for the testBuild script for just local tests; but I did try your suggestion with testBuild:
"testbuild": "NODE_ENV=production npm-run-all clean --parallel testProd:*"
However, still no Purge; resulting CSS file is 1.7 MB. When I set Purge enabled to true, it works fine; CSS is 22 KB.
Messy though it is, I've made the repo/branch public if you'd like a look-see:
https://github.com/brycewray/eleventy_solo/tree/tw
@brycewray Cloned it down and ran it with enabled removed and it's still purging as expected for me. I did have to run npm install --save-dev postcss-cli since it wasn't in your dependencies but used in your build scripts but otherwise didn't make any changes 🤔

Here's the complete package.json:
Expand package.json
{
"name": "eleventy_solo",
"version": "1.0.0",
"description": "",
"private": true,
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"clean": "rm -rf _site",
"start": "npm-run-all clean --parallel dev:*",
"dev:postcss": "postcss src/assets/css/index.css -d _site/css/ --config ./postcss.config.js -w",
"dev:eleventy": "ELEVENTY_ENV=development npx @11ty/eleventy --watch --quiet",
"dev:bsync": "browser-sync start --server ./_site -w --no-open --no-notify --no-ghost-mode",
"build": "npm-run-all clean --parallel prod:*",
"prod:postcss": "postcss src/assets/css/index.css -d _site/css/ --config ./postcss.config.js",
"prod:eleventy": "ELEVENTY_ENV=production npx @11ty/eleventy --output=./_site",
"testProd:postcss": "postcss src/assets/css/index.css -d _site/css/ --config ./postcss.config.js -w",
"testProd:bsync": "browser-sync start --server ./_site -w --no-open --no-notify --no-ghost-mode",
"testProd:eleventy": "ELEVENTY_ENV=production npx @11ty/eleventy --output=./_site --watch",
"setProd": "NODE_ENV=production",
"testbuild": "NODE_ENV=production npm-run-all clean --parallel testProd:*"
},
"keywords": [],
"author": "",
"license": "MIT",
"browserslist": [
"defaults",
"maintained node versions",
"> 5%"
],
"devDependencies": {
"@11ty/eleventy": "^0.10.0",
"@11ty/eleventy-plugin-rss": "^1.0.7",
"@babel/core": "^7.8.7",
"@babel/preset-env": "^7.8.7",
"@babel/register": "^7.8.6",
"autoprefixer": "^9.7.4",
"babel-core": "^6.26.3",
"babel-plugin-prismjs": "^2.0.1",
"babel-preset-env": "^1.7.0",
"browser-sync": "^2.26.7",
"cross-env": "^7.0.2",
"cssnano": "^4.1.10",
"debug": "^4.1.1",
"del": "^5.1.0",
"eleventy-plugin-error-overlay": "^0.1.2",
"eleventy-plugin-local-respimg": "^0.2.0",
"eleventy-plugin-youtube-embed": "^1.2.0",
"eleventy-rss-helper": "^1.2.1",
"fibers": "^4.0.2",
"from-env": "^1.1.4",
"glob": "^7.1.6",
"glob-all": "^3.2.1",
"inline-source-map": "^0.6.2",
"instant.page": "^3.0.0",
"lazysizes": "^5.2.0",
"lodash": "^4.17.15",
"luxon": "^1.23.0",
"markdown-it": "^10.0.0",
"markdown-it-attrs": "^3.0.2",
"markdown-it-bracketed-spans": "^1.0.1",
"markdown-it-footnote": "^3.0.2",
"markdown-it-link-attributes": "^3.0.0",
"markdown-it-prism": "^2.0.5",
"node-fetch": "^2.6.0",
"node-loader": "^0.6.0",
"npm-run-all": "^4.1.5",
"postcss": "^7.0.27",
"postcss-cli": "^7.1.1",
"postcss-css-variables": "^0.14.0",
"postcss-nesting": "^7.0.1",
"postcss-partial-import": "^4.1.0",
"postcss-preset-env": "^6.7.0",
"posthtml": "^0.12.0",
"prismjs": "^1.19.0",
"rss": "^1.2.2",
"sanitize-html": "^1.22.1",
"sharp": "^0.23.4"
},
"dependencies": {
"axios": "^0.19.2",
"dot-env": "0.0.1",
"dotenv": "^8.2.0",
"eleventy-plugin-lazyimages": "^1.1.1",
"get-json": "^1.0.1",
"html-minifier": "^4.0.0",
"jsonfile": "^6.0.1",
"md5": "^2.2.1",
"postcss-clean": "^1.1.0",
"postcss-import": "^12.0.1",
"tailwindcss": "^1.4.4"
}
}
...and the complete tailwind.config.js file:
Expand tailwind.config.js
module.exports = {
purge: {
// normally not necessary but TS 1.4 and Purge don't seem to have their stuff together
// re NODE_ENV=production, even if that's declared in the package.json script -- 2020-05-03, 10:04 AM CDT
content: ['./src/**/*.js', './src/**/*.11ty.js'],
},
theme: {
fontFamily: {
body: ['Public Sans', 'system-ui'],
codefont: ['Roboto Mono', 'monospace'],
},
},
variants: {},
plugins: [],
}
The command I ran to get these results was npm run testbuild, after adding NODE_ENV=production to the beginning of the command in the package.json file.
@adamwathan Yep, I see now — I've been going back and forth between two different repos, one with webpack and this one without it, and forgot to install postcss-cli in the second one. That was it. Un-enabled purge works now like it should. Thanks very much!
(Never got it to work in the webpack-equipped one despite trying all the fixes suggested above, but I'll look at it again later. Probably missed something silly there, too. :-)
Adam, it's fantastic how much you care and invest and take time. You're doing such a good job.
I'll second @LeoniePhiline and add that a major reason why I'm looking at TWCSS again after deciding against it earlier this year is because of @adamwathan's presentation at Laracon U.S. 2019, which I saw yesterday for the first time and impressed me greatly:
That presentation has been also my introduction to tailwind. The moment I switched from ewww to woowww. 😄
Most helpful comment
The issue is that webpack doesn't set
process.env.NODE_ENVfor some stupid reason:https://github.com/webpack/webpack/issues/7074
So just update your production build scripts to set it yourself: