Skip to content

Commit 4923042

Browse files
Allow users to disable url rewriting in the PostCSS plugin (#18321)
Since we (optionally) support source maps now it's possible that a later PostCSS plugin that *still* does url rewriting might fail to do so correctly because nodes will have preserved source locations in dev builds where before we "pretended" that everything came from the original file. But, because we can't know if such a plugin is present, disabling this behavior when source maps are enabled could cause issues *and* would be a breaking change. I wish everything *could just work* here but realistically we can't know what plugins have run before our PostCSS plugin or what plugins will run after so the best option (I think) we can offer here is to allow users to disable url rewriting at the plugin level. Fixes #16700
1 parent afbfdeb commit 4923042

File tree

3 files changed

+93
-3
lines changed

3 files changed

+93
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- Extract candidates in Slang templates ([#18565](https://github.com/tailwindlabs/tailwindcss/pull/18565))
2020
- Improve error messages when encountering invalid functional utility names ([#18568](https://github.com/tailwindlabs/tailwindcss/pull/18568))
2121
- Don’t output CSS objects with false or undefined in the AST ([#18571](https://github.com/tailwindlabs/tailwindcss/pull/18571))
22+
- Add option to disable url rewriting in `@tailwindcss/postcss` ([#18321](https://github.com/tailwindlabs/tailwindcss/pull/18321))
2223

2324
## [4.1.11] - 2025-06-26
2425

integrations/postcss/url-rewriting.test.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,78 @@ test(
7272
`)
7373
},
7474
)
75+
76+
test(
77+
'url rewriting can be disabled',
78+
{
79+
fs: {
80+
'package.json': json`
81+
{
82+
"dependencies": {
83+
"postcss": "^8",
84+
"postcss-cli": "^10",
85+
"tailwindcss": "workspace:^",
86+
"@tailwindcss/postcss": "workspace:^"
87+
}
88+
}
89+
`,
90+
'postcss.config.js': js`
91+
module.exports = {
92+
plugins: {
93+
'@tailwindcss/postcss': {
94+
transformAssetUrls: false,
95+
},
96+
},
97+
}
98+
`,
99+
'src/index.css': css`
100+
@reference 'tailwindcss';
101+
@import './dir-1/bar.css';
102+
@import './dir-1/dir-2/baz.css';
103+
@import './dir-1/dir-2/vector.css';
104+
`,
105+
'src/dir-1/bar.css': css`
106+
.test1 {
107+
background-image: url('../../resources/image.png');
108+
}
109+
`,
110+
'src/dir-1/dir-2/baz.css': css`
111+
.test2 {
112+
background-image: url('../../../resources/image.png');
113+
}
114+
`,
115+
'src/dir-1/dir-2/vector.css': css`
116+
@import './dir-3/vector.css';
117+
.test3 {
118+
background-image: url('../../../resources/vector.svg');
119+
}
120+
`,
121+
'src/dir-1/dir-2/dir-3/vector.css': css`
122+
.test4 {
123+
background-image: url('./vector-2.svg');
124+
}
125+
`,
126+
},
127+
},
128+
async ({ fs, exec, expect }) => {
129+
await exec('pnpm postcss src/index.css --output dist/out.css')
130+
131+
expect(await fs.dumpFiles('dist/out.css')).toMatchInlineSnapshot(`
132+
"
133+
--- dist/out.css ---
134+
.test1 {
135+
background-image: url('../../resources/image.png');
136+
}
137+
.test2 {
138+
background-image: url('../../../resources/image.png');
139+
}
140+
.test4 {
141+
background-image: url('./vector-2.svg');
142+
}
143+
.test3 {
144+
background-image: url('../../../resources/vector.svg');
145+
}
146+
"
147+
`)
148+
},
149+
)

packages/@tailwindcss-postcss/src/index.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,30 @@ function getContextFromCache(inputFile: string, opts: PluginOptions): CacheEntry
4848
}
4949

5050
export type PluginOptions = {
51-
// The base directory to scan for class candidates.
51+
/**
52+
* The base directory to scan for class candidates.
53+
*
54+
* Defaults to the current working directory.
55+
*/
5256
base?: string
5357

54-
// Optimize and minify the output CSS.
58+
/**
59+
* Optimize and minify the output CSS.
60+
*/
5561
optimize?: boolean | { minify?: boolean }
62+
63+
/**
64+
* Enable or disable asset URL rewriting.
65+
*
66+
* Defaults to `true`.
67+
*/
68+
transformAssetUrls?: boolean
5669
}
5770

5871
function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
5972
let base = opts.base ?? process.cwd()
6073
let optimize = opts.optimize ?? process.env.NODE_ENV === 'production'
74+
let shouldRewriteUrls = opts.transformAssetUrls ?? true
6175

6276
return {
6377
postcssPlugin: '@tailwindcss/postcss',
@@ -123,7 +137,7 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
123137
let compiler = await compileAst(ast, {
124138
from: result.opts.from,
125139
base: inputBasePath,
126-
shouldRewriteUrls: true,
140+
shouldRewriteUrls,
127141
onDependency: (path) => context.fullRebuildPaths.push(path),
128142
// In CSS Module files, we have to disable the `@property` polyfill since these will
129143
// emit global `*` rules which are considered to be non-pure and will cause builds

0 commit comments

Comments
 (0)