wip
This commit is contained in:
parent
6bd3327d8e
commit
df35325e27
9 changed files with 72 additions and 16 deletions
|
|
@ -10,6 +10,7 @@ let featureFlags = {
|
|||
'hoverOnlyWhenSupported',
|
||||
'respectDefaultRingColorOpacity',
|
||||
'disableColorOpacityUtilitiesByDefault',
|
||||
'relativeContentPathsByDefault',
|
||||
],
|
||||
experimental: [
|
||||
'optimizeUniversalDefaults',
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import setupTrackingContext from './lib/setupTrackingContext'
|
||||
import processTailwindFeatures from './processTailwindFeatures'
|
||||
import { env } from './lib/sharedState'
|
||||
import { findAtConfigPath } from './lib/findAtConfigPath'
|
||||
|
||||
module.exports = function tailwindcss(configOrPath) {
|
||||
return {
|
||||
|
|
@ -13,6 +14,10 @@ module.exports = function tailwindcss(configOrPath) {
|
|||
return root
|
||||
},
|
||||
function (root, result) {
|
||||
// Use the path for the `@config` directive if it exists, otherwise use the
|
||||
// path for the file being processed
|
||||
configOrPath = findAtConfigPath(root, result) ?? configOrPath
|
||||
|
||||
let context = setupTrackingContext(configOrPath)
|
||||
|
||||
if (root.type === 'document') {
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ function resolveRelativePaths(context, contentPaths) {
|
|||
let resolveFrom = []
|
||||
|
||||
// Resolve base paths relative to the config file (when possible) if the experimental flag is enabled
|
||||
if (context.userConfigPath && context.postcssOptions?.experimental?.contextualPaths) {
|
||||
if (context.userConfigPath && context.tailwindConfig.content.relative) {
|
||||
resolveFrom = [path.dirname(context.userConfigPath)]
|
||||
}
|
||||
|
||||
|
|
|
|||
33
src/lib/findAtConfigPath.js
Normal file
33
src/lib/findAtConfigPath.js
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import path from 'path'
|
||||
|
||||
/**
|
||||
* Find the @config at-rule in the given CSS AST and return the relative path to the config file
|
||||
*
|
||||
*
|
||||
* @param {import('postcss').Root} root
|
||||
* @param {import('postcss').Result} result
|
||||
*/
|
||||
export function findAtConfigPath(root, result) {
|
||||
let configPath = null
|
||||
let relativeTo = root.source.input.file ?? result.opts.from ?? null
|
||||
|
||||
root.walkAtRules('config', (rule) => {
|
||||
if (relativeTo === undefined) {
|
||||
throw rule.error(
|
||||
'The `@config` at-rule cannot be used without a `from` option being set on the PostCSS config.'
|
||||
)
|
||||
}
|
||||
|
||||
if (configPath) {
|
||||
throw rule.error('Only `@config` at-rule is allowed per file.')
|
||||
}
|
||||
|
||||
configPath = rule.params.replace(/^['"]|['"]$/, '')
|
||||
|
||||
if (path.isAbsolute(configPath)) {
|
||||
throw rule.error('The `@config` at-rule cannot be used with an absolute path.')
|
||||
}
|
||||
})
|
||||
|
||||
return configPath ? path.resolve(path.dirname(relativeTo), configPath) : null
|
||||
}
|
||||
|
|
@ -940,8 +940,7 @@ export function getContext(
|
|||
tailwindConfig,
|
||||
userConfigPath,
|
||||
tailwindConfigHash,
|
||||
contextDependencies,
|
||||
postcssOptions
|
||||
contextDependencies
|
||||
) {
|
||||
let sourcePath = result.opts.from
|
||||
let isConfigFile = userConfigPath !== null
|
||||
|
|
@ -1003,7 +1002,6 @@ export function getContext(
|
|||
|
||||
Object.assign(context, {
|
||||
userConfigPath,
|
||||
postcssOptions,
|
||||
})
|
||||
|
||||
trackModified([...contextDependencies], getFileModifiedMap(context))
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ function getCandidateFiles(context, tailwindConfig) {
|
|||
// Get the config object based on a path
|
||||
function getTailwindConfig(configOrPath, inputPath) {
|
||||
let userConfigPath = resolveConfigPath(configOrPath, inputPath)
|
||||
let postcssOptions = typeof configOrPath === 'object' && configOrPath !== null ? configOrPath : {}
|
||||
|
||||
if (userConfigPath !== null) {
|
||||
let [prevConfig, prevConfigHash, prevDeps, prevModified] =
|
||||
|
|
@ -47,7 +46,7 @@ function getTailwindConfig(configOrPath, inputPath) {
|
|||
|
||||
// It hasn't changed (based on timestamps)
|
||||
if (!modified) {
|
||||
return [prevConfig, userConfigPath, prevConfigHash, prevDeps, postcssOptions]
|
||||
return [prevConfig, userConfigPath, prevConfigHash, prevDeps]
|
||||
}
|
||||
|
||||
// It has changed (based on timestamps), or first run
|
||||
|
|
@ -58,7 +57,7 @@ function getTailwindConfig(configOrPath, inputPath) {
|
|||
newConfig = validateConfig(newConfig)
|
||||
let newHash = hash(newConfig)
|
||||
configPathCache.set(userConfigPath, [newConfig, newHash, newDeps, newModified])
|
||||
return [newConfig, userConfigPath, newHash, newDeps, postcssOptions]
|
||||
return [newConfig, userConfigPath, newHash, newDeps]
|
||||
}
|
||||
|
||||
// It's a plain object, not a path
|
||||
|
|
@ -68,7 +67,7 @@ function getTailwindConfig(configOrPath, inputPath) {
|
|||
|
||||
newConfig = validateConfig(newConfig)
|
||||
|
||||
return [newConfig, null, hash(newConfig), [], postcssOptions]
|
||||
return [newConfig, null, hash(newConfig), []]
|
||||
}
|
||||
|
||||
// DISABLE_TOUCH = TRUE
|
||||
|
|
@ -79,7 +78,7 @@ function getTailwindConfig(configOrPath, inputPath) {
|
|||
export default function setupTrackingContext(configOrPath) {
|
||||
return ({ tailwindDirectives, registerDependency }) => {
|
||||
return (root, result) => {
|
||||
let [tailwindConfig, userConfigPath, tailwindConfigHash, configDependencies, postcssOptions] =
|
||||
let [tailwindConfig, userConfigPath, tailwindConfigHash, configDependencies] =
|
||||
getTailwindConfig(configOrPath, result.opts.from)
|
||||
|
||||
let contextDependencies = new Set(configDependencies)
|
||||
|
|
@ -108,8 +107,7 @@ export default function setupTrackingContext(configOrPath) {
|
|||
tailwindConfig,
|
||||
userConfigPath,
|
||||
tailwindConfigHash,
|
||||
contextDependencies,
|
||||
postcssOptions
|
||||
contextDependencies
|
||||
)
|
||||
|
||||
let candidateFiles = getCandidateFiles(context, tailwindConfig)
|
||||
|
|
|
|||
|
|
@ -56,9 +56,11 @@ export function normalizeConfig(config) {
|
|||
|
||||
// When `config.content` is an object
|
||||
if (typeof config.content === 'object' && config.content !== null) {
|
||||
// Only `files`, `extract` and `transform` can exist in `config.content`
|
||||
// Only `files`, `relative`, `extract`, and `transform` can exist in `config.content`
|
||||
if (
|
||||
Object.keys(config.content).some((key) => !['files', 'extract', 'transform'].includes(key))
|
||||
Object.keys(config.content).some(
|
||||
(key) => !['files', 'extract', 'transform', 'relative'].includes(key)
|
||||
)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
|
@ -112,6 +114,14 @@ export function normalizeConfig(config) {
|
|||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
// `config.content.relative` is optional and can be a boolean
|
||||
if (
|
||||
typeof config.content.relative !== 'boolean' &&
|
||||
typeof config.content.relative !== 'undefined'
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
@ -154,6 +164,16 @@ export function normalizeConfig(config) {
|
|||
|
||||
// Normalize the `content`
|
||||
config.content = {
|
||||
relative: (() => {
|
||||
let { content } = config
|
||||
|
||||
if (content?.relative) {
|
||||
return content.relative
|
||||
}
|
||||
|
||||
return config.future?.relativeContentPathsByDefault ?? false
|
||||
})(),
|
||||
|
||||
files: (() => {
|
||||
let { content, purge } = config
|
||||
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ export default function resolveConfigPath(pathOrConfig, inputPath) {
|
|||
pathOrConfig.config !== undefined &&
|
||||
isString(pathOrConfig.config)
|
||||
) {
|
||||
if (pathOrConfig.experimental?.contextualPaths) {
|
||||
return pickResolvedPath(pathOrConfig.config, inputPath)
|
||||
}
|
||||
// if (pathOrConfig.experimental?.contextualPaths) {
|
||||
// return pickResolvedPath(pathOrConfig.config, inputPath)
|
||||
// }
|
||||
|
||||
return path.resolve(pathOrConfig.config)
|
||||
}
|
||||
|
|
|
|||
1
types/config.d.ts
vendored
1
types/config.d.ts
vendored
|
|
@ -31,6 +31,7 @@ type ContentConfig =
|
|||
| (FilePath | RawFile)[]
|
||||
| {
|
||||
files: (FilePath | RawFile)[]
|
||||
relative?: boolean
|
||||
extract?: ExtractorFn | { [extension: string]: ExtractorFn }
|
||||
transform?: TransformerFn | { [extension: string]: TransformerFn }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue