From 71fb9cdf594828680372f6353d3cba998f07549a Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Mon, 19 May 2025 12:47:08 +0200 Subject: [PATCH] Improve `@tailwindcss/upgrade` and `pnpm` workspaces support (#18065) This PR fixes an issue where an error such as: image Will be thrown during the upgrade process. This can happen when you are using `pnpm` and your CSS file includes a `@import "tailwindcss";`. In this scenario, `tailwindcss` will be loaded from a shared `.pnpm` folder outside of the current working directory. In this case, we are also not interested in migrating _that_ file, but we also don't want the upgrade process to just crash. I didn't see an option to ignore errors like this, so wrapped it in a try/catch instead. It also fixes another issue where if you are using a pnpm workspace and run the upgrade tool from the root, then it throws you an error that you cannot add dependencies to the workspace root unless `-w` or `--workspace-root` flags are passed. For this, we disable the check entirely using the `--ignore-workspace-root-check` flag. If we always used the `--workspace-root` flag, then the dependencies would always be added to the root, regardless of where you are running the script from which is not what we want. ## Test plan Before: image After: image Before: image After: image --- CHANGELOG.md | 1 + integrations/upgrade/index.test.ts | 188 ++++++++++++++++-- .../src/codemods/css/analyze.ts | 9 +- .../src/utils/packages.ts | 7 + 4 files changed, 185 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8a414fec..f4ab2a1e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Upgrade: Do not migrate declarations that look like candidates in ` `, 'src/input.css': css` @@ -3016,21 +3166,21 @@ test( expect(await fs.dumpFiles('./src/**/*.{css,vue}')).toMatchInlineSnapshot(` " --- ./src/index.vue --- - --- ./src/input.css --- diff --git a/packages/@tailwindcss-upgrade/src/codemods/css/analyze.ts b/packages/@tailwindcss-upgrade/src/codemods/css/analyze.ts index 954d8ce0f..c9af6a7a3 100644 --- a/packages/@tailwindcss-upgrade/src/codemods/css/analyze.ts +++ b/packages/@tailwindcss-upgrade/src/codemods/css/analyze.ts @@ -12,7 +12,14 @@ export async function analyze(stylesheets: Stylesheet[]) { let processingQueue: (() => Promise)[] = [] let stylesheetsByFile = new DefaultMap((file) => { // We don't want to process ignored files (like node_modules) - if (isIgnored(file)) { + try { + if (isIgnored(file)) { + return null + } + } catch { + // If the file is not part of the current working directory (which can + // happen if you import `tailwindcss` and it's loading a shared file from + // pnpm) then this will throw. return null } diff --git a/packages/@tailwindcss-upgrade/src/utils/packages.ts b/packages/@tailwindcss-upgrade/src/utils/packages.ts index 9f7f5619f..65f823bec 100644 --- a/packages/@tailwindcss-upgrade/src/utils/packages.ts +++ b/packages/@tailwindcss-upgrade/src/utils/packages.ts @@ -31,6 +31,13 @@ export function pkg(base: string) { args.push(SAVE_DEV[packageManager] || SAVE_DEV.default) } + // Allow running the `pnpm` command in the workspace root without + // erroring. Can't just use `--workspace-root` because that will force + // install dependencies in the workspace root. + if (packageManager === 'pnpm') { + args.push('--ignore-workspace-root-check') + } + let command = `${packageManager} add ${args.join(' ')}` try { return await exec(command, { cwd: base })