From b2b95d5738d1829d0237b6342bb1f01e601f3d28 Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Fri, 3 Nov 2017 09:54:15 -0400 Subject: [PATCH] Register config file with Webpack for watching This change tells Webpack (for those using it) that the config file used should be tracked as a dependency and that the CSS should be re-compiled if that config file changes. It's careful to make sure the config file is loaded fresh every single time to avoid weird caching issues. --- docs/tailwind.js | 3 ++- src/index.js | 34 ++++++++++++++++---------- src/lib/evaluateTailwindFunctions.js | 4 ++- src/lib/generateUtilities.js | 4 ++- src/lib/registerConfigAsDependency.js | 15 ++++++++++++ src/lib/substituteClassApplyAtRules.js | 7 +++--- src/lib/substituteFocusableAtRules.js | 6 +++-- src/lib/substituteHoverableAtRules.js | 6 +++-- src/lib/substitutePreflightAtRule.js | 4 ++- src/lib/substituteResponsiveAtRules.js | 6 +++-- src/lib/substituteScreenAtRules.js | 3 ++- 11 files changed, 65 insertions(+), 27 deletions(-) create mode 100644 src/lib/registerConfigAsDependency.js diff --git a/docs/tailwind.js b/docs/tailwind.js index 7b45b53b0..3b68a5bbd 100644 --- a/docs/tailwind.js +++ b/docs/tailwind.js @@ -1,4 +1,5 @@ -var config = require('../defaultConfig') +var config = require('../lib/index').defaultConfig() + config.colors = { ...config.colors, diff --git a/src/index.js b/src/index.js index cc02186bb..f0899fe77 100644 --- a/src/index.js +++ b/src/index.js @@ -5,6 +5,7 @@ import _ from 'lodash' import postcss from 'postcss' import stylefmt from 'stylefmt' +import registerConfigAsDependency from './lib/registerConfigAsDependency' import substitutePreflightAtRule from './lib/substitutePreflightAtRule' import evaluateTailwindFunctions from './lib/evaluateTailwindFunctions' import generateUtilities from './lib/generateUtilities' @@ -15,23 +16,30 @@ import substituteScreenAtRules from './lib/substituteScreenAtRules' import substituteClassApplyAtRules from './lib/substituteClassApplyAtRules' const plugin = postcss.plugin('tailwind', (config) => { - if (_.isUndefined(config)) { - config = require('../defaultConfig') + const plugins = [] + + if (! _.isUndefined(config)) { + plugins.push(registerConfigAsDependency(path.resolve(config))) } - if (_.isString(config)) { - config = require(path.resolve(config)) + const lazyConfig = () => { + if (_.isUndefined(config)) { + return require('../defaultConfig') + } + + delete require.cache[require.resolve(path.resolve(config))] + return require(path.resolve(config)) } - return postcss([ - substitutePreflightAtRule(config), - evaluateTailwindFunctions(config), - generateUtilities(config), - substituteHoverableAtRules(config), - substituteFocusableAtRules(config), - substituteResponsiveAtRules(config), - substituteScreenAtRules(config), - substituteClassApplyAtRules(config), + return postcss(...plugins, ...[ + substitutePreflightAtRule(lazyConfig), + evaluateTailwindFunctions(lazyConfig), + generateUtilities(lazyConfig), + substituteHoverableAtRules(lazyConfig), + substituteFocusableAtRules(lazyConfig), + substituteResponsiveAtRules(lazyConfig), + substituteScreenAtRules(lazyConfig), + substituteClassApplyAtRules(lazyConfig), stylefmt, ]) }) diff --git a/src/lib/evaluateTailwindFunctions.js b/src/lib/evaluateTailwindFunctions.js index c89e246ee..3b2ab3486 100644 --- a/src/lib/evaluateTailwindFunctions.js +++ b/src/lib/evaluateTailwindFunctions.js @@ -1,7 +1,9 @@ import _ from 'lodash' import functions from 'postcss-functions' -export default function(options) { +export default function(config) { + const options = config() + return functions({ functions: { config: function (path) { diff --git a/src/lib/generateUtilities.js b/src/lib/generateUtilities.js index b5c6c5e4a..bf658fcc0 100644 --- a/src/lib/generateUtilities.js +++ b/src/lib/generateUtilities.js @@ -37,8 +37,10 @@ import verticalAlign from '../generators/verticalAlign' import visibility from '../generators/visibility' import zIndex from '../generators/zIndex' -export default function(options) { +export default function(config) { return function(css) { + const options = config() + css.walkAtRules('tailwind', atRule => { if (atRule.params === 'utilities') { const utilities = _.flatten([ diff --git a/src/lib/registerConfigAsDependency.js b/src/lib/registerConfigAsDependency.js new file mode 100644 index 000000000..589db20ed --- /dev/null +++ b/src/lib/registerConfigAsDependency.js @@ -0,0 +1,15 @@ +import fs from 'fs' + +export default function(configFile) { + if (! fs.existsSync(configFile)) { + throw new Error(`Specified Tailwind config file "${configFile}" doesn't exist.`) + } + + return function (css, opts) { + opts.messages = [{ + type: 'dependency', + file: configFile, + parent: css.source.input.file, + }] + } +} diff --git a/src/lib/substituteClassApplyAtRules.js b/src/lib/substituteClassApplyAtRules.js index 7d506d7a2..ff3568c4d 100644 --- a/src/lib/substituteClassApplyAtRules.js +++ b/src/lib/substituteClassApplyAtRules.js @@ -9,8 +9,9 @@ function normalizeClassNames(classNames) { }) } -export default postcss.plugin('tailwind-apply', function(css) { - return function(css) { +export default function(config) { + return function (css) { + const options = config() css.walkRules(function(rule) { rule.walkAtRules('apply', atRule => { const mixins = normalizeClassNames(postcss.list.space(atRule.params)) @@ -42,4 +43,4 @@ export default postcss.plugin('tailwind-apply', function(css) { }) }) } -}) +} diff --git a/src/lib/substituteFocusableAtRules.js b/src/lib/substituteFocusableAtRules.js index c12aa2b6c..10cf04e2f 100644 --- a/src/lib/substituteFocusableAtRules.js +++ b/src/lib/substituteFocusableAtRules.js @@ -2,8 +2,10 @@ import _ from 'lodash' import postcss from 'postcss' import cloneNodes from '../util/cloneNodes' -export default function(options) { - return function(css) { +export default function(config) { + return function (css) { + const options = config() + css.walkAtRules('focusable', atRule => { atRule.walkRules(rule => { diff --git a/src/lib/substituteHoverableAtRules.js b/src/lib/substituteHoverableAtRules.js index e4d419e2a..abe432d70 100644 --- a/src/lib/substituteHoverableAtRules.js +++ b/src/lib/substituteHoverableAtRules.js @@ -2,8 +2,10 @@ import _ from 'lodash' import postcss from 'postcss' import cloneNodes from '../util/cloneNodes' -export default function(options) { - return function(css) { +export default function(config) { + return function (css) { + const options = config() + css.walkAtRules('hoverable', atRule => { atRule.walkRules(rule => { diff --git a/src/lib/substitutePreflightAtRule.js b/src/lib/substitutePreflightAtRule.js index 18478d0ef..62e01a49a 100644 --- a/src/lib/substitutePreflightAtRule.js +++ b/src/lib/substitutePreflightAtRule.js @@ -1,8 +1,10 @@ import fs from 'fs' import postcss from 'postcss' -export default function(options) { +export default function(config) { return function (css) { + const options = config() + css.walkAtRules('tailwind', atRule => { if (atRule.params === 'preflight') { atRule.before(postcss.parse(fs.readFileSync(`${__dirname}/../../css/preflight.css`, 'utf8'))) diff --git a/src/lib/substituteResponsiveAtRules.js b/src/lib/substituteResponsiveAtRules.js index 837035edf..98b306c3f 100644 --- a/src/lib/substituteResponsiveAtRules.js +++ b/src/lib/substituteResponsiveAtRules.js @@ -3,8 +3,10 @@ import postcss from 'postcss' import cloneNodes from '../util/cloneNodes' import buildMediaQuery from '../util/buildMediaQuery' -export default function({ screens }) { - return function(css) { + +export default function(config) { + return function (css) { + const screens = config().screens const rules = [] css.walkAtRules('responsive', atRule => { diff --git a/src/lib/substituteScreenAtRules.js b/src/lib/substituteScreenAtRules.js index 67d9de910..951492e8f 100644 --- a/src/lib/substituteScreenAtRules.js +++ b/src/lib/substituteScreenAtRules.js @@ -3,8 +3,9 @@ import postcss from 'postcss' import cloneNodes from '../util/cloneNodes' import buildMediaQuery from '../util/buildMediaQuery' -export default function(options) { +export default function(config) { return function(css) { + const options = config() const rules = [] css.walkAtRules('screen', atRule => {