mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
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"> |
This commit is contained in:
parent
ab9e2b716b
commit
38c9a881ac
@ -21,6 +21,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Ensure `flex` is suggested ([#15014](https://github.com/tailwindlabs/tailwindcss/pull/15014))
|
||||
- _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))
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -1,22 +1,13 @@
|
||||
import { __unstable__loadDesignSystem } from '@tailwindcss/node'
|
||||
import dedent from 'dedent'
|
||||
import postcss from 'postcss'
|
||||
import { expect, it } from 'vitest'
|
||||
import type { UserConfig } from '../../../tailwindcss/src/compat/config/types'
|
||||
import { migrateImport } from './migrate-import'
|
||||
|
||||
const css = dedent
|
||||
|
||||
async function migrate(input: string, userConfig: UserConfig = {}) {
|
||||
async function migrate(input: string) {
|
||||
return postcss()
|
||||
.use(
|
||||
migrateImport({
|
||||
designSystem: await __unstable__loadDesignSystem(`@import 'tailwindcss';`, {
|
||||
base: __dirname,
|
||||
}),
|
||||
userConfig,
|
||||
}),
|
||||
)
|
||||
.use(migrateImport())
|
||||
.process(input, { from: expect.getState().testPath })
|
||||
.then((result) => result.css)
|
||||
}
|
||||
@ -24,6 +15,8 @@ async function migrate(input: string, userConfig: UserConfig = {}) {
|
||||
it('prints relative file imports as relative paths', async () => {
|
||||
expect(
|
||||
await migrate(css`
|
||||
@import url('https://example.com');
|
||||
|
||||
@import 'fixtures/test';
|
||||
@import 'fixtures/test.css';
|
||||
@import './fixtures/test.css';
|
||||
@ -62,7 +55,9 @@ it('prints relative file imports as relative paths', async () => {
|
||||
@import 'tailwindcss/theme';
|
||||
`),
|
||||
).toMatchInlineSnapshot(`
|
||||
"@import './fixtures/test.css';
|
||||
"@import url('https://example.com');
|
||||
|
||||
@import './fixtures/test.css';
|
||||
@import './fixtures/test.css';
|
||||
@import './fixtures/test.css';
|
||||
@import './fixtures/test.css';
|
||||
|
||||
@ -12,27 +12,33 @@ export function migrateImport(): Plugin {
|
||||
|
||||
let promises: Promise<void>[] = []
|
||||
root.walkAtRules('import', (rule) => {
|
||||
let [firstParam, ...rest] = segment(rule.params, ' ')
|
||||
try {
|
||||
let [firstParam, ...rest] = segment(rule.params, ' ')
|
||||
|
||||
let params = parseImportParams(ValueParser.parse(firstParam))
|
||||
let params = parseImportParams(ValueParser.parse(firstParam))
|
||||
|
||||
let isRelative = params.uri[0] === '.'
|
||||
let hasCssExtension = params.uri.endsWith('.css')
|
||||
let isRelative = params.uri[0] === '.'
|
||||
let hasCssExtension = params.uri.endsWith('.css')
|
||||
|
||||
if (isRelative && hasCssExtension) {
|
||||
return
|
||||
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.
|
||||
}
|
||||
|
||||
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(' ')
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
await Promise.allSettled(promises)
|
||||
|
||||
@ -120,6 +120,13 @@ export async function analyze(stylesheets: Stylesheet[]) {
|
||||
resolvedPath = resolveCssId(id, basePath)
|
||||
}
|
||||
} catch (err) {
|
||||
// Import is a URL, we don't want to process these, but also don't
|
||||
// want to show an error message for them.
|
||||
if (id.startsWith('http://') || id.startsWith('https://') || id.startsWith('//')) {
|
||||
return
|
||||
}
|
||||
|
||||
// Something went wrong, we can't resolve the import.
|
||||
error(
|
||||
`Failed to resolve import: ${highlight(id)} in ${highlight(relative(node.source?.input.file!, basePath))}. Skipping.`,
|
||||
{ prefix: '↳ ' },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user