Skip to content

Commit

Permalink
feat(cli): support tailwind.config.mjs file (#120)
Browse files Browse the repository at this point in the history
* feat(cli): support `tailwind.config.mjs` file

* feat: update

* fix: teest case

---------

Co-authored-by: sadeghbarati <[email protected]>
  • Loading branch information
Dunqing and sadeghbarati authored Oct 21, 2023
1 parent 2f9845e commit f4b5b3f
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 10 deletions.
17 changes: 11 additions & 6 deletions packages/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
rawConfigSchema,
resolveConfigPaths,
} from '../utils/get-config'
import { transformCJSToESM } from '../utils/transformers/transform-cjs-to-esm'

const PROJECT_DEPENDENCIES = {
base: [
Expand Down Expand Up @@ -110,6 +111,7 @@ export async function promptForConfig(
{ title: 'Vite', value: 'vite' },
{ title: 'Nuxt', value: 'nuxt' },
{ title: 'Laravel', value: 'laravel' },
{ title: 'Astro', value: 'astro' },
],
},
{
Expand All @@ -136,7 +138,7 @@ export async function promptForConfig(
type: 'text',
name: 'tailwindCss',
message: `Where is your ${highlight('Tailwind CSS')} file?`,
initial: (prev, values) => defaultConfig?.tailwind.css ?? TAILWIND_CSS_PATH[values.framework as 'vite' | 'nuxt' | 'laravel'],
initial: (prev, values) => defaultConfig?.tailwind.css ?? TAILWIND_CSS_PATH[values.framework as 'vite' | 'nuxt' | 'laravel' | 'astro'],
},
{
type: 'toggle',
Expand All @@ -151,8 +153,8 @@ export async function promptForConfig(
{
type: 'text',
name: 'tailwindConfig',
message: `Where is your ${highlight('tailwind.config.js')} located?`,
initial: defaultConfig?.tailwind.config ?? DEFAULT_TAILWIND_CONFIG,
message: `Where is your ${highlight('tailwind.config')} located?`,
initial: (prev, values) => defaultConfig?.tailwind.config ?? values.framework === 'astro' ? 'tailwind.config.mjs' : DEFAULT_TAILWIND_CONFIG,
},
{
type: 'text',
Expand Down Expand Up @@ -235,9 +237,12 @@ export async function runInit(cwd: string, config: Config) {
// Write tailwind config.
await fs.writeFile(
config.resolvedPaths.tailwindConfig,
config.tailwind.cssVariables
? template(templates.TAILWIND_CONFIG_WITH_VARIABLES)({ extension, framework: config.framework })
: template(templates.TAILWIND_CONFIG)({ extension, framework: config.framework }),
transformCJSToESM(
config.resolvedPaths.tailwindConfig,
config.tailwind.cssVariables
? template(templates.TAILWIND_CONFIG_WITH_VARIABLES)({ extension, framework: config.framework })
: template(templates.TAILWIND_CONFIG)({ extension, framework: config.framework }),
),
'utf8',
)

Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/utils/get-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const TAILWIND_CSS_PATH = {
nuxt: 'assets/css/tailwind.css',
vite: 'src/assets/index.css',
laravel: 'resources/css/app.css',
astro: 'src/styles/globals.css',
}

// TODO: Figure out if we want to support all cosmiconfig formats.
Expand Down
18 changes: 14 additions & 4 deletions packages/cli/src/utils/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ export function cn(...inputs: ClassValue[]) {
}
`

export const TAILWIND_CONFIG = `/** @type {import('tailwindcss').Config} */
export const TAILWIND_CONFIG = `
const animate = require("tailwindcss-animate")
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
content: [
Expand Down Expand Up @@ -41,10 +44,13 @@ module.exports = {
},
},
},
plugins: [require("tailwindcss-animate")],
plugins: [animate],
}`

export const TAILWIND_CONFIG_WITH_VARIABLES = `/** @type {import('tailwindcss').Config} */
export const TAILWIND_CONFIG_WITH_VARIABLES = `\n
const animate = require("tailwindcss-animate")
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ["class"],
<% if (framework === 'vite') { %>
Expand All @@ -61,6 +67,10 @@ module.exports = {
"./resources/views/**/*.blade.php",
"./resources/js/**/*.{<%- extension %>,<%- extension %>x,vue}",
],
<% } else if (framework === 'astro') { %>
content: [
'./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}',
],
<% } %>
theme: {
container: {
Expand Down Expand Up @@ -127,5 +137,5 @@ module.exports = {
},
},
},
plugins: [require("tailwindcss-animate")],
plugins: [animate],
}`
8 changes: 8 additions & 0 deletions packages/cli/src/utils/transformers/transform-cjs-to-esm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function transformCJSToESM(filename: string, code: string) {
if (filename.endsWith('.mjs')) {
return code
.replace(/const\s([\w\d_]+)\s*=\s*require\((.*)\);?/g, 'import $1 from $2')
.replace(/module\.exports = /g, 'export default ')
}
return code
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`handle tailwind config template correctly 1`] = `
"
import animate from \\"tailwindcss-animate\\"
/** @type {import('tailwindcss').Config} */
export default {
darkMode: [\\"class\\"],
content: [
'./pages/**/*.{<%- extension %>,<%- extension %>x,vue}',
'./components/**/*.{<%- extension %>,<%- extension %>x,vue}',
'./app/**/*.{<%- extension %>,<%- extension %>x,vue}',
'./src/**/*.{<%- extension %>,<%- extension %>x,vue}',
],
theme: {
container: {
center: true,
padding: \\"2rem\\",
screens: {
\\"2xl\\": \\"1400px\\",
},
},
extend: {
keyframes: {
\\"accordion-down\\": {
from: { height: 0 },
to: { height: \\"var(--radix-accordion-content-height)\\" },
},
\\"accordion-up\\": {
from: { height: \\"var(--radix-accordion-content-height)\\" },
to: { height: 0 },
},
},
animation: {
\\"accordion-down\\": \\"accordion-down 0.2s ease-out\\",
\\"accordion-up\\": \\"accordion-up 0.2s ease-out\\",
},
},
},
plugins: [animate],
}"
`;

exports[`handle tailwind config template correctly 2`] = `
"
import animate from \\"tailwindcss-animate\\"
/** @type {import('tailwindcss').Config} */
export default {
darkMode: [\\"class\\"],
<% if (framework === 'vite') { %>
content: [
'./pages/**/*.{<%- extension %>,<%- extension %>x,vue}',
'./components/**/*.{<%- extension %>,<%- extension %>x,vue}',
'./app/**/*.{<%- extension %>,<%- extension %>x,vue}',
'./src/**/*.{<%- extension %>,<%- extension %>x,vue}',
],
<% } else if (framework === 'laravel') { %>
content: [
\\"./vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php\\",
\\"./storage/framework/views/*.php\\",
\\"./resources/views/**/*.blade.php\\",
\\"./resources/js/**/*.{<%- extension %>,<%- extension %>x,vue}\\",
],
<% } else if (framework === 'astro') { %>
content: [
'./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}',
],
<% } %>
theme: {
container: {
center: true,
padding: \\"2rem\\",
screens: {
\\"2xl\\": \\"1400px\\",
},
},
extend: {
colors: {
border: \\"hsl(var(--border))\\",
input: \\"hsl(var(--input))\\",
ring: \\"hsl(var(--ring))\\",
background: \\"hsl(var(--background))\\",
foreground: \\"hsl(var(--foreground))\\",
primary: {
DEFAULT: \\"hsl(var(--primary))\\",
foreground: \\"hsl(var(--primary-foreground))\\",
},
secondary: {
DEFAULT: \\"hsl(var(--secondary))\\",
foreground: \\"hsl(var(--secondary-foreground))\\",
},
destructive: {
DEFAULT: \\"hsl(var(--destructive))\\",
foreground: \\"hsl(var(--destructive-foreground))\\",
},
muted: {
DEFAULT: \\"hsl(var(--muted))\\",
foreground: \\"hsl(var(--muted-foreground))\\",
},
accent: {
DEFAULT: \\"hsl(var(--accent))\\",
foreground: \\"hsl(var(--accent-foreground))\\",
},
popover: {
DEFAULT: \\"hsl(var(--popover))\\",
foreground: \\"hsl(var(--popover-foreground))\\",
},
card: {
DEFAULT: \\"hsl(var(--card))\\",
foreground: \\"hsl(var(--card-foreground))\\",
},
},
borderRadius: {
lg: \\"var(--radius)\\",
md: \\"calc(var(--radius) - 2px)\\",
sm: \\"calc(var(--radius) - 4px)\\",
},
keyframes: {
\\"accordion-down\\": {
from: { height: 0 },
to: { height: \\"var(--radix-accordion-content-height)\\" },
},
\\"accordion-up\\": {
from: { height: \\"var(--radix-accordion-content-height)\\" },
to: { height: 0 },
},
},
animation: {
\\"accordion-down\\": \\"accordion-down 0.2s ease-out\\",
\\"accordion-up\\": \\"accordion-up 0.2s ease-out\\",
},
},
},
plugins: [animate],
}"
`;
8 changes: 8 additions & 0 deletions packages/cli/test/utils/transform-cjs-to-esm.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { expect, test } from 'vitest'
import { TAILWIND_CONFIG, TAILWIND_CONFIG_WITH_VARIABLES } from '../../src/utils/templates'
import { transformCJSToESM } from '../../src/utils/transformers/transform-cjs-to-esm'

test('handle tailwind config template correctly', () => {
expect(transformCJSToESM('.mjs', TAILWIND_CONFIG)).toMatchSnapshot()
expect(transformCJSToESM('.mjs', TAILWIND_CONFIG_WITH_VARIABLES)).toMatchSnapshot()
})

0 comments on commit f4b5b3f

Please sign in to comment.