Skip to content

Commit f7096aa

Browse files
authored
feat: more adaptive content paths (#744)
* chore: initial * chore: extensions * chore: update * chore: update test * chore: add conditions for composables and utils * chore: update * chore: update tests * chore: finish tests
1 parent 36b4766 commit f7096aa

File tree

7 files changed

+71
-27
lines changed

7 files changed

+71
-27
lines changed

playground/.nuxt/tsconfig.json

Whitespace-only changes.

src/resolvers.ts

+35-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { existsSync } from 'fs'
2-
import { join, relative } from 'pathe'
3-
import { addTemplate, createResolver, findPath, useNuxt, tryResolveModule } from '@nuxt/kit'
2+
import { join, relative, resolve } from 'pathe'
3+
import { addTemplate, createResolver, findPath, useNuxt, tryResolveModule, resolveAlias } from '@nuxt/kit'
44
import type { Arrayable, InjectPosition, ModuleOptions } from './types'
55

66
/**
@@ -22,17 +22,39 @@ export const resolveConfigPath = async (path: Arrayable<string>) => (
2222
* @param srcDir
2323
* @returns array of resolved content globs
2424
*/
25-
export const resolveContentPaths = (srcDir: string) => ([
26-
`${srcDir}/components/**/*.{vue,js,ts}`,
27-
`${srcDir}/layouts/**/*.vue`,
28-
`${srcDir}/pages/**/*.vue`,
29-
`${srcDir}/composables/**/*.{js,ts}`,
30-
`${srcDir}/plugins/**/*.{js,ts}`,
31-
`${srcDir}/utils/**/*.{js,ts}`,
32-
`${srcDir}/{App,app}.{js,ts,vue}`,
33-
`${srcDir}/{Error,error}.{js,ts,vue}`,
34-
`${srcDir}/app.config.{js,ts}`
35-
])
25+
export const resolveContentPaths = (srcDir: string, nuxt = useNuxt()) => {
26+
const r = (p: string) => p.startsWith(srcDir) ? p : resolve(srcDir, p)
27+
const extensionFormat = (s: string[]) => s.length > 1 ? `.{${s.join(',')}}` : `.${s.join('') || 'vue'}`
28+
29+
const defaultExtensions = extensionFormat(['js', 'ts', 'mjs'])
30+
const sfcExtensions = extensionFormat(nuxt.options.extensions.map(e => e.replace(/^\.*/, '')))
31+
32+
const importDirs = [...(nuxt.options.imports.dirs || [])].map(r)
33+
const [composablesDir, utilsDir] = [resolve(srcDir, 'composables'), resolve(srcDir, 'utils')]
34+
35+
if (!importDirs.includes(composablesDir)) importDirs.push(composablesDir)
36+
if (!importDirs.includes(utilsDir)) importDirs.push(utilsDir)
37+
38+
return [
39+
...(() => {
40+
if (nuxt.options.components) {
41+
return (Array.isArray(nuxt.options.components) ? nuxt.options.components : typeof nuxt.options.components === 'boolean' ? ['components'] : nuxt.options.components.dirs).map(d => `${resolveAlias(typeof d === 'string' ? d : d.path)}/**/*${sfcExtensions}`)
42+
}
43+
return []
44+
})(),
45+
46+
r(`${nuxt.options.dir.layouts}/**/*${sfcExtensions}`),
47+
...(nuxt.options.pages ? [r(`${nuxt.options.dir.pages}/**/*${sfcExtensions}`)] : []),
48+
49+
r(`${nuxt.options.dir.plugins}/**/*${defaultExtensions}`),
50+
r(`${nuxt.options.dir.modules}/**/*${defaultExtensions}`),
51+
...importDirs.map(d => `${d}/**/*${defaultExtensions}`),
52+
53+
r(`{A,a}pp${sfcExtensions}`),
54+
r(`{E,e}rror${sfcExtensions}`),
55+
r(`app.config${defaultExtensions}`),
56+
]
57+
}
3658

3759
/**
3860
*

test/configs.test.ts

+26-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { describe, test, expect, vi } from 'vitest'
1+
import { describe, test, expect, vi, afterAll } from 'vitest'
22
import { useTestContext } from '@nuxt/test-utils'
33
import destr from 'destr'
4-
import { setupNuxtTailwind } from './util'
4+
import { setupNuxtTailwind, r } from './util'
5+
import { Config } from 'tailwindcss'
56

67
describe('tailwindcss module configs', async () => {
78
const spyStderr = vi.spyOn(process.stderr, 'write').mockImplementation(() => undefined!)
@@ -22,6 +23,12 @@ describe('tailwindcss module configs', async () => {
2223
'content-obj.config'
2324
],
2425
cssPath: 'tailwind.css'
26+
},
27+
{
28+
dir: { plugins: 'my-pluggable-modules', modules: 'my-modular-plugins' },
29+
modules: [r('modules/cjs-config.ts'), '@nuxtjs/tailwindcss'],
30+
imports: { dirs: ['my-imports-dir1', 'my-imports-dir2'] },
31+
extensions: ['.json', '.mdc', '.mdx', '.coffee']
2532
})
2633

2734
test('throws error about malformed config', () => {
@@ -34,33 +41,43 @@ describe('tailwindcss module configs', async () => {
3441

3542
test('ts config file is loaded and merged', () => {
3643
const nuxt = useTestContext().nuxt!
37-
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('tailwind.config.'))!
44+
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('test-tailwind.config.'))!
3845
// set from ts-tailwind.config.ts
3946
expect(nuxt.vfs[vfsKey]).contains('"typescriptBlue": "#007acc"')
4047
})
4148

4249
test('js config file is loaded and merged', () => {
4350
const nuxt = useTestContext().nuxt!
44-
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('tailwind.config.'))!
51+
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('test-tailwind.config.'))!
4552
// set from ts-tailwind.config.ts
4653
expect(nuxt.vfs[vfsKey]).contains('"javascriptYellow": "#f1e05a"')
4754
})
4855

56+
test('content is adaptive', () => {
57+
const nuxt = useTestContext().nuxt!
58+
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('test-tailwind.config.'))!
59+
const { content: { files } } = destr<Omit<Config, 'content'> & { content: Extract<Config['content'], { relative?: boolean }> }>(nuxt.vfs[vfsKey].replace(/^(module\.exports = )/, ''))
60+
61+
expect(files.find(c => /my-pluggable-modules|my-modular-plugins/.test(c))).toBeDefined()
62+
expect(files.filter(c => c.includes('my-imports-dir')).length).toBe(2)
63+
expect(files.find(c => c.includes('components/**/*'))?.includes('json,mdc,mdx,coffee')).toBeTruthy()
64+
})
65+
4966
test('content is overridden', () => {
5067
const nuxt = useTestContext().nuxt!
51-
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('tailwind.config.'))!
68+
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('test-tailwind.config.'))!
5269
// set from override-tailwind.config.ts
53-
const contentFiles = destr(nuxt.vfs[vfsKey].replace(/^(module\.exports = )/, '')).content.files
70+
const contentFiles = destr<Omit<Config, 'content'> & { content: Extract<Config['content'], { relative?: boolean }> }>(nuxt.vfs[vfsKey].replace(/^(module\.exports = )/, '')).content.files
5471

5572
expect(contentFiles[0]).toBe('ts-content/**/*.md')
5673
expect(contentFiles[1]).toBe('./custom-theme/**/*.vue')
57-
expect(contentFiles.slice(2).filter(c => c.endsWith('vue')).length).toBe(2)
74+
expect(contentFiles.filter(c => /{[AE],[ae]}/.test(c)).length).toBe(0)
5875
})
5976

6077
test('content merges with objects', () => {
6178
const nuxt = useTestContext().nuxt!
62-
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('tailwind.config.'))!
63-
const { content } = destr(nuxt.vfs[vfsKey].replace(/^(module\.exports = )/, ''))
79+
const vfsKey = Object.keys(nuxt.vfs).find(k => k.includes('test-tailwind.config.'))!
80+
const { content } = destr<Omit<Config, 'content'> & { content: Extract<Config['content'], { relative?: boolean }> }>(nuxt.vfs[vfsKey].replace(/^(module\.exports = )/, ''))
6481

6582
expect(content.relative).toBeTruthy()
6683
expect(content.files.pop()).toBe('./my-components/**/*.tsx')

test/fixture/basic/modules/cjs-config.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { defineNuxtModule, addTemplate } from '@nuxt/kit'
1+
import { defineNuxtModule, addTemplate, logger } from '@nuxt/kit'
22

33
export default defineNuxtModule({
44
setup (_options, nuxt) {
5+
// logger.info('Creating test-tailwind.config.cjs...')
6+
57
nuxt.hook('tailwindcss:resolvedConfig', (config) => {
68
addTemplate({
7-
filename: 'tailwind.config.cjs', // gets prepended by .nuxt/
9+
filename: 'test-tailwind.config.cjs', // gets prepended by .nuxt/
810
getContents: () => `module.exports = ${JSON.stringify(config, null, 2)}`,
911
write: true
1012
})

test/fixture/basic/override-tailwind.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export default {
22
content: contentDefaults => [
33
contentDefaults[0],
44
'./custom-theme/**/*.vue',
5-
...contentDefaults.filter(c => c.endsWith('vue'))
5+
...contentDefaults.filter(c => !/{[AE],[ae]}/.test(c))
66
],
77
theme: {
88
extend: {

test/fixture/basic/tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
// https://nuxt.com/docs/guide/concepts/typescript
3-
"extends": "./.nuxt/tsconfig.json"
3+
"extends": "../../../playground/.nuxt/tsconfig.json"
44
}

test/util.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { fileURLToPath } from 'node:url'
22
import { setup } from '@nuxt/test-utils'
3+
import { NuxtConfig } from '@nuxt/schema'
4+
import { ModuleOptions } from '../src/module'
35

46
export const r = (s: string = '') => fileURLToPath(new URL('./fixture/basic/' + s, import.meta.url))
57

6-
export const setupNuxtTailwind = (tailwindcss = {}) => {
8+
export const setupNuxtTailwind = (tailwindcss: Partial<ModuleOptions> = {}, nuxtConfig: NuxtConfig = {}) => {
79
return setup({
810
rootDir: r(),
911
server: true,
1012
browser: false,
1113
nuxtConfig: {
14+
...nuxtConfig,
1215
tailwindcss
1316
}
1417
})

0 commit comments

Comments
 (0)