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

feat: providing types for all exports #617

Merged
merged 5 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 1 addition & 1 deletion docs/content/1.getting-started/2.options.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ This is only relevant when [`exposeConfig`](/getting-started/options#exposeconfi

::alert{type="warning"}

It is unlikely for `exposeLevel` to ever be over 4 - the usual depth of a Tailwind config. A higher value is also likely to increase boot-time and disk space in dev.
It is unlikely for `exposeLevel` to ever be over 4 - the usual depth of a Tailwind config. A higher value is also likely to increase boot-time and disk space in dev. Refer to the [Nuxt Virtual File System](https://nuxt.com/docs/guide/directory-structure/nuxt#virtual-file-system) to see generated files.

::

Expand Down
6 changes: 6 additions & 0 deletions docs/content/2.tailwind/1.config.md
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,9 @@ import { _800 as slate800 } from '#tailwind-config/theme/colors/slate' // alias
Please be aware this adds `~19.5KB` (`~3.5KB`) to the client bundle size.

::

::alert{type="info"}

Import types are only provided through the `#tailwind-config/*` alias.

::
ineshbose marked this conversation as resolved.
Show resolved Hide resolved
28 changes: 19 additions & 9 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ export default defineNuxtModule<ModuleOptions>({
// Expose resolved tailwind config as an alias
// https://tailwindcss.com/docs/configuration/#referencing-in-javascript
if (moduleOptions.exposeConfig) {
const dtsContent: string[] = []

/**
* Creates MJS exports for properties of the config
*
Expand All @@ -177,44 +179,52 @@ export default defineNuxtModule<ModuleOptions>({
* @param maxLevel maximum level of depth
*/
const populateMap = (obj: any, path: string[] = [], level = 1, maxLevel = moduleOptions.exposeLevel) => {
Object.entries(obj).forEach(([key, value = {}]) => {
Object.entries(obj).forEach(([key, value = {} as any]) => {
const subpath = path.concat(key).join('/')

if (
level >= maxLevel || // if recursive call is more than desired
typeof value !== 'object' || // if its not an object, no more recursion required
Array.isArray(value) || // arrays are objects in JS, but we can't break it down
Object.keys(value as any).find(k => !k.match(/^[0-9a-z]+$/i)) // object has non-alphanumeric property (unsafe var name)
Object.keys(value).find(k => !k.match(/^[0-9a-z]+$/i)) // object has non-alphanumeric property (unsafe var name)
) {
addTemplate({
filename: `tailwind.config/${path.concat(key).join('/')}.mjs`,
filename: `tailwind.config/${subpath}.mjs`,
getContents: () => `export default ${JSON.stringify(value, null, 2)}`
})
dtsContent.push(`declare module "#tailwind-config/${subpath}" { const defaultExport: ${JSON.stringify(value)}; export default defaultExport; }`)
} else {
// recurse through nested objects
populateMap(value, path.concat(key), level + 1, maxLevel)

const values = Object.keys(value as any)
const values = Object.keys(value)
addTemplate({
filename: `tailwind.config/${path.concat(key).join('/')}.mjs`,
getContents: () => `${Object.keys(value as any).map(v => `import _${v} from "./${key}/${v}.mjs"`).join('\n')}\nconst config = { ${values.map(k => `"${k}": _${k}`).join(', ')} }\nexport { config as default${values.length > 0 ? ', _' : ''}${values.join(', _')} }`
filename: `tailwind.config/${subpath}.mjs`,
getContents: () => `${values.map(v => `import _${v} from "./${key}/${v}.mjs"`).join('\n')}\nconst config = { ${values.map(k => `"${k}": _${k}`).join(', ')} }\nexport { config as default${values.length > 0 ? ', _' : ''}${values.join(', _')} }`
})
dtsContent.push(`declare module "#tailwind-config/${subpath}" {${Object.keys(value).map(v => ` export const _${v}: typeof import("#tailwind-config/${join(`${key}/${subpath}`, `../${v}`)}");`).join('')} const defaultExport: { ${values.map(k => `"${k}": typeof _${k}`).join(', ')} }; export default defaultExport; }`)
}
})
}

populateMap(resolvedConfig)

const configOptions = Object.keys(resolvedConfig)

const template = addTemplate({
filename: 'tailwind.config/index.mjs',
getContents: () => `${configOptions.map(v => `import ${v} from "#build/tailwind.config/${v}.mjs"`).join('\n')}\nconst config = { ${configOptions.join(', ')} }\nexport { config as default, ${configOptions.join(', ')} }`,
write: true
})
addTemplate({
dtsContent.push(`declare module "#tailwind-config" {${configOptions.map(v => ` export const ${v}: typeof import("${join('#tailwind-config', v)}");`).join('')} const defaultExport: { ${configOptions.map(v => `"${v}": typeof ${v}`)} }; export default defaultExport; }`)
const typesTemplate = addTemplate({
filename: 'tailwind.config.d.ts',
getContents: () => `type tailwindcssConfig = import("tailwindcss").Config\ndeclare const config: tailwindcssConfig\n${configOptions.map(o => `declare const ${o}: tailwindcssConfig["${o}"]`).join('\n')}\nexport { config as default, ${configOptions.join(', ')} }`,
getContents: () => dtsContent.join('\n'),
write: true
})
nuxt.options.alias['#tailwind-config'] = dirname(template.dst)
nuxt.hook('prepare:types', (opts) => {
opts.references.push({ path: typesTemplate.dst })
})
}

// Allow extending tailwindcss config by other modules
Expand Down