Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for TypeScript configuration files #7327

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
type TailwindConfig = any

/**
* Defines the Tailwind CSS configuration.
*
* @example
* ```ts
* import { defineConfig } from 'tailwindcss'
*
* export default defineConfig({
* content: ['src/*.vue'],
* theme: {
* // ...
* }
* })
* ```
*/
export function defineConfig(options?: TailwindConfig): TailwindConfig

/**
* Tailwind CSS as a PostCSS plugin.
*/
export const tailwindcss: Plugin
78 changes: 77 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@
"postcss-selector-parser": "^6.0.9",
"postcss-value-parser": "^4.2.0",
"quick-lru": "^5.1.1",
"resolve": "^1.22.0"
"resolve": "^1.22.0",
"unconfig": "^0.2.2"
},
"browserslist": [
"> 1%",
Expand Down
9 changes: 6 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import setupTrackingContext from './lib/setupTrackingContext'
import processTailwindFeatures from './processTailwindFeatures'
import { env } from './lib/sharedState'

module.exports = function tailwindcss(configOrPath) {
const plugin = function tailwindcss(configOrPath) {
return {
postcssPlugin: 'tailwindcss',
plugins: [
Expand All @@ -12,8 +12,8 @@ module.exports = function tailwindcss(configOrPath) {
console.time('JIT TOTAL')
return root
},
function (root, result) {
processTailwindFeatures(setupTrackingContext(configOrPath))(root, result)
async function (root, result) {
await processTailwindFeatures(setupTrackingContext(configOrPath))(root, result)
},
env.DEBUG &&
function (root) {
Expand All @@ -25,4 +25,7 @@ module.exports = function tailwindcss(configOrPath) {
}
}

module.exports = plugin
module.exports.postcss = true
module.exports.tailwindcss = plugin
module.exports.defineConfig = (config) => config
23 changes: 20 additions & 3 deletions src/lib/setupTrackingContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import path from 'path'
import fastGlob from 'fast-glob'
import LRU from 'quick-lru'
import normalizePath from 'normalize-path'
import { loadConfig } from 'unconfig'

import hash from '../util/hashConfig'
import getModuleDependencies from '../lib/getModuleDependencies'
Expand Down Expand Up @@ -34,9 +35,25 @@ function getCandidateFiles(context, tailwindConfig) {
}

// Get the config object based on a path
function getTailwindConfig(configOrPath) {
export async function getTailwindConfig(configOrPath) {
let userConfigPath = resolveConfigPath(configOrPath)

// Try loading with unconfig first
if (!userConfigPath || typeof userConfigPath === 'string') {
const unconfig = await loadConfig({
merge: false,
sources: [
{ files: userConfigPath?.replace(/\.ts$/, ''), extensions: ['ts'], skipOnError: true },
{ files: 'tailwind.config', extensions: ['ts'], skipOnError: true },
],
})

if (unconfig.sources.length > 0) {
const resolvedConfig = resolveConfig(unconfig.config)
return [resolvedConfig, null, hash(resolvedConfig), []]
}
}

if (userConfigPath !== null) {
let [prevConfig, prevConfigHash, prevDeps, prevModified] =
configPathCache.get(userConfigPath) || []
Expand Down Expand Up @@ -113,9 +130,9 @@ function resolveChangedFiles(candidateFiles, fileModifiedMap) {
// plugins) then return it
export default function setupTrackingContext(configOrPath) {
return ({ tailwindDirectives, registerDependency, applyDirectives }) => {
return (root, result) => {
return async (root, result) => {
let [tailwindConfig, userConfigPath, tailwindConfigHash, configDependencies] =
getTailwindConfig(configOrPath)
await getTailwindConfig(configOrPath)

let contextDependencies = new Set(configDependencies)

Expand Down
4 changes: 2 additions & 2 deletions src/processTailwindFeatures.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { createContext } from './lib/setupContextUtils'
import { issueFlagNotices } from './featureFlags'

export default function processTailwindFeatures(setupContext) {
return function (root, result) {
return async function (root, result) {
let { tailwindDirectives, applyDirectives } = normalizeTailwindDirectives(root)

detectNesting()(root, result)
Expand All @@ -21,7 +21,7 @@ export default function processTailwindFeatures(setupContext) {
// itself.
partitionApplyAtRules()(root, result)

let context = setupContext({
let context = await setupContext({
tailwindDirectives,
applyDirectives,
registerDependency(dependency) {
Expand Down
15 changes: 15 additions & 0 deletions tests/customConfig.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { cjsConfigFile, defaultConfigFile } from '../src/constants'
import inTempDirectory from '../jest/runInTempDirectory'

import { run, html, css, javascript } from './util/run'
import { getTailwindConfig } from '../src/lib/setupTrackingContext'

test('it uses the values from the custom config file', () => {
let config = require(path.resolve(`${__dirname}/fixtures/custom-config.js`))
Expand All @@ -19,6 +20,20 @@ test('it uses the values from the custom config file', () => {
})
})

test('it resolves a typescript config file', async () => {
let [config] = await getTailwindConfig(path.resolve(`${__dirname}/fixtures/ts-config.ts`))

return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
@media (min-width: 400px) {
.mobile\:font-bold {
font-weight: 700;
}
}
`)
})
})

test('custom config can be passed as an object', () => {
let config = {
content: [{ raw: html`<div class="mobile:font-bold"></div>` }],
Expand Down
11 changes: 11 additions & 0 deletions tests/fixtures/ts-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @ts-ignore
import { defineConfig } from '../../src'

export default defineConfig({
content: [{ raw: '<div class="mobile:font-bold"></div>' }],
theme: {
screens: {
mobile: '400px',
},
},
})