Skip to content

Commit 2de4816

Browse files
author
Brad Cornes
committed
add utility config map
1 parent d89883b commit 2de4816

File tree

7 files changed

+145
-53
lines changed

7 files changed

+145
-53
lines changed

packages/tailwindcss-class-names/src/getPlugins.js

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
import * as path from 'path'
22
import stackTrace from 'stack-trace'
33
import pkgUp from 'pkg-up'
4+
import { glob } from './glob'
5+
import { isObject } from './isObject'
46

5-
function isObject(variable) {
6-
return Object.prototype.toString.call(variable) === '[object Object]'
7+
export async function getBuiltInPlugins(cwd) {
8+
try {
9+
return (
10+
await glob(path.resolve(cwd, 'node_modules/tailwindcss/lib/plugins/*.js'))
11+
)
12+
.map((x) => {
13+
try {
14+
const mod = __non_webpack_require__(x)
15+
return mod.default ? mod.default() : mod()
16+
} catch (_) {}
17+
})
18+
.filter(Boolean)
19+
} catch (_) {
20+
return []
21+
}
722
}
823

924
export default function getPlugins(config) {
@@ -13,7 +28,7 @@ export default function getPlugins(config) {
1328
return []
1429
}
1530

16-
return plugins.map(plugin => {
31+
return plugins.map((plugin) => {
1732
let pluginConfig = plugin.config
1833
if (!isObject(pluginConfig)) {
1934
pluginConfig = {}
@@ -25,7 +40,7 @@ export default function getPlugins(config) {
2540
: [],
2641
variants: isObject(pluginConfig.variants)
2742
? Object.keys(pluginConfig.variants)
28-
: []
43+
: [],
2944
}
3045

3146
const fn = plugin.handler || plugin
@@ -40,32 +55,32 @@ export default function getPlugins(config) {
4055
const trace = stackTrace.parse(e)
4156
if (trace.length === 0)
4257
return {
43-
name: fnName
58+
name: fnName,
4459
}
4560
const file = trace[0].fileName
4661
const dir = path.dirname(file)
4762
let pkg = pkgUp.sync({ cwd: dir })
4863
if (!pkg)
4964
return {
50-
name: fnName
65+
name: fnName,
5166
}
5267
try {
5368
pkg = __non_webpack_require__(pkg)
5469
} catch (_) {
5570
return {
56-
name: fnName
71+
name: fnName,
5772
}
5873
}
5974
if (pkg.name && path.resolve(dir, pkg.main || 'index.js') === file) {
6075
return {
6176
name: pkg.name,
6277
homepage: pkg.homepage,
63-
contributes
78+
contributes,
6479
}
6580
}
6681
}
6782
return {
68-
name: fnName
83+
name: fnName,
6984
}
7085
})
7186
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { runPlugin } from './runPlugin'
2+
import { getBuiltInPlugins } from './getPlugins'
3+
import { isObject } from './isObject'
4+
5+
const proxyHandler = (base = []) => ({
6+
get(target, key) {
7+
if (isObject(target[key])) {
8+
return new Proxy(target[key], proxyHandler([...base, key]))
9+
} else {
10+
if (
11+
[...base, key].every((x) => typeof x === 'string') &&
12+
target.hasOwnProperty(key)
13+
) {
14+
return '$dep$' + [...base, key].join('.')
15+
}
16+
return target[key]
17+
}
18+
},
19+
})
20+
21+
export async function getUtilityConfigMap({ cwd, resolvedConfig, postcss }) {
22+
const builtInPlugins = await getBuiltInPlugins(cwd)
23+
const userPlugins = Array.isArray(resolvedConfig.plugins)
24+
? resolvedConfig.plugins
25+
: []
26+
27+
try {
28+
const classNameConfigMap = {}
29+
const proxiedConfig = new Proxy(resolvedConfig, proxyHandler())
30+
31+
;[...builtInPlugins, ...userPlugins].forEach((plugin) => {
32+
runPlugin(plugin, {
33+
postcss,
34+
config: proxiedConfig,
35+
addUtilities: (utilities) => {
36+
Object.keys(utilities).forEach((util) => {
37+
let props = Object.keys(utilities[util])
38+
if (
39+
props.length === 1 &&
40+
/^\.[^\s]+$/.test(util) &&
41+
typeof utilities[util][props[0]] === 'string' &&
42+
utilities[util][props[0]].substr(0, 5) === '$dep$'
43+
) {
44+
classNameConfigMap[util.substr(1)] = utilities[util][
45+
props[0]
46+
].substr(5)
47+
}
48+
})
49+
},
50+
})
51+
})
52+
53+
return classNameConfigMap
54+
} catch (_) {
55+
return {}
56+
}
57+
}

packages/tailwindcss-class-names/src/getVariants.js

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import semver from 'semver'
2-
import dlv from 'dlv'
2+
import { runPlugin } from './runPlugin'
33

44
export default function getVariants({ config, version, postcss }) {
55
let variants = ['responsive', 'hover']
@@ -11,28 +11,16 @@ export default function getVariants({ config, version, postcss }) {
1111
variants.push('first', 'last', 'odd', 'even', 'disabled', 'visited')
1212
semver.gte(version, '1.3.0') && variants.push('group-focus')
1313

14-
let plugins = config.plugins
15-
if (!Array.isArray(plugins)) {
16-
plugins = []
17-
}
14+
let plugins = Array.isArray(config.plugins) ? config.plugins : []
15+
1816
plugins.forEach((plugin) => {
19-
try {
20-
;(plugin.handler || plugin)({
21-
addUtilities: () => {},
22-
addComponents: () => {},
23-
addBase: () => {},
24-
addVariant: (name) => {
25-
variants.push(name)
26-
},
27-
e: (x) => x,
28-
prefix: (x) => x,
29-
theme: (path, defaultValue) =>
30-
dlv(config, `theme.${path}`, defaultValue),
31-
variants: () => [],
32-
config: (path, defaultValue) => dlv(config, path, defaultValue),
33-
postcss,
34-
})
35-
} catch (_) {}
17+
runPlugin(plugin, {
18+
postcss,
19+
config,
20+
addVariant: (name) => {
21+
variants.push(name)
22+
},
23+
})
3624
})
3725

3826
return variants
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import nodeGlob from 'glob'
2+
import dlv from 'dlv'
3+
import * as path from 'path'
4+
5+
export function glob(pattern, options = {}) {
6+
return new Promise((resolve, reject) => {
7+
let g = new nodeGlob.Glob(pattern, options)
8+
let matches = []
9+
let max = dlv(options, 'max', Infinity)
10+
g.on('match', (match) => {
11+
matches.push(path.resolve(options.cwd || process.cwd(), match))
12+
if (matches.length === max) {
13+
g.abort()
14+
resolve(matches)
15+
}
16+
})
17+
g.on('end', () => {
18+
resolve(matches)
19+
})
20+
g.on('error', reject)
21+
})
22+
}

packages/tailwindcss-class-names/src/index.js

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import Hook from './hook.mjs'
33
import dlv from 'dlv'
44
import dset from 'dset'
55
import importFrom from 'import-from'
6-
import nodeGlob from 'glob'
7-
import * as path from 'path'
86
import chokidar from 'chokidar'
97
import semver from 'semver'
108
import invariant from 'tiny-invariant'
119
import getPlugins from './getPlugins'
1210
import getVariants from './getVariants'
1311
import resolveConfig from './resolveConfig'
1412
import * as util from 'util'
13+
import { glob } from './glob'
14+
import { getUtilityConfigMap } from './getUtilityConfigMap'
1515

1616
function TailwindConfigError(error) {
1717
Error.call(this)
@@ -24,25 +24,6 @@ function TailwindConfigError(error) {
2424

2525
util.inherits(TailwindConfigError, Error)
2626

27-
function glob(pattern, options = {}) {
28-
return new Promise((resolve, reject) => {
29-
let g = new nodeGlob.Glob(pattern, options)
30-
let matches = []
31-
let max = dlv(options, 'max', Infinity)
32-
g.on('match', (match) => {
33-
matches.push(path.resolve(options.cwd || process.cwd(), match))
34-
if (matches.length === max) {
35-
g.abort()
36-
resolve(matches)
37-
}
38-
})
39-
g.on('end', () => {
40-
resolve(matches)
41-
})
42-
g.on('error', reject)
43-
})
44-
}
45-
4627
function arraysEqual(arr1, arr2) {
4728
return (
4829
JSON.stringify(arr1.concat([]).sort()) ===
@@ -109,14 +90,21 @@ export default async function getClassNames(
10990
delete config[sepLocation]
11091
}
11192

93+
const resolvedConfig = resolveConfig({ cwd, config })
94+
11295
return {
11396
configPath,
114-
config: resolveConfig({ cwd, config }),
97+
config: resolvedConfig,
11598
separator: typeof userSeperator === 'undefined' ? ':' : userSeperator,
11699
classNames: await extractClassNames(ast),
117100
dependencies: hook.deps,
118101
plugins: getPlugins(config),
119102
variants: getVariants({ config, version, postcss }),
103+
utilityConfigMap: await getUtilityConfigMap({
104+
cwd,
105+
resolvedConfig,
106+
postcss,
107+
}),
120108
}
121109
}
122110

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export function isObject(thing) {
2+
return Object.prototype.toString.call(thing) === '[object Object]'
3+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import dlv from 'dlv'
2+
3+
export function runPlugin(plugin, params = {}) {
4+
const { config, ...rest } = params
5+
try {
6+
;(plugin.handler || plugin)({
7+
addUtilities: () => {},
8+
addComponents: () => {},
9+
addBase: () => {},
10+
addVariant: () => {},
11+
e: (x) => x,
12+
prefix: (x) => x,
13+
theme: (path, defaultValue) => dlv(config, `theme.${path}`, defaultValue),
14+
variants: () => [],
15+
config: (path, defaultValue) => dlv(config, path, defaultValue),
16+
...rest,
17+
})
18+
} catch (_) {}
19+
}

0 commit comments

Comments
 (0)