Robin Malfait 38c9a881ac
Upgrade: don't show error during upgrade when analyzing external URL import (#15040)
This PR improves the output of the upgrade tool when we are handling
imports and the import happens to be an external URL.

External URLs shouldn't and can't be upgraded, so printing an error
message doesn't help the user.

Additionally, if an `@import` is using the `url(…)` function, then we
skip over it and continue with the rest of the imports.

| Before | After |
| --- | --- |
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/1ee00ea4-68e1-4252-b1cf-30a04f608b75">
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/da1f3eaf-dedb-4b1b-bf73-93bdfee65759">
|

Running this on github.com/parcel-bundler/parcel

| Before | After |
| -- | -- |
| <img width="1552" alt="image"
src="https://github.com/user-attachments/assets/89987444-8008-4edd-a907-6ad9276a86a0">
| <img width="1552" alt="image"
src="https://github.com/user-attachments/assets/cc2a34ae-ef17-4ad1-b06d-097874400b4d">
|
2024-11-19 15:52:30 +01:00

52 lines
1.6 KiB
TypeScript

import fs from 'node:fs/promises'
import { dirname, resolve } from 'node:path'
import { type Plugin, type Root } from 'postcss'
import { parseImportParams } from '../../../tailwindcss/src/at-import'
import { segment } from '../../../tailwindcss/src/utils/segment'
import * as ValueParser from '../../../tailwindcss/src/value-parser'
export function migrateImport(): Plugin {
async function migrate(root: Root) {
let file = root.source?.input.file
if (!file) return
let promises: Promise<void>[] = []
root.walkAtRules('import', (rule) => {
try {
let [firstParam, ...rest] = segment(rule.params, ' ')
let params = parseImportParams(ValueParser.parse(firstParam))
let isRelative = params.uri[0] === '.'
let hasCssExtension = params.uri.endsWith('.css')
if (isRelative && hasCssExtension) {
return
}
let fullPath = resolve(dirname(file), params.uri)
if (!hasCssExtension) fullPath += '.css'
promises.push(
fs.stat(fullPath).then(() => {
let ext = hasCssExtension ? '' : '.css'
let path = isRelative ? params.uri : `./${params.uri}`
rule.params = [`'${path}${ext}'`, ...rest].join(' ')
}),
)
} catch {
// When an error occurs while parsing the `@import` statement, we skip
// the import. This will happen in cases where you import an external
// URL.
}
})
await Promise.allSettled(promises)
}
return {
postcssPlugin: '@tailwindcss/upgrade/migrate-import',
OnceExit: migrate,
}
}