Skip to content

Commit fe9fc9a

Browse files
authored
Use resolveJsId when resolving tailwindcss/package.json (#15041)
This PR uses the `enhanced-resolve` instead of `createRequire(…).resolve` which improves the usability when running the upgrade tool locally using Bun. While testing, we also noticed that it is not possible to use a `cjs`-only plugin inside of an `esm` project. It was also not possible to use an `esm`-only plugin inside of a `cjs` project. # Test plan We added integration tests in both the CLI (the CLI is an mjs project) and in the PostCSS (where we can configure a `cjs` and `esm` PostCSS config) integration tests where we created an `esm` and `cjs` based project with 4 plugins (`cjs`-only, `esm`-only, and TypeScript based plugins: `cts`-only and `mts`-only).
1 parent e4bfa8c commit fe9fc9a

File tree

6 files changed

+365
-16
lines changed

6 files changed

+365
-16
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2323
### Fixed
2424

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

3234
### Changed
3335

integrations/cli/index.test.ts

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import dedent from 'dedent'
22
import os from 'node:os'
33
import path from 'node:path'
44
import { describe, expect } from 'vitest'
5-
import { candidate, css, html, js, json, test, yaml } from '../utils'
5+
import { candidate, css, html, js, json, test, ts, yaml } from '../utils'
66

77
const STANDALONE_BINARY = (() => {
88
switch (os.platform()) {
@@ -257,6 +257,161 @@ describe.each([
257257
await fs.expectFileToContain('dist/out.css', [candidate`underline`])
258258
},
259259
)
260+
261+
test(
262+
'module resolution using CJS, ESM, CTS, and MTS',
263+
{
264+
fs: {
265+
'package.json': json`{}`,
266+
'pnpm-workspace.yaml': yaml`
267+
#
268+
packages:
269+
- project-cjs
270+
- project-esm
271+
- plugin-cjs
272+
- plugin-esm
273+
- plugin-cts
274+
- plugin-mts
275+
`,
276+
'project-cjs/package.json': json`
277+
{
278+
"type": "commonjs",
279+
"dependencies": {
280+
"tailwindcss": "workspace:^",
281+
"@tailwindcss/cli": "workspace:^",
282+
"plugin-cjs": "workspace:*",
283+
"plugin-esm": "workspace:*",
284+
"plugin-cts": "workspace:*",
285+
"plugin-mts": "workspace:*"
286+
}
287+
}
288+
`,
289+
'project-cjs/index.html': html`
290+
<div class="cjs esm cts mts"></div>
291+
`,
292+
'project-cjs/src/index.css': css`
293+
@import 'tailwindcss/utilities';
294+
@plugin 'plugin-cjs';
295+
@plugin 'plugin-esm';
296+
@plugin 'plugin-cts';
297+
@plugin 'plugin-mts';
298+
`,
299+
300+
'project-esm/package.json': json`
301+
{
302+
"type": "module",
303+
"dependencies": {
304+
"tailwindcss": "workspace:^",
305+
"@tailwindcss/cli": "workspace:^",
306+
"plugin-cjs": "workspace:*",
307+
"plugin-esm": "workspace:*",
308+
"plugin-cts": "workspace:*",
309+
"plugin-mts": "workspace:*"
310+
}
311+
}
312+
`,
313+
'project-esm/index.html': html`
314+
<div class="cjs esm cts mts"></div>
315+
`,
316+
'project-esm/src/index.css': css`
317+
@import 'tailwindcss/utilities';
318+
@plugin 'plugin-cjs';
319+
@plugin 'plugin-esm';
320+
@plugin 'plugin-cts';
321+
@plugin 'plugin-mts';
322+
`,
323+
324+
'plugin-cjs/package.json': json`
325+
{
326+
"name": "plugin-cjs",
327+
"type": "commonjs",
328+
"exports": {
329+
".": {
330+
"require": "./index.cjs"
331+
}
332+
}
333+
}
334+
`,
335+
'plugin-cjs/index.cjs': js`
336+
module.exports = function ({ addUtilities }) {
337+
addUtilities({ '.cjs': { content: '"cjs"' } })
338+
}
339+
`,
340+
341+
'plugin-esm/package.json': json`
342+
{
343+
"name": "plugin-esm",
344+
"type": "module",
345+
"exports": {
346+
".": {
347+
"import": "./index.mjs"
348+
}
349+
}
350+
}
351+
`,
352+
'plugin-esm/index.mjs': js`
353+
export default function ({ addUtilities }) {
354+
addUtilities({ '.esm': { content: '"esm"' } })
355+
}
356+
`,
357+
358+
'plugin-cts/package.json': json`
359+
{
360+
"name": "plugin-cts",
361+
"type": "commonjs",
362+
"exports": {
363+
".": {
364+
"require": "./index.cts"
365+
}
366+
}
367+
}
368+
`,
369+
'plugin-cts/index.cts': ts`
370+
export default function ({ addUtilities }) {
371+
addUtilities({ '.cts': { content: '"cts"' as const } })
372+
}
373+
`,
374+
375+
'plugin-mts/package.json': json`
376+
{
377+
"name": "plugin-mts",
378+
"type": "module",
379+
"exports": {
380+
".": {
381+
"import": "./index.mts"
382+
}
383+
}
384+
}
385+
`,
386+
'plugin-mts/index.mts': ts`
387+
export default function ({ addUtilities }) {
388+
addUtilities({ '.mts': { content: '"mts"' as const } })
389+
}
390+
`,
391+
},
392+
},
393+
async ({ root, fs, exec }) => {
394+
await exec(`${command} --input src/index.css --output dist/out.css`, {
395+
cwd: path.join(root, 'project-cjs'),
396+
})
397+
await exec(`${command} --input src/index.css --output dist/out.css`, {
398+
cwd: path.join(root, 'project-esm'),
399+
})
400+
401+
await fs.expectFileToContain('./project-cjs/dist/out.css', [
402+
candidate`cjs`,
403+
candidate`esm`,
404+
candidate`cts`,
405+
candidate`mts`,
406+
])
407+
await fs.expectFileToContain('./project-esm/dist/out.css', [
408+
candidate`cjs`,
409+
candidate`esm`,
410+
candidate`cts`,
411+
candidate`mts`,
412+
])
413+
},
414+
)
260415
})
261416

262417
test(

integrations/postcss/index.test.ts

Lines changed: 172 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import dedent from 'dedent'
22
import path from 'node:path'
33
import { expect } from 'vitest'
4-
import { candidate, css, html, js, json, test, yaml } from '../utils'
4+
import { candidate, css, html, js, json, test, ts, yaml } from '../utils'
55

66
test(
77
'production build (string)',
@@ -315,6 +315,177 @@ test(
315315
},
316316
)
317317

318+
test(
319+
'module resolution using CJS, ESM, CTS, and MTS',
320+
{
321+
fs: {
322+
'package.json': json`{}`,
323+
'pnpm-workspace.yaml': yaml`
324+
#
325+
packages:
326+
- project-cjs
327+
- project-esm
328+
- plugin-cjs
329+
- plugin-esm
330+
- plugin-cts
331+
- plugin-mts
332+
`,
333+
'project-cjs/package.json': json`
334+
{
335+
"type": "commonjs",
336+
"dependencies": {
337+
"@tailwindcss/postcss": "workspace:^",
338+
"plugin-cjs": "workspace:*",
339+
"plugin-cts": "workspace:*",
340+
"plugin-esm": "workspace:*",
341+
"plugin-mts": "workspace:*",
342+
"postcss": "^8",
343+
"postcss-cli": "^10",
344+
"tailwindcss": "workspace:^"
345+
}
346+
}
347+
`,
348+
'project-cjs/postcss.config.cjs': js`
349+
let tailwindcss = require('@tailwindcss/postcss')
350+
module.exports = {
351+
plugins: [tailwindcss()],
352+
}
353+
`,
354+
'project-cjs/index.html': html`
355+
<div class="cjs esm cts mts"></div>
356+
`,
357+
'project-cjs/src/index.css': css`
358+
@import 'tailwindcss/utilities';
359+
@plugin 'plugin-cjs';
360+
@plugin 'plugin-esm';
361+
@plugin 'plugin-cts';
362+
@plugin 'plugin-mts';
363+
`,
364+
365+
'project-esm/package.json': json`
366+
{
367+
"type": "module",
368+
"dependencies": {
369+
"@tailwindcss/postcss": "workspace:^",
370+
"plugin-cjs": "workspace:*",
371+
"plugin-cts": "workspace:*",
372+
"plugin-esm": "workspace:*",
373+
"plugin-mts": "workspace:*",
374+
"postcss": "^8",
375+
"postcss-cli": "^10",
376+
"tailwindcss": "workspace:^"
377+
}
378+
}
379+
`,
380+
'project-esm/postcss.config.mjs': js`
381+
import tailwindcss from '@tailwindcss/postcss'
382+
export default {
383+
plugins: [tailwindcss()],
384+
}
385+
`,
386+
'project-esm/index.html': html`
387+
<div class="cjs esm cts mts"></div>
388+
`,
389+
'project-esm/src/index.css': css`
390+
@import 'tailwindcss/utilities';
391+
@plugin 'plugin-cjs';
392+
@plugin 'plugin-esm';
393+
@plugin 'plugin-cts';
394+
@plugin 'plugin-mts';
395+
`,
396+
397+
'plugin-cjs/package.json': json`
398+
{
399+
"name": "plugin-cjs",
400+
"type": "commonjs",
401+
"exports": {
402+
".": {
403+
"require": "./index.cjs"
404+
}
405+
}
406+
}
407+
`,
408+
'plugin-cjs/index.cjs': js`
409+
module.exports = function ({ addUtilities }) {
410+
addUtilities({ '.cjs': { content: '"cjs"' } })
411+
}
412+
`,
413+
414+
'plugin-esm/package.json': json`
415+
{
416+
"name": "plugin-esm",
417+
"type": "module",
418+
"exports": {
419+
".": {
420+
"import": "./index.mjs"
421+
}
422+
}
423+
}
424+
`,
425+
'plugin-esm/index.mjs': js`
426+
export default function ({ addUtilities }) {
427+
addUtilities({ '.esm': { content: '"esm"' } })
428+
}
429+
`,
430+
431+
'plugin-cts/package.json': json`
432+
{
433+
"name": "plugin-cts",
434+
"type": "commonjs",
435+
"exports": {
436+
".": {
437+
"require": "./index.cts"
438+
}
439+
}
440+
}
441+
`,
442+
'plugin-cts/index.cts': ts`
443+
export default function ({ addUtilities }) {
444+
addUtilities({ '.cts': { content: '"cts"' as const } })
445+
}
446+
`,
447+
448+
'plugin-mts/package.json': json`
449+
{
450+
"name": "plugin-mts",
451+
"type": "module",
452+
"exports": {
453+
".": {
454+
"import": "./index.mts"
455+
}
456+
}
457+
}
458+
`,
459+
'plugin-mts/index.mts': ts`
460+
export default function ({ addUtilities }) {
461+
addUtilities({ '.mts': { content: '"mts"' as const } })
462+
}
463+
`,
464+
},
465+
},
466+
async ({ root, fs, exec }) => {
467+
await exec(`pnpm postcss src/index.css --output dist/out.css`, {
468+
cwd: path.join(root, 'project-cjs'),
469+
})
470+
await exec(`pnpm postcss src/index.css --output dist/out.css`, {
471+
cwd: path.join(root, 'project-esm'),
472+
})
473+
474+
await fs.expectFileToContain('./project-cjs/dist/out.css', [
475+
candidate`cjs`,
476+
candidate`esm`,
477+
candidate`cts`,
478+
candidate`mts`,
479+
])
480+
await fs.expectFileToContain('./project-esm/dist/out.css', [
481+
candidate`cjs`,
482+
candidate`esm`,
483+
candidate`cts`,
484+
candidate`mts`,
485+
])
486+
},
487+
)
488+
318489
test(
319490
'watch mode',
320491
{

0 commit comments

Comments
 (0)