diff --git a/CHANGELOG.md b/CHANGELOG.md index 879ed210eea2..270fc089d6e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +### Fixed + +- Try resolving `config.default` before `config` to ensure the config file is resolved correctly ([#10898](https://github.com/tailwindlabs/tailwindcss/pull/10898)) ## [3.3.0] - 2023-03-27 diff --git a/integrations/execute.js b/integrations/execute.js index f5ab2131804a..6c5f2036327d 100644 --- a/integrations/execute.js +++ b/integrations/execute.js @@ -3,6 +3,8 @@ let path = require('path') let { spawn } = require('child_process') let resolveToolRoot = require('./resolve-tool-root') +let SHOW_OUTPUT = false + let runningProcessess = [] afterEach(() => { @@ -92,6 +94,9 @@ module.exports = function $(command, options = {}) { let combined = '' child.stdout.on('data', (data) => { + if (SHOW_OUTPUT) { + console.log(data.toString()) + } stdoutMessages.push(data.toString()) notifyNextStdoutActor() stdout += data @@ -99,6 +104,9 @@ module.exports = function $(command, options = {}) { }) child.stderr.on('data', (data) => { + if (SHOW_OUTPUT) { + console.error(data.toString()) + } stderrMessages.push(data.toString()) notifyNextStderrActor() stderr += data diff --git a/integrations/parcel/tests/integration.test.js b/integrations/parcel/tests/integration.test.js index 0fc539f37eec..55e7f83a38b0 100644 --- a/integrations/parcel/tests/integration.test.js +++ b/integrations/parcel/tests/integration.test.js @@ -3,11 +3,12 @@ let { css, html, javascript } = require('../../syntax') let { env } = require('../../../lib/lib/sharedState') let { - readOutputFile, appendToInputFile, - writeInputFile, - waitForOutputFileCreation, + readOutputFile, + removeFile, waitForOutputFileChange, + waitForOutputFileCreation, + writeInputFile, } = require('../../io')({ output: 'dist', input: 'src' }) describe('static build', () => { @@ -32,6 +33,132 @@ describe('static build', () => { ` ) }) + + it('can use a tailwind.config.js configuration file with ESM syntax', async () => { + await removeFile('tailwind.config.js') + await writeInputFile( + 'index.html', + html` + +
+ ` + ) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.js', + javascript` + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } + ` + ) + + await $('parcel build ./src/index.html --no-cache', { + env: { NODE_ENV: 'production' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) + + it('can use a tailwind.config.ts configuration file', async () => { + await removeFile('tailwind.config.js') + await writeInputFile( + 'index.html', + html` + +
+ ` + ) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.ts', + javascript` + import type { Config } from 'tailwindcss' + + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } satisfies Config + ` + ) + + await $('parcel build ./src/index.html --no-cache', { + env: { NODE_ENV: 'production' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile(/index\.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) }) describe('watcher', () => { diff --git a/integrations/rollup/tests/integration.test.js b/integrations/rollup/tests/integration.test.js index 1daea888a875..dbbfcc8d11f1 100644 --- a/integrations/rollup/tests/integration.test.js +++ b/integrations/rollup/tests/integration.test.js @@ -2,7 +2,7 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') let { env } = require('../../../lib/lib/sharedState') -let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ +let { readOutputFile, appendToInputFile, writeInputFile, removeFile } = require('../../io')({ output: 'dist', input: 'src', }) @@ -27,6 +27,120 @@ describe('static build', () => { ` ) }) + + it('can use a tailwind.config.js configuration file with ESM syntax', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.js', + javascript` + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } + ` + ) + + await $('rollup -c', { + env: { NODE_ENV: 'production' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) + + it('can use a tailwind.config.ts configuration file', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.ts', + javascript` + import type { Config } from 'tailwindcss' + + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } satisfies Config + ` + ) + + await $('rollup -c', { + env: { NODE_ENV: 'production' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('index.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) }) describe('watcher', () => { diff --git a/integrations/tailwindcss-cli/tests/integration.test.js b/integrations/tailwindcss-cli/tests/integration.test.js index ff8db20b8a2d..6efa9fdf5e44 100644 --- a/integrations/tailwindcss-cli/tests/integration.test.js +++ b/integrations/tailwindcss-cli/tests/integration.test.js @@ -3,7 +3,7 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') let { env } = require('../../../lib/lib/sharedState') -let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ +let { readOutputFile, appendToInputFile, writeInputFile, removeFile } = require('../../io')({ output: 'dist', input: 'src', }) @@ -111,6 +111,120 @@ describe('static build', () => { } }) + it('can use a tailwind.config.js configuration file with ESM syntax', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.js', + javascript` + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } + ` + ) + + await $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css', { + env: { NODE_ENV: 'production' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) + + it('can use a tailwind.config.ts configuration file', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.ts', + javascript` + import type { Config } from 'tailwindcss' + + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } satisfies Config + ` + ) + + await $('node ../../lib/cli.js -i ./src/index.css -o ./dist/main.css', { + env: { NODE_ENV: 'production' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) + it('can read from a config file from an @config directive', async () => { await writeInputFile('index.html', html`
`) await writeInputFile( diff --git a/integrations/vite/tests/integration.test.js b/integrations/vite/tests/integration.test.js index 1e5cd2d3345e..a07a2a9a6efc 100644 --- a/integrations/vite/tests/integration.test.js +++ b/integrations/vite/tests/integration.test.js @@ -4,7 +4,7 @@ let $ = require('../../execute') let { css, html, javascript } = require('../../syntax') let { env } = require('../../../lib/lib/sharedState') -let { readOutputFile, appendToInputFile, writeInputFile } = require('../../io')({ +let { readOutputFile, appendToInputFile, writeInputFile, removeFile } = require('../../io')({ output: 'dist', input: '.', }) @@ -42,6 +42,116 @@ describe('static build', () => { ` ) }) + + it('can use a tailwind.config.js configuration file with ESM syntax', async () => { + await writeInputFile( + 'index.html', + html` + +
+ ` + ) + await removeFile('tailwind.config.js') + await writeInputFile( + 'tailwind.config.js', + javascript` + export default { + content: ['index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } + ` + ) + + await $('vite build', { + env: { NODE_ENV: 'production', NO_COLOR: '1' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile(/index.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile(/index.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) + + it('can use a tailwind.config.ts configuration file', async () => { + await writeInputFile( + 'index.html', + html` + +
+ ` + ) + await removeFile('tailwind.config.js') + await writeInputFile( + 'tailwind.config.ts', + javascript` + import type { Config } from 'tailwindcss' + + export default { + content: ['index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } satisfies Config + ` + ) + + await $('vite build', { + env: { NODE_ENV: 'production', NO_COLOR: '1' }, + }) + + if (!env.OXIDE) { + expect(await readOutputFile(/index.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile(/index.\w+\.css$/)).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) }) describe('watcher', () => { diff --git a/integrations/webpack-4/tests/integration.test.js b/integrations/webpack-4/tests/integration.test.js index 6bbf3f879fcd..a666721bbdc1 100644 --- a/integrations/webpack-4/tests/integration.test.js +++ b/integrations/webpack-4/tests/integration.test.js @@ -3,11 +3,12 @@ let { css, html, javascript } = require('../../syntax') let { env } = require('../../../lib/lib/sharedState') let { - readOutputFile, appendToInputFile, - writeInputFile, - waitForOutputFileCreation, + readOutputFile, + removeFile, waitForOutputFileChange, + waitForOutputFileCreation, + writeInputFile, } = require('../../io')({ output: 'dist', input: 'src' }) describe('static build', () => { @@ -24,6 +25,116 @@ describe('static build', () => { ` ) }) + + it('can use a tailwind.config.js configuration file with ESM syntax', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.js', + javascript` + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } + ` + ) + + await $('webpack --mode=production') + + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) + + it('can use a tailwind.config.ts configuration file', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.ts', + javascript` + import type { Config } from 'tailwindcss' + + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } satisfies Config + ` + ) + + await $('webpack --mode=production') + + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) }) describe('watcher', () => { diff --git a/integrations/webpack-5/tests/integration.test.js b/integrations/webpack-5/tests/integration.test.js index fde0d60c5364..ae493fbdbb66 100644 --- a/integrations/webpack-5/tests/integration.test.js +++ b/integrations/webpack-5/tests/integration.test.js @@ -3,11 +3,12 @@ let { css, html, javascript } = require('../../syntax') let { env } = require('../../../lib/lib/sharedState') let { - readOutputFile, appendToInputFile, - writeInputFile, - waitForOutputFileCreation, + readOutputFile, + removeFile, waitForOutputFileChange, + waitForOutputFileCreation, + writeInputFile, } = require('../../io')({ output: 'dist', input: 'src' }) describe('static build', () => { @@ -24,6 +25,116 @@ describe('static build', () => { ` ) }) + + it('can use a tailwind.config.js configuration file with ESM syntax', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.js', + javascript` + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } + ` + ) + + await $('webpack --mode=production') + + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) + + it('can use a tailwind.config.ts configuration file', async () => { + await removeFile('tailwind.config.js') + await writeInputFile('index.html', html`
`) + await writeInputFile( + 'index.css', + css` + @tailwind base; + @tailwind components; + @tailwind utilities; + ` + ) + await writeInputFile( + '../tailwind.config.ts', + javascript` + import type { Config } from 'tailwindcss' + + export default { + content: ['./src/index.html'], + theme: { + extend: { + colors: { + primary: 'black', + }, + }, + }, + corePlugins: { + preflight: false, + }, + } satisfies Config + ` + ) + + await $('webpack --mode=production') + + if (!env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); + } + ` + ) + } + + if (env.OXIDE) { + expect(await readOutputFile('main.css')).toIncludeCss( + css` + .bg-primary { + background-color: black; + } + ` + ) + } + }) }) describe('watcher', () => { diff --git a/src/lib/load-config.ts b/src/lib/load-config.ts index 89ce3a368d0b..645e8e1d55c4 100644 --- a/src/lib/load-config.ts +++ b/src/lib/load-config.ts @@ -19,9 +19,13 @@ function lazyJiti() { } export function loadConfig(path: string): Config { - try { - return path ? require(path) : {} - } catch { - return lazyJiti()(path) - } + let config = (function () { + try { + return path ? require(path) : {} + } catch { + return lazyJiti()(path) + } + })() + + return config.default ?? config }