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: first class hmr #818

Merged
merged 34 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5d2859a
chore: initial
ineshbose Jan 20, 2024
34294a0
chore: progress
ineshbose Jan 20, 2024
ddf4b26
chore: use cjs instead
ineshbose Jan 21, 2024
681cbb3
Merge branch 'main' of https://github.com/nuxt-modules/tailwindcss in…
ineshbose Jan 24, 2024
808d7c8
chore: progress
ineshbose Jan 24, 2024
dfb0e1f
Merge branch 'main' into first-class-hmr
ineshbose Jan 25, 2024
fba9a63
Merge branch 'main' into first-class-hmr
ineshbose Jan 25, 2024
6ab12a5
Merge branch 'main' of https://github.com/nuxt-modules/tailwindcss in…
ineshbose Jan 28, 2024
d44e6e6
chore: progress
ineshbose Jan 28, 2024
7084ab6
Merge branch 'main' into first-class-hmr
ineshbose Feb 3, 2024
55298a0
Merge branch 'main' into first-class-hmr
ineshbose Feb 7, 2024
c923814
Merge branch 'main' into first-class-hmr
ineshbose Feb 10, 2024
0a9533e
chore: change approach
ineshbose Feb 13, 2024
8567875
chore: progress
ineshbose Feb 14, 2024
2c0d664
chore: finishing up
ineshbose Feb 14, 2024
9956922
Merge branch 'main' into first-class-hmr
ineshbose Feb 28, 2024
2041b3a
Merge branch 'main' into first-class-hmr
ineshbose Mar 23, 2024
8530478
chore: try some race fixes
ineshbose Mar 24, 2024
6105343
fix: viewer stuff
ineshbose Mar 24, 2024
17a73f0
chore: try and use context
ineshbose Mar 25, 2024
71fa7af
chore: remove console logs
ineshbose Mar 25, 2024
af218e1
chore: update
ineshbose Mar 26, 2024
3e97163
chore: update expose templates
ineshbose Mar 27, 2024
e55236d
chore: move load config to `modules:done`, closes #826
ineshbose Mar 27, 2024
b9c69b6
chore: update dependencies
ineshbose Mar 29, 2024
200d620
chore: continue try to fix flash
ineshbose Apr 2, 2024
087b6e2
Merge branch 'main' into first-class-hmr
ineshbose Apr 5, 2024
79d4464
Merge branch 'main' into first-class-hmr
ineshbose Apr 7, 2024
96bb62a
chore: invalidate module
ineshbose Apr 11, 2024
e8c7f74
chore: avoid invalidation on every call
ineshbose Apr 12, 2024
bc5c7b3
chore: use options.dev during build
ineshbose Apr 12, 2024
703dcdf
chore: remove webpack
ineshbose Apr 12, 2024
6d5e6cc
chore: keep backwards compatibility
ineshbose Apr 12, 2024
47f3be4
chore: write tests
ineshbose Apr 12, 2024
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
4 changes: 2 additions & 2 deletions docs/content/1.getting-started/2.configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,13 @@ You can edit the endpoint by `viewer.endpoint` and if you'd like to export the v

- Default: `false`

You can take advantage of some DX utilities this modules provide to you as you develop your Nuxt applicatio with Tailwind. Read more in [Editor Support](/tailwind/editor-support).
You can take advantage of some DX utilities this modules provide to you as you develop your Nuxt application with Tailwind. Read more in [Editor Support](/tailwind/editor-support).

```ts [nuxt.config.ts]
export default defineNuxtConfig({
tailwindcss: {
editorSupport: true
// editorSupport: { autocompleteUtil: { as: 'tailwindClasses' }, generateConfig: true }
// editorSupport: { autocompleteUtil: { as: 'tailwindClasses' } }
}
})
```
33 changes: 19 additions & 14 deletions docs/content/2.tailwind/3.editor-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Add the following configuration to your `.vscode/settings.json` file, so that Ta

If you use pnpm, ensure that tailwindcss is installed in your top-level node_modules folder.

## Autocomplete
## String Classes Autocomplete

When using strings of Tailwind classes, you can enable IntelliSense suggestions using the [`editorSupport.autocompleteUtil`](/getting-started/configuration#editorsupport) option. You will have to add the following VSCode setting:

Expand All @@ -44,9 +44,20 @@ const variantClasses = {
</script>
```

## Load Config File
## Configuration IntelliSense

Since Tailwind CSS v3.3, [ESM/TS configuration has been supported](https://tailwindcss.com/blog/tailwindcss-v3-3#esm-and-type-script-support) so your editor should automatically configure autocomplete based on your `tailwind.config`. If you happen to use a lower version and/or require to generate a flat configuration, you can do so using [`editorSupport.generateConfig`](/getting-started/configuration#editorsupport) option, or you can use the `tailwindcss:resolvedConfig` hook and a custom Nuxt module:
Since Tailwind CSS v3.3, [ESM/TS configuration has been supported](https://tailwindcss.com/blog/tailwindcss-v3-3#esm-and-type-script-support) so your editor should automatically configure autocomplete based on your `tailwind.config`. If you have a complex Nuxt project with multiple Tailwind configurations that are within layers, passed from hooks or inline `nuxt.config` and want to use a merged configuration, the module generates it in `.nuxt/tailwind.config.cjs` that you can use by adding the following VSCode setting:

```diff [.vscode/settings.json]
// ...
+ "tailwindCSS.experimental.configFile": ".nuxt/tailwind.config.cjs",
"files.associations": {
"*.css": "tailwindcss"
},
// ...
```

If you require more customisation to what configuration the IntelliSense extension reads, you can take advantage of hooks, especially the `tailwindcss:resolvedConfig` hook that runs the configuration through [`tailwindcss/resolveConfig`](https://github.com/tailwindlabs/tailwindcss/blob/master/resolveConfig.js) to provide the complete config object.

```ts [modules/tw-cjs-config.ts]
import { defineNuxtModule, addTemplate } from '@nuxt/kit'
Expand All @@ -55,8 +66,11 @@ export default defineNuxtModule({
setup (options, nuxt) {
nuxt.hook('tailwindcss:resolvedConfig', (config) => {
addTemplate({
filename: 'tailwind.config.cjs', // gets prepended by .nuxt/
getContents: () => `module.exports = ${JSON.stringify(config)}`,
filename: 'intellisense-tw.cjs', // gets prepended by .nuxt/
getContents: () => `
/* my-comment */
module.exports = ${JSON.stringify(config)}
`,
write: true
})
})
Expand All @@ -65,12 +79,3 @@ export default defineNuxtModule({
```

This hook allows you to customize your generated template in different ways (e.g., different filename, contents, etc.) through a module. Please be aware that using `JSON.stringify` will remove plugins from your configuration.

```diff [.vscode/settings.json]
// ...
+ "tailwindCSS.experimental.configFile": ".nuxt/tailwind.config.cjs",
"files.associations": {
"*.css": "tailwindcss"
},
// ...
```
37 changes: 17 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,38 +43,35 @@
"test:types": "pnpm dev:prepare && tsc --noEmit && nuxi typecheck playground"
},
"dependencies": {
"@nuxt/kit": "^3.9.3",
"autoprefixer": "^10.4.17",
"chokidar": "^3.5.3",
"clear-module": "^4.1.2",
"@nuxt/kit": "^3.11.1",
"autoprefixer": "^10.4.19",
"consola": "^3.2.3",
"defu": "^6.1.4",
"h3": "^1.10.0",
"micromatch": "^4.0.5",
"h3": "^1.11.1",
"pathe": "^1.1.2",
"postcss": "^8.4.33",
"postcss-custom-properties": "^13.3.4",
"postcss-nesting": "^12.0.2",
"postcss-custom-properties": "^13.3.6",
"postcss-nesting": "^12.1.0",
"tailwind-config-viewer": "^1.7.3",
"tailwindcss": "~3.4.1",
"ufo": "^1.3.2"
"ufo": "^1.5.3",
"unctx": "^2.3.1"
},
"devDependencies": {
"@fontsource/inter": "^5.0.16",
"@nuxt/content": "^2.10.0",
"@nuxt/devtools": "^1.0.8",
"@fontsource/inter": "^5.0.17",
"@nuxt/content": "^2.12.1",
"@nuxt/devtools": "^1.1.5",
"@nuxt/eslint-config": "latest",
"@nuxt/module-builder": "^0.5.5",
"@nuxt/test-utils": "^3.10.0",
"@tailwindcss/typography": "^0.5.10",
"@types/micromatch": "^4.0.6",
"@nuxt/test-utils": "^3.12.0",
"@tailwindcss/typography": "^0.5.12",
"changelogen": "^0.5.5",
"destr": "^2.0.2",
"destr": "^2.0.3",
"eslint": "latest",
"happy-dom": "^13.1.4",
"nuxt": "^3.9.3",
"typescript": "^5.3.3",
"vitest": "1.1.0"
"nuxt": "^3.11.1",
"typescript": "^5.4.3",
"vitest": "1.4.0"
},
"packageManager": "[email protected]",
"resolutions": {
Expand All @@ -83,4 +80,4 @@
"stackblitz": {
"startCommand": "pnpm dev:prepare && pnpm dev"
}
}
}
2 changes: 1 addition & 1 deletion playground/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
</template>

<script setup>
</script>
</script>
34 changes: 34 additions & 0 deletions playground/modules/resolved.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { defineNuxtModule, addTemplate, updateTemplates } from '@nuxt/kit'
import { resolve } from 'pathe'
import loadConfig from 'tailwindcss/loadConfig.js'
import resolveConfig from 'tailwindcss/resolveConfig.js'

export default defineNuxtModule({
setup (_options, nuxt) {
// logger.info('Creating test-tailwind.config.cjs...')
let counter = 1

nuxt.hook('tailwindcss:resolvedConfig', (config, oldConfig) =>
oldConfig
? setTimeout(() => updateTemplates({ filter: t => t.filename === 'resolved-config.cjs' }), 100)
: addTemplate({
filename: 'resolved-config.cjs',
getContents: () => `module.exports = /* ${counter++}, ${Boolean(oldConfig)} */ ${JSON.stringify(config, null, 2)}`,
write: true
})
)

// const template = addTemplate({
// filename: 'resolved-config.config.cjs', // gets prepended by .nuxt/
// getContents: ({ nuxt }) => {
// const config = loadConfig(resolve(nuxt.options.buildDir, 'tailwind.config.cjs'))
// return `module.exports = ${JSON.stringify(resolveConfig(config), null, 2)}`
// },
// write: true
// })

// nuxt.hook('app:templatesGenerated', (_app, templates) => {
// templates.map(t => t.dst).includes(resolve(nuxt.options.buildDir, 'tailwind.config.cjs')) && updateTemplates({ filter: t => t.dst === template.dst })
// })
}
})
27 changes: 27 additions & 0 deletions playground/modules/template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineNuxtModule, addTemplate } from '@nuxt/kit'

export default defineNuxtModule((_, nuxt) => {
const template = addTemplate({
filename: 'my-tw-config.cjs',
write: true,
getContents: () => `
const colors = require('tailwindcss/colors')

module.exports = {
theme: {
extend: {
colors: {
accent: colors.slate['500']
}
}
}
}
`
})

nuxt.options.tailwindcss = nuxt.options.tailwindcss ?? {}
if (!Array.isArray(nuxt.options.tailwindcss.configPath)) {
nuxt.options.tailwindcss.configPath = nuxt.options.tailwindcss.configPath ? [nuxt.options.tailwindcss.configPath] : ['tailwind.config']
}
nuxt.options.tailwindcss.configPath.push(template.dst)
})
45 changes: 42 additions & 3 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,58 @@
import { defineNuxtConfig } from 'nuxt/config'
import { existsSync } from 'node:fs'
import { resolve } from 'pathe'
import { consola } from 'consola'
import typography from '@tailwindcss/typography'

import type { ModuleHooks, ModuleOptions } from '../src/types'

const logger = consola.withTag('nuxt:tailwindcss:playground')

export default defineNuxtConfig({
extends: ['./theme'],
// builder: 'webpack',
modules: [
'@nuxt/content',
existsSync(resolve(__dirname, '../dist/module.mjs')) ? '@nuxtjs/tailwindcss' : '../src/module',
'@nuxt/devtools'
'@nuxt/content',
],
// @ts-ignore
tailwindcss: {
// viewer: false,
config: { plugins: [typography()] },
exposeConfig: true,
cssPath: '~/assets/css/tailwind.css',
editorSupport: true
},
} satisfies Partial<ModuleOptions>,
hooks: {
'tailwindcss:loadConfig': (config, configPath, idx) => {
logger.info('Running `tailwindcss:loadConfig` hook...', Object.keys(config || {}), { configPath, idx })

if (idx === 0 && config) {
config.theme = config.theme ?? {}
config.theme.extend = config.theme.extend ?? {}
config.theme.extend.screens = { md2: '100px' }
config.theme.extend.colors = config.theme.extend.colors ?? {}
// @ts-ignore
config.theme.extend.colors.zeroLayer = '#0fe325'
} else if (idx === 1 && config) {
config.content = config.content ?? []
Array.isArray(config.content) ? config.content.push('my-content') : config.content.files.push('my-file-content')
}
},
'tailwindcss:config': (config) => {
logger.info('Running `tailwindcss:config` hook...')

config.theme = config.theme ?? {}
config.theme.extend = config.theme.extend ?? {}
config.theme.extend.colors = config.theme.extend.colors ?? {}
// @ts-ignore
config.theme.extend.colors.twConfig = '#f0ff0f'
},
'tailwindcss:resolvedConfig': (config, oldConfig) => {
// @ts-ignore
logger.info('Running `tailwindcss:resolvedConfig` hook...', { typography: Boolean(config.theme.typography), hasOld: Boolean(oldConfig) })
}
} satisfies Partial<ModuleHooks>,
content: {
documentDriven: true
},
Expand Down
4 changes: 1 addition & 3 deletions playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@
"dev": "nuxi dev",
"build": "nuxi build",
"generate": "nuxi generate"
},
"dependencies": {},
"devDependencies": {}
}
}
13 changes: 13 additions & 0 deletions playground/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@
<span class="text-blue-500">meow!</span>
</div>
<p class="text-brand">
This color comes from the `./tailwind.config`
</p>
<p class="text-secondary">
This color comes from the `./theme` layer
</p>
<p class="text-accent">
This color comes from the `./modules/template` module
</p>
<p class="text-zeroLayer">
This color comes from the `tailwindcss:loadConfig` hook
</p>
<p class="text-twConfig">
This color comes from the `tailwindcss:config` hook
</p>
<div>
<NuxtLink
to="/content"
Expand All @@ -35,5 +47,6 @@
import { tw } from '#imports'
import tailwindConfig from '#tailwind-config'

// const tw = <T>(s: T) => s
const mainDivClass = tw`max-w-screen-lg p-4 mx-auto space-y-4`
</script>
3 changes: 2 additions & 1 deletion playground/theme/tailwind.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module.exports = {
theme: {
extend: {
colors: {
brand: colors.fuchsia['500']
brand: colors.fuchsia['500'],
secondary: colors.fuchsia['500']
}
}
}
Expand Down
Loading