Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Ensure `flex` is suggested ([#15014](https://github.com/tailwindlabs/tailwindcss/pull/15014))
- Improve module resolution for `cjs`-only and `esm`-only plugins ([#15041](https://github.com/tailwindlabs/tailwindcss/pull/15041))
- _Upgrade (experimental)_: Resolve imports when specifying a CSS entry point on the command-line ([#15010](https://github.com/tailwindlabs/tailwindcss/pull/15010))
- _Upgrade (experimental)_: Resolve nearest Tailwind config file when CSS file does not contain `@config` ([#15001](https://github.com/tailwindlabs/tailwindcss/pull/15001))
- _Upgrade (experimental)_: Improve output when CSS imports can not be found ([#15038](https://github.com/tailwindlabs/tailwindcss/pull/15038))
- _Upgrade (experimental)_: Ignore analyzing imports with external URLs (e.g.: `@import "https://fonts.google.com"`) ([#15040](https://github.com/tailwindlabs/tailwindcss/pull/15040))
- _Upgrade (experimental)_: Ignore analyzing imports with `url(…)` (e.g.: `@import url("https://fonts.google.com")`) ([#15040](https://github.com/tailwindlabs/tailwindcss/pull/15040))
- _Upgrade (experimental)_: Use `resolveJsId` when resolving `tailwindcss/package.json` ([#15041](https://github.com/tailwindlabs/tailwindcss/pull/15041))

### Changed

Expand Down
157 changes: 156 additions & 1 deletion integrations/cli/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import dedent from 'dedent'
import os from 'node:os'
import path from 'node:path'
import { describe, expect } from 'vitest'
import { candidate, css, html, js, json, test, yaml } from '../utils'
import { candidate, css, html, js, json, test, ts, yaml } from '../utils'

const STANDALONE_BINARY = (() => {
switch (os.platform()) {
Expand Down Expand Up @@ -257,6 +257,161 @@ describe.each([
await fs.expectFileToContain('dist/out.css', [candidate`underline`])
},
)

test(
'module resolution using CJS, ESM, CTS, and MTS',
{
fs: {
'package.json': json`{}`,
'pnpm-workspace.yaml': yaml`
#
packages:
- project-cjs
- project-esm
- plugin-cjs
- plugin-esm
- plugin-cts
- plugin-mts
`,
'project-cjs/package.json': json`
{
"type": "commonjs",
"dependencies": {
"tailwindcss": "workspace:^",
"@tailwindcss/cli": "workspace:^",
"plugin-cjs": "workspace:*",
"plugin-esm": "workspace:*",
"plugin-cts": "workspace:*",
"plugin-mts": "workspace:*"
}
}
`,
'project-cjs/index.html': html`
<div class="cjs esm cts mts"></div>
`,
'project-cjs/src/index.css': css`
@import 'tailwindcss/utilities';
@plugin 'plugin-cjs';
@plugin 'plugin-esm';
@plugin 'plugin-cts';
@plugin 'plugin-mts';
`,

'project-esm/package.json': json`
{
"type": "module",
"dependencies": {
"tailwindcss": "workspace:^",
"@tailwindcss/cli": "workspace:^",
"plugin-cjs": "workspace:*",
"plugin-esm": "workspace:*",
"plugin-cts": "workspace:*",
"plugin-mts": "workspace:*"
}
}
`,
'project-esm/index.html': html`
<div class="cjs esm cts mts"></div>
`,
'project-esm/src/index.css': css`
@import 'tailwindcss/utilities';
@plugin 'plugin-cjs';
@plugin 'plugin-esm';
@plugin 'plugin-cts';
@plugin 'plugin-mts';
`,

'plugin-cjs/package.json': json`
{
"name": "plugin-cjs",
"type": "commonjs",
"exports": {
".": {
"require": "./index.cjs"
}
}
}
`,
'plugin-cjs/index.cjs': js`
module.exports = function ({ addUtilities }) {
addUtilities({ '.cjs': { content: '"cjs"' } })
}
`,

'plugin-esm/package.json': json`
{
"name": "plugin-esm",
"type": "module",
"exports": {
".": {
"import": "./index.mjs"
}
}
}
`,
'plugin-esm/index.mjs': js`
export default function ({ addUtilities }) {
addUtilities({ '.esm': { content: '"esm"' } })
}
`,

'plugin-cts/package.json': json`
{
"name": "plugin-cts",
"type": "commonjs",
"exports": {
".": {
"require": "./index.cts"
}
}
}
`,
'plugin-cts/index.cts': ts`
export default function ({ addUtilities }) {
addUtilities({ '.cts': { content: '"cts"' as const } })
}
`,

'plugin-mts/package.json': json`
{
"name": "plugin-mts",
"type": "module",
"exports": {
".": {
"import": "./index.mts"
}
}
}
`,
'plugin-mts/index.mts': ts`
export default function ({ addUtilities }) {
addUtilities({ '.mts': { content: '"mts"' as const } })
}
`,
},
},
async ({ root, fs, exec }) => {
await exec(`${command} --input src/index.css --output dist/out.css`, {
cwd: path.join(root, 'project-cjs'),
})
await exec(`${command} --input src/index.css --output dist/out.css`, {
cwd: path.join(root, 'project-esm'),
})

await fs.expectFileToContain('./project-cjs/dist/out.css', [
candidate`cjs`,
candidate`esm`,
candidate`cts`,
candidate`mts`,
])
await fs.expectFileToContain('./project-esm/dist/out.css', [
candidate`cjs`,
candidate`esm`,
candidate`cts`,
candidate`mts`,
])
},
)
})

test(
Expand Down
173 changes: 172 additions & 1 deletion integrations/postcss/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import dedent from 'dedent'
import path from 'node:path'
import { expect } from 'vitest'
import { candidate, css, html, js, json, test, yaml } from '../utils'
import { candidate, css, html, js, json, test, ts, yaml } from '../utils'

test(
'production build (string)',
Expand Down Expand Up @@ -315,6 +315,177 @@ test(
},
)

test(
'module resolution using CJS, ESM, CTS, and MTS',
{
fs: {
'package.json': json`{}`,
'pnpm-workspace.yaml': yaml`
#
packages:
- project-cjs
- project-esm
- plugin-cjs
- plugin-esm
- plugin-cts
- plugin-mts
`,
'project-cjs/package.json': json`
{
"type": "commonjs",
"dependencies": {
"@tailwindcss/postcss": "workspace:^",
"plugin-cjs": "workspace:*",
"plugin-cts": "workspace:*",
"plugin-esm": "workspace:*",
"plugin-mts": "workspace:*",
"postcss": "^8",
"postcss-cli": "^10",
"tailwindcss": "workspace:^"
}
}
`,
'project-cjs/postcss.config.cjs': js`
let tailwindcss = require('@tailwindcss/postcss')
module.exports = {
plugins: [tailwindcss()],
}
`,
'project-cjs/index.html': html`
<div class="cjs esm cts mts"></div>
`,
'project-cjs/src/index.css': css`
@import 'tailwindcss/utilities';
@plugin 'plugin-cjs';
@plugin 'plugin-esm';
@plugin 'plugin-cts';
@plugin 'plugin-mts';
`,

'project-esm/package.json': json`
{
"type": "module",
"dependencies": {
"@tailwindcss/postcss": "workspace:^",
"plugin-cjs": "workspace:*",
"plugin-cts": "workspace:*",
"plugin-esm": "workspace:*",
"plugin-mts": "workspace:*",
"postcss": "^8",
"postcss-cli": "^10",
"tailwindcss": "workspace:^"
}
}
`,
'project-esm/postcss.config.mjs': js`
import tailwindcss from '@tailwindcss/postcss'
export default {
plugins: [tailwindcss()],
}
`,
'project-esm/index.html': html`
<div class="cjs esm cts mts"></div>
`,
'project-esm/src/index.css': css`
@import 'tailwindcss/utilities';
@plugin 'plugin-cjs';
@plugin 'plugin-esm';
@plugin 'plugin-cts';
@plugin 'plugin-mts';
`,

'plugin-cjs/package.json': json`
{
"name": "plugin-cjs",
"type": "commonjs",
"exports": {
".": {
"require": "./index.cjs"
}
}
}
`,
'plugin-cjs/index.cjs': js`
module.exports = function ({ addUtilities }) {
addUtilities({ '.cjs': { content: '"cjs"' } })
}
`,

'plugin-esm/package.json': json`
{
"name": "plugin-esm",
"type": "module",
"exports": {
".": {
"import": "./index.mjs"
}
}
}
`,
'plugin-esm/index.mjs': js`
export default function ({ addUtilities }) {
addUtilities({ '.esm': { content: '"esm"' } })
}
`,

'plugin-cts/package.json': json`
{
"name": "plugin-cts",
"type": "commonjs",
"exports": {
".": {
"require": "./index.cts"
}
}
}
`,
'plugin-cts/index.cts': ts`
export default function ({ addUtilities }) {
addUtilities({ '.cts': { content: '"cts"' as const } })
}
`,

'plugin-mts/package.json': json`
{
"name": "plugin-mts",
"type": "module",
"exports": {
".": {
"import": "./index.mts"
}
}
}
`,
'plugin-mts/index.mts': ts`
export default function ({ addUtilities }) {
addUtilities({ '.mts': { content: '"mts"' as const } })
}
`,
},
},
async ({ root, fs, exec }) => {
await exec(`pnpm postcss src/index.css --output dist/out.css`, {
cwd: path.join(root, 'project-cjs'),
})
await exec(`pnpm postcss src/index.css --output dist/out.css`, {
cwd: path.join(root, 'project-esm'),
})

await fs.expectFileToContain('./project-cjs/dist/out.css', [
candidate`cjs`,
candidate`esm`,
candidate`cts`,
candidate`mts`,
])
await fs.expectFileToContain('./project-esm/dist/out.css', [
candidate`cjs`,
candidate`esm`,
candidate`cts`,
candidate`mts`,
])
},
)

test(
'watch mode',
{
Expand Down
Loading