Wrap Tailwind plugins in new plugin to only unwrap config once
This commit is contained in:
parent
64cda2f44b
commit
b21d258f63
11 changed files with 70 additions and 62 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import postcss from 'postcss'
|
||||
import plugin from '../src/lib/substituteClassApplyAtRules'
|
||||
|
||||
function run(input, opts = () => {}) {
|
||||
function run(input, opts = {}) {
|
||||
return postcss([plugin(opts)]).process(input, { from: undefined })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import postcss from 'postcss'
|
|||
import plugin from '../src/lib/evaluateTailwindFunctions'
|
||||
|
||||
function run(input, opts = {}) {
|
||||
return postcss([plugin(() => opts)]).process(input, { from: undefined })
|
||||
return postcss([plugin(opts)]).process(input, { from: undefined })
|
||||
}
|
||||
|
||||
test('it looks up values in the config using dot notation', () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import postcss from 'postcss'
|
|||
import plugin from '../src/lib/substituteResponsiveAtRules'
|
||||
import config from '../defaultConfig.stub.js'
|
||||
|
||||
function run(input, opts = () => config) {
|
||||
function run(input, opts = config) {
|
||||
return postcss([plugin(opts)]).process(input, { from: undefined })
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ test('it can generate responsive variants', () => {
|
|||
}
|
||||
`
|
||||
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
|
|
@ -40,7 +40,7 @@ test('it can generate responsive variants', () => {
|
|||
options: {
|
||||
separator: ':',
|
||||
},
|
||||
})).then(result => {
|
||||
}).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
|
|
@ -71,7 +71,7 @@ test('it can generate responsive variants with a custom separator', () => {
|
|||
}
|
||||
`
|
||||
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
|
|
@ -80,7 +80,7 @@ test('it can generate responsive variants with a custom separator', () => {
|
|||
options: {
|
||||
separator: '__',
|
||||
},
|
||||
})).then(result => {
|
||||
}).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
|
|
@ -117,7 +117,7 @@ test('responsive variants are grouped', () => {
|
|||
}
|
||||
`
|
||||
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
|
|
@ -126,7 +126,7 @@ test('responsive variants are grouped', () => {
|
|||
options: {
|
||||
separator: ':',
|
||||
},
|
||||
})).then(result => {
|
||||
}).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
|
|
@ -152,7 +152,7 @@ test('screen prefix is only applied to the last class in a selector', () => {
|
|||
}
|
||||
`
|
||||
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
|
|
@ -161,7 +161,7 @@ test('screen prefix is only applied to the last class in a selector', () => {
|
|||
options: {
|
||||
separator: ':',
|
||||
},
|
||||
})).then(result => {
|
||||
}).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
|
|
@ -187,7 +187,7 @@ test('responsive variants are generated for all selectors in a rule', () => {
|
|||
}
|
||||
`
|
||||
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
|
|
@ -196,7 +196,7 @@ test('responsive variants are generated for all selectors in a rule', () => {
|
|||
options: {
|
||||
separator: ':',
|
||||
},
|
||||
})).then(result => {
|
||||
}).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
|
|
@ -209,7 +209,7 @@ test('selectors with no classes cannot be made responsive', () => {
|
|||
}
|
||||
`
|
||||
expect.assertions(1)
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
|
|
@ -218,7 +218,7 @@ test('selectors with no classes cannot be made responsive', () => {
|
|||
options: {
|
||||
separator: ':',
|
||||
},
|
||||
})).catch(e => {
|
||||
}).catch(e => {
|
||||
expect(e).toMatchObject({ name: 'CssSyntaxError' })
|
||||
})
|
||||
})
|
||||
|
|
@ -230,7 +230,7 @@ test('all selectors in a rule must contain classes', () => {
|
|||
}
|
||||
`
|
||||
expect.assertions(1)
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
screens: {
|
||||
sm: '500px',
|
||||
md: '750px',
|
||||
|
|
@ -239,7 +239,7 @@ test('all selectors in a rule must contain classes', () => {
|
|||
options: {
|
||||
separator: ':',
|
||||
},
|
||||
})).catch(e => {
|
||||
}).catch(e => {
|
||||
expect(e).toMatchObject({ name: 'CssSyntaxError' })
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import postcss from 'postcss'
|
|||
import plugin from '../src/lib/substituteVariantsAtRules'
|
||||
import config from '../defaultConfig.stub.js'
|
||||
|
||||
function run(input, opts = () => config) {
|
||||
function run(input, opts = config) {
|
||||
return postcss([plugin(opts)]).process(input, { from: undefined })
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +182,7 @@ test('plugin variants work', () => {
|
|||
.first-child\\:chocolate:first-child { color: brown; }
|
||||
`
|
||||
|
||||
return run(input, () => ({
|
||||
return run(input, {
|
||||
...config,
|
||||
plugins: [
|
||||
...config.plugins,
|
||||
|
|
@ -192,7 +192,7 @@ test('plugin variants work', () => {
|
|||
})
|
||||
},
|
||||
],
|
||||
})).then(result => {
|
||||
}).then(result => {
|
||||
expect(result.css).toMatchCss(output)
|
||||
expect(result.warnings().length).toBe(0)
|
||||
})
|
||||
|
|
|
|||
40
src/index.js
40
src/index.js
|
|
@ -5,15 +5,10 @@ import postcss from 'postcss'
|
|||
import perfectionist from 'perfectionist'
|
||||
|
||||
import registerConfigAsDependency from './lib/registerConfigAsDependency'
|
||||
import substituteTailwindAtRules from './lib/substituteTailwindAtRules'
|
||||
import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions'
|
||||
import substituteVariantsAtRules from './lib/substituteVariantsAtRules'
|
||||
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
|
||||
import substituteScreenAtRules from './lib/substituteScreenAtRules'
|
||||
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'
|
||||
|
||||
import processTailwindFeatures from './processTailwindFeatures'
|
||||
import mergeConfigWithDefaults from './util/mergeConfigWithDefaults'
|
||||
|
||||
|
||||
const plugin = postcss.plugin('tailwind', config => {
|
||||
const plugins = []
|
||||
|
||||
|
|
@ -36,26 +31,19 @@ const plugin = postcss.plugin('tailwind', config => {
|
|||
)
|
||||
}
|
||||
|
||||
return postcss(
|
||||
return postcss([
|
||||
...plugins,
|
||||
...[
|
||||
substituteTailwindAtRules(lazyConfig),
|
||||
evaluateTailwindFunctions(lazyConfig),
|
||||
substituteVariantsAtRules(lazyConfig),
|
||||
substituteResponsiveAtRules(lazyConfig),
|
||||
substituteScreenAtRules(lazyConfig),
|
||||
substituteClassApplyAtRules(lazyConfig),
|
||||
perfectionist({
|
||||
cascade: true,
|
||||
colorShorthand: true,
|
||||
indentSize: 2,
|
||||
maxSelectorLength: 1,
|
||||
maxValueLength: false,
|
||||
trimLeadingZero: true,
|
||||
trimTrailingZeros: true,
|
||||
}),
|
||||
]
|
||||
)
|
||||
processTailwindFeatures(lazyConfig),
|
||||
perfectionist({
|
||||
cascade: true,
|
||||
colorShorthand: true,
|
||||
indentSize: 2,
|
||||
maxSelectorLength: 1,
|
||||
maxValueLength: false,
|
||||
trimLeadingZero: true,
|
||||
trimTrailingZeros: true,
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
plugin.defaultConfig = function() {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export default function(config) {
|
|||
return functions({
|
||||
functions: {
|
||||
config: (path, defaultValue) => {
|
||||
return _.get(config(), _.trim(path, `'"`), defaultValue)
|
||||
return _.get(config, _.trim(path, `'"`), defaultValue)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import buildSelectorVariant from '../util/buildSelectorVariant'
|
|||
|
||||
export default function(config) {
|
||||
return function(css) {
|
||||
const screens = config().screens
|
||||
const separator = config().options.separator
|
||||
const screens = config.screens
|
||||
const separator = config.options.separator
|
||||
const responsiveRules = []
|
||||
let finalRules = []
|
||||
|
||||
|
|
|
|||
|
|
@ -3,17 +3,15 @@ import buildMediaQuery from '../util/buildMediaQuery'
|
|||
|
||||
export default function(config) {
|
||||
return function(css) {
|
||||
const options = config()
|
||||
|
||||
css.walkAtRules('screen', atRule => {
|
||||
const screen = atRule.params
|
||||
|
||||
if (!_.has(options.screens, screen)) {
|
||||
if (!_.has(config.screens, screen)) {
|
||||
throw atRule.error(`No \`${screen}\` screen found.`)
|
||||
}
|
||||
|
||||
atRule.name = 'media'
|
||||
atRule.params = buildMediaQuery(options.screens[screen])
|
||||
atRule.params = buildMediaQuery(config.screens[screen])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,8 @@ import processPlugins from '../util/processPlugins'
|
|||
|
||||
export default function(config) {
|
||||
return function(css) {
|
||||
const unwrappedConfig = config()
|
||||
|
||||
const { components: pluginComponents, utilities: pluginUtilities } = processPlugins(
|
||||
unwrappedConfig
|
||||
config
|
||||
)
|
||||
|
||||
css.walkAtRules('tailwind', atRule => {
|
||||
|
|
@ -37,9 +35,9 @@ export default function(config) {
|
|||
}
|
||||
|
||||
if (atRule.params === 'utilities') {
|
||||
const utilities = generateModules(utilityModules, unwrappedConfig.modules, unwrappedConfig)
|
||||
const utilities = generateModules(utilityModules, config.modules, config)
|
||||
|
||||
if (unwrappedConfig.options.important) {
|
||||
if (config.options.important) {
|
||||
utilities.walkDecls(decl => (decl.important = true))
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +49,7 @@ export default function(config) {
|
|||
nodes: pluginUtilities,
|
||||
})
|
||||
|
||||
prefixTree(tailwindUtilityTree, unwrappedConfig.options.prefix)
|
||||
prefixTree(tailwindUtilityTree, config.options.prefix)
|
||||
|
||||
tailwindUtilityTree.walk(node => (node.source = atRule.source))
|
||||
pluginUtilityTree.walk(node => (node.source = atRule.source))
|
||||
|
|
|
|||
|
|
@ -31,10 +31,9 @@ const defaultVariantGenerators = {
|
|||
|
||||
export default function(config) {
|
||||
return function(css) {
|
||||
const unwrappedConfig = config()
|
||||
const variantGenerators = {
|
||||
...defaultVariantGenerators,
|
||||
...processPlugins(unwrappedConfig).variantGenerators,
|
||||
...processPlugins(config).variantGenerators,
|
||||
}
|
||||
|
||||
css.walkAtRules('variants', atRule => {
|
||||
|
|
@ -49,7 +48,7 @@ export default function(config) {
|
|||
atRule.before(atRule.clone().nodes)
|
||||
|
||||
_.forEach(_.without(variants, 'responsive'), variant => {
|
||||
variantGenerators[variant](atRule, unwrappedConfig)
|
||||
variantGenerators[variant](atRule, config)
|
||||
})
|
||||
|
||||
atRule.remove()
|
||||
|
|
|
|||
25
src/processTailwindFeatures.js
Normal file
25
src/processTailwindFeatures.js
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import path from 'path'
|
||||
|
||||
import _ from 'lodash'
|
||||
import postcss from 'postcss'
|
||||
|
||||
import registerConfigAsDependency from './lib/registerConfigAsDependency'
|
||||
import substituteTailwindAtRules from './lib/substituteTailwindAtRules'
|
||||
import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions'
|
||||
import substituteVariantsAtRules from './lib/substituteVariantsAtRules'
|
||||
import substituteResponsiveAtRules from './lib/substituteResponsiveAtRules'
|
||||
import substituteScreenAtRules from './lib/substituteScreenAtRules'
|
||||
import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules'
|
||||
|
||||
export default function(lazyConfig) {
|
||||
const config = lazyConfig()
|
||||
|
||||
return postcss([
|
||||
substituteTailwindAtRules(config),
|
||||
evaluateTailwindFunctions(config),
|
||||
substituteVariantsAtRules(config),
|
||||
substituteResponsiveAtRules(config),
|
||||
substituteScreenAtRules(config),
|
||||
substituteClassApplyAtRules(config),
|
||||
])
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue