Skip to content

Commit fb1731a

Browse files
authored
Inject @config "..." when a tailwind.config.{js,ts,...} is detected (#14635)
This PR injects a `@config "…"` in the CSS file if a JS based config has been found. We will try to inject the `@config` in a sensible place: 1. Above the very first `@theme` 2. If that doesn't work, below the last `@import` 3. If that doesn't work, at the top of the file (as a last resort)
1 parent 4d1becd commit fb1731a

File tree

8 files changed

+292
-15
lines changed

8 files changed

+292
-15
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2727
- _Upgrade (experimental)_: Ensure CSS before a layer stays unlayered when running codemods ([#14596](https://github.com/tailwindlabs/tailwindcss/pull/14596))
2828
- _Upgrade (experimental)_: Resolve issues where some prefixed candidates were not properly migrated ([#14600](https://github.com/tailwindlabs/tailwindcss/pull/14600))
2929
- _Upgrade (experimental)_: Migrate `@media screen(…)` when running codemods ([#14603](https://github.com/tailwindlabs/tailwindcss/pull/14603))
30+
- _Upgrade (experimental)_: Inject `@config "…"` when a `tailwind.config.{js,ts,…}` is detected ([#14635](https://github.com/tailwindlabs/tailwindcss/pull/14635))
3031

3132
## [4.0.0-alpha.26] - 2024-10-03
3233

integrations/upgrade/index.test.ts

Lines changed: 157 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ test(
3939
<div class="flex! sm:block! bg-linear-to-t bg-[var(--my-red)]"></div>
4040
4141
--- ./src/input.css ---
42-
@import 'tailwindcss';"
42+
@import 'tailwindcss';
43+
@config "../tailwind.config.js";
44+
"
4345
`)
4446

4547
let packageJsonContent = await fs.read('package.json')
@@ -95,9 +97,12 @@ test(
9597
--- ./src/input.css ---
9698
@import 'tailwindcss' prefix(tw);
9799
100+
@config "../tailwind.config.js";
101+
98102
.btn {
99103
@apply tw:rounded-md! tw:px-2 tw:py-1 tw:bg-blue-500 tw:text-white;
100-
}"
104+
}
105+
"
101106
`)
102107
},
103108
)
@@ -140,6 +145,8 @@ test(
140145
--- ./src/index.css ---
141146
@import 'tailwindcss';
142147
148+
@config "../tailwind.config.js";
149+
143150
.a {
144151
@apply flex;
145152
}
@@ -150,7 +157,8 @@ test(
150157
151158
.c {
152159
@apply flex! flex-col! items-center!;
153-
}"
160+
}
161+
"
154162
`)
155163
},
156164
)
@@ -193,6 +201,8 @@ test(
193201
--- ./src/index.css ---
194202
@import 'tailwindcss';
195203
204+
@config "../tailwind.config.js";
205+
196206
@layer base {
197207
html {
198208
color: #333;
@@ -203,7 +213,8 @@ test(
203213
.btn {
204214
color: red;
205215
}
206-
}"
216+
}
217+
"
207218
`)
208219
},
209220
)
@@ -251,6 +262,8 @@ test(
251262
--- ./src/index.css ---
252263
@import 'tailwindcss';
253264
265+
@config "../tailwind.config.js";
266+
254267
@utility btn {
255268
@apply rounded-md px-2 py-1 bg-blue-500 text-white;
256269
}
@@ -261,7 +274,8 @@ test(
261274
}
262275
-ms-overflow-style: none;
263276
scrollbar-width: none;
264-
}"
277+
}
278+
"
265279
`)
266280
},
267281
)
@@ -533,7 +547,8 @@ test(
533547
<div class="flex"></div>
534548
535549
--- ./src/other.html ---
536-
<div class="tw:flex"></div>"
550+
<div class="tw:flex"></div>
551+
"
537552
`)
538553
},
539554
)
@@ -573,7 +588,8 @@ test(
573588
<div class="tw:bg-linear-to-t"></div>
574589
575590
--- ./src/other.html ---
576-
<div class="bg-gradient-to-t"></div>"
591+
<div class="bg-gradient-to-t"></div>
592+
"
577593
`)
578594
},
579595
)
@@ -615,6 +631,7 @@ test(
615631
--- ./src/index.css ---
616632
@import 'tailwindcss';
617633
@import './utilities.css';
634+
@config "../tailwind.config.js";
618635
619636
--- ./src/utilities.css ---
620637
@utility no-scrollbar {
@@ -623,7 +640,8 @@ test(
623640
}
624641
-ms-overflow-style: none;
625642
scrollbar-width: none;
626-
}"
643+
}
644+
"
627645
`)
628646
},
629647
)
@@ -730,6 +748,7 @@ test(
730748
@import './c.1.css' layer(utilities);
731749
@import './c.1.utilities.css';
732750
@import './d.1.css';
751+
@config "../tailwind.config.js";
733752
734753
--- ./src/a.1.css ---
735754
@import './a.1.utilities.css'
@@ -804,7 +823,8 @@ test(
804823
--- ./src/d.4.css ---
805824
@utility from-a-4 {
806825
color: blue;
807-
}"
826+
}
827+
"
808828
`)
809829
},
810830
)
@@ -862,14 +882,141 @@ test(
862882
--- ./src/root.1.css ---
863883
@import 'tailwindcss/utilities' layer(utilities);
864884
@import './a.1.css' layer(utilities);
885+
@config "../tailwind.config.js";
865886
866887
--- ./src/root.2.css ---
867888
@import 'tailwindcss/utilities' layer(utilities);
868889
@import './a.1.css' layer(components);
890+
@config "../tailwind.config.js";
891+
892+
--- ./src/root.3.css ---
893+
@import 'tailwindcss/utilities' layer(utilities);
894+
@import './a.1.css' layer(utilities);
895+
@config "../tailwind.config.js";
896+
"
897+
`)
898+
},
899+
)
900+
901+
test(
902+
'injecting `@config` when a tailwind.config.{js,ts,…} is detected',
903+
{
904+
fs: {
905+
'package.json': json`
906+
{
907+
"dependencies": {
908+
"@tailwindcss/upgrade": "workspace:^"
909+
}
910+
}
911+
`,
912+
'tailwind.config.ts': js`
913+
export default {
914+
content: ['./src/**/*.{html,js}'],
915+
}
916+
`,
917+
'src/index.html': html`
918+
<h1>🤠👋</h1>
919+
<div class="!flex sm:!block bg-gradient-to-t bg-[--my-red]"></div>
920+
`,
921+
'src/root.1.css': css`
922+
/* Inject missing @config */
923+
@tailwind base;
924+
@tailwind components;
925+
@tailwind utilities;
926+
`,
927+
'src/root.2.css': css`
928+
/* Already contains @config */
929+
@tailwind base;
930+
@tailwind components;
931+
@tailwind utilities;
932+
@config "../tailwind.config.js";
933+
`,
934+
'src/root.3.css': css`
935+
/* Inject missing @config above first @theme */
936+
@tailwind base;
937+
@tailwind components;
938+
@tailwind utilities;
939+
940+
@variant hocus (&:hover, &:focus);
941+
942+
@theme {
943+
--color-red-500: #f00;
944+
}
945+
946+
@theme {
947+
--color-blue-500: #00f;
948+
}
949+
`,
950+
'src/root.4.css': css`
951+
/* Inject missing @config due to nested imports with tailwind imports */
952+
@import './root.4/base.css';
953+
@import './root.4/utilities.css';
954+
`,
955+
'src/root.4/base.css': css`@import 'tailwindcss/base';`,
956+
'src/root.4/utilities.css': css`@import 'tailwindcss/utilities';`,
957+
958+
'src/root.5.css': css`@import './root.5/tailwind.css';`,
959+
'src/root.5/tailwind.css': css`
960+
/* Inject missing @config in this file, due to full import */
961+
@import 'tailwindcss';
962+
`,
963+
},
964+
},
965+
async ({ exec, fs }) => {
966+
await exec('npx @tailwindcss/upgrade --force')
967+
968+
expect(await fs.dumpFiles('./src/**/*.{html,css}')).toMatchInlineSnapshot(`
969+
"
970+
--- ./src/index.html ---
971+
<h1>🤠👋</h1>
972+
<div class="flex! sm:block! bg-linear-to-t bg-[var(--my-red)]"></div>
973+
974+
--- ./src/root.1.css ---
975+
/* Inject missing @config */
976+
@import 'tailwindcss';
977+
@config "../tailwind.config.ts";
978+
979+
--- ./src/root.2.css ---
980+
/* Already contains @config */
981+
@import 'tailwindcss';
982+
@config "../tailwind.config.js";
869983
870984
--- ./src/root.3.css ---
985+
/* Inject missing @config above first @theme */
986+
@import 'tailwindcss';
987+
@config "../tailwind.config.ts";
988+
989+
@variant hocus (&:hover, &:focus);
990+
991+
@theme {
992+
--color-red-500: #f00;
993+
}
994+
995+
@theme {
996+
--color-blue-500: #00f;
997+
}
998+
999+
--- ./src/root.4.css ---
1000+
/* Inject missing @config due to nested imports with tailwind imports */
1001+
@import './root.4/base.css';
1002+
@import './root.4/utilities.css';
1003+
@config "../tailwind.config.ts";
1004+
1005+
--- ./src/root.5.css ---
1006+
@import './root.5/tailwind.css';
1007+
1008+
--- ./src/root.4/base.css ---
1009+
@import 'tailwindcss/theme' layer(theme);
1010+
@import 'tailwindcss/preflight' layer(base);
1011+
1012+
--- ./src/root.4/utilities.css ---
8711013
@import 'tailwindcss/utilities' layer(utilities);
872-
@import './a.1.css' layer(utilities);"
1014+
1015+
--- ./src/root.5/tailwind.css ---
1016+
/* Inject missing @config in this file, due to full import */
1017+
@import 'tailwindcss';
1018+
@config "../../tailwind.config.ts";
1019+
"
8731020
`)
8741021
},
8751022
)

integrations/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,8 @@ export function test(
330330
return a[0].localeCompare(z[0])
331331
})
332332
.map(([file, content]) => `--- ${file} ---\n${content || '<EMPTY>'}`)
333-
.join('\n\n')}`
333+
.join('\n\n')
334+
.trim()}\n`
334335
},
335336
async expectFileToContain(filePath, contents) {
336337
return retryAssertion(async () => {

0 commit comments

Comments
 (0)