Skip to content

Bump all Tailwind CSS related dependencies during upgrade #17763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 24, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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

This file was deleted.

28 changes: 16 additions & 12 deletions packages/@tailwindcss-upgrade/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import path from 'node:path'
import postcss from 'postcss'
import { migrateJsConfig } from './codemods/config/migrate-js-config'
import { migratePostCSSConfig } from './codemods/config/migrate-postcss'
import { migratePrettierPlugin } from './codemods/config/migrate-prettier'
import { analyze as analyzeStylesheets } from './codemods/css/analyze'
import { formatNodes } from './codemods/css/format-nodes'
import { linkConfigs as linkConfigsToStylesheets } from './codemods/css/link'
Expand Down Expand Up @@ -229,11 +228,22 @@ async function run() {
}

info('Updating dependencies…')
try {
// Upgrade Tailwind CSS
await pkg(base).add(['tailwindcss@latest'])
success(`Updated package: ${highlight('tailwindcss')}`, { prefix: '↳ ' })
} catch {}
for (let dependency of [
'tailwindcss',
'@tailwindcss/cli',
'@tailwindcss/postcss',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PostCSS config is migrated later, which means that on v3 projects at the time of running this will result in a no-op.

'@tailwindcss/vite',
'@tailwindcss/node',
'@tailwindcss/oxide',
'prettier-plugin-tailwindcss',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added prettier-plugin-tailwindcss here instead of the dedicated migratePrettierPlugin step.

]) {
try {
if (await pkg(base).has(dependency)) {
await pkg(base).add([`${dependency}@latest`])
success(`Updated package: ${highlight(dependency)}`, { prefix: '↳ ' })
}
} catch {}
}

let tailwindRootStylesheets = stylesheets.filter((sheet) => sheet.isTailwindRoot && sheet.file)

Expand Down Expand Up @@ -305,12 +315,6 @@ async function run() {
await migratePostCSSConfig(base)
}

info('Updating dependencies…')
{
// Migrate the prettier plugin to the latest version
await migratePrettierPlugin(base)
}
Comment on lines -308 to -312
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this to the array of dependencies to upgrade.


// Run all cleanup functions because we completed the migration
await Promise.allSettled(cleanup.map((fn) => fn()))

Expand Down
8 changes: 8 additions & 0 deletions packages/@tailwindcss-upgrade/src/utils/packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ export function pkg(base: string) {
throw e
}
},
async has(name: string) {
try {
let packageJsonPath = resolve(base, 'package.json')
let packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8')
return packageJsonContent.includes(`"${name}":`)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used quotes otherwise tailwindcss would also match if it saw @tailwindcss/postcss. Even though that doesn't really matter in this case.

Also, this doesn't really handle aliases at all:

"my-tailwindcss": "npm:[email protected]"

It also potentially overrides locally installed versions or symlinks:

"tailwindcss": "file:/path/to/local/version"

But give we want to work on a clean Git repo, I think this should be fine.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, not even trying to parse the JSON file. Took this from the prettier upgrade script we had (which I replaced with this) which means that you don't have to list dependencies, devDependenies, optionalDependencies, ...

} catch {}
return false
},
async remove(packages: string[]) {
let packageManager = await packageManagerForBase.get(base)
let command = `${packageManager} remove ${packages.join(' ')}`
Expand Down
Loading