diff --git a/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts b/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts index f96ae4382155..4a17ebb1e508 100644 --- a/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts +++ b/packages/angular_devkit/build_angular/src/webpack/configs/styles.ts @@ -186,7 +186,27 @@ export function getStylesConfig(wco: WebpackConfigOptions) { ); } if (tailwindPackagePath) { - extraPostcssPlugins.push(require(tailwindPackagePath)({ config: tailwindConfigPath })); + const tailwindConfig = require(tailwindConfigPath); + if (typeof tailwindConfig !== 'function') { + if (!tailwindConfig.purge) { + tailwindConfig.purge = {}; + } + if (Array.isArray(tailwindConfig.purge)) { + tailwindConfig.purge = { + content: [...tailwindConfig.purge], + }; + } + if (typeof tailwindConfig.purge.enabled === 'undefined') { + tailwindConfig.purge.enabled = !!buildOptions.optimization?.styles.minify; + } + + } else { + wco.logger.warn( + `Tailwind CSS configuration file export function instead of object.` + + ` To enable Purge in Tailwind CSS, please make sure to export an object.`, + ); + } + extraPostcssPlugins.push(require(tailwindPackagePath)(tailwindConfig)); } } diff --git a/tests/legacy-cli/e2e/tests/build/styles/tailwind.ts b/tests/legacy-cli/e2e/tests/build/styles/tailwind.ts index 00818606c932..ea5be365e0eb 100644 --- a/tests/legacy-cli/e2e/tests/build/styles/tailwind.ts +++ b/tests/legacy-cli/e2e/tests/build/styles/tailwind.ts @@ -1,6 +1,7 @@ -import { deleteFile, expectFileToMatch, writeFile } from '../../../utils/fs'; +import { deleteFile, expectFileToMatch, replaceInFile, writeFile } from '../../../utils/fs'; import { installPackage, uninstallPackage } from '../../../utils/packages'; import { ng, silentExec } from '../../../utils/process'; +import { updateJsonFile } from '../../../utils/project'; import { expectToFail } from '../../../utils/utils'; export default async function () { @@ -14,12 +15,18 @@ export default async function () { // Create configuration file await silentExec('npx', 'tailwindcss', 'init'); + await replaceInFile('tailwind.config.js', `purge: [],`, `purge: ['./src/**/*.{html,ts}'],`); + await updateJsonFile('angular.json', json => { + json.projects['test-project'].architect.build.configurations.production.budgets = [ + { type: 'all', maximumError: '100mb' }, + ]; + }); // Add Tailwind directives to a component style - await writeFile('src/app/app.component.css', '@tailwind base; @tailwind components;'); + await writeFile('src/app/app.component.css', '@tailwind base; @tailwind components; @tailwind utilities'); // Add Tailwind directives to a global style - await writeFile('src/styles.css', '@tailwind base; @tailwind components;'); + await writeFile('src/styles.css', '@tailwind base; @tailwind components; @tailwind utilities'); // Build should succeed and process Tailwind directives await ng('build'); @@ -28,19 +35,66 @@ export default async function () { await expectFileToMatch('dist/test-project/styles.css', /::placeholder/); await expectFileToMatch('dist/test-project/main.js', /::placeholder/); await expectToFail(() => - expectFileToMatch('dist/test-project/styles.css', '@tailwind base; @tailwind components;'), + expectFileToMatch('dist/test-project/styles.css', '@tailwind base; @tailwind components; @tailwind utilities'), ); await expectToFail(() => - expectFileToMatch('dist/test-project/main.js', '@tailwind base; @tailwind components;'), + expectFileToMatch('dist/test-project/main.js', '@tailwind base; @tailwind components; @tailwind utilities'), ); + + await writeFile('src/app/app.component.html', '