Skip to content

Commit

Permalink
fix(viewer): provide workaround for nuxt2 modules:done serverMiddle…
Browse files Browse the repository at this point in the history
…ware race condition
  • Loading branch information
ineshbose committed Oct 14, 2024
1 parent 98296a8 commit 9d42549
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
17 changes: 10 additions & 7 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ twCtx.tryUse = () => {
}
twCtx.set = (instance, replace = true) => {
const resolvedConfig = instance && resolveConfig(instance)
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
resolvedConfig && useNuxt().callHook('tailwindcss:resolvedConfig', resolvedConfig, twCtx.tryUse() ?? undefined)

set(resolvedConfig as unknown as TWConfig, replace)
Expand Down Expand Up @@ -179,13 +180,13 @@ const createInternalContext = async (moduleOptions: ModuleOptions, nuxt = useNux
}).filter(Boolean)

return [
`// generated by the @nuxtjs/tailwindcss <https://github.com/nuxt-modules/tailwindcss> module at ${(new Date()).toLocaleString()}`,
`const configMerger = require(${JSON.stringify(createResolver(import.meta.url).resolve('./runtime/merger.js'))});`,
`\nconst inlineConfig = ${serializeConfig(moduleOptions.config as Partial<TWConfig>)};\n`,
'const config = [',
layerConfigs.join(',\n'),
`].reduce((prev, curr) => configMerger(curr, prev), configMerger(inlineConfig, { content: { files: ${JSON.stringify(contentPaths)} } }));\n`,
`module.exports = ${configUpdatedHook['main-config'] ? `(() => {const cfg=config;${configUpdatedHook['main-config']};return cfg;})()` : 'config'}\n`,
`// generated by the @nuxtjs/tailwindcss <https://github.com/nuxt-modules/tailwindcss> module at ${(new Date()).toLocaleString()}`,
`const configMerger = require(${JSON.stringify(createResolver(import.meta.url).resolve('./runtime/merger.js'))});`,
`\nconst inlineConfig = ${serializeConfig(moduleOptions.config as Partial<TWConfig>)};\n`,
'const config = [',
layerConfigs.join(',\n'),
`].reduce((prev, curr) => configMerger(curr, prev), configMerger(inlineConfig, { content: { files: ${JSON.stringify(contentPaths)} } }));\n`,
`module.exports = ${configUpdatedHook['main-config'] ? `(() => {const cfg=config;${configUpdatedHook['main-config']};return cfg;})()` : 'config'}\n`,
].join('\n')
},
})
Expand All @@ -208,10 +209,12 @@ const createInternalContext = async (moduleOptions: ModuleOptions, nuxt = useNux
nuxt.hook('tailwindcss:internal:regenerateTemplates', (data) => {
if (!data || !data.configTemplateUpdated) return
const configFile = server.moduleGraph.getModuleById(configResolvedPath)
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
configFile && server.moduleGraph.invalidateModule(configFile)
})
})

// eslint-disable-next-line @typescript-eslint/no-unused-expressions
moduleOptions.exposeConfig && nuxt.hook('builder:watch', async (_, path) => {
if (configPaths.includes(join(nuxt.options.rootDir, path))) {
twCtx.set(_loadConfig(configResolvedPath))
Expand Down
18 changes: 15 additions & 3 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { joinURL } from 'ufo'
import {
defineNuxtModule,
installModule,
isNuxt2,
getNuxtVersion,
resolvePath,
useNuxt,
createResolver,
addImports,
updateTemplates,
addTemplate,
isNuxtMajorVersion,
} from '@nuxt/kit'

// @ts-expect-error no declaration file
Expand Down Expand Up @@ -69,7 +69,7 @@ export default defineNuxtModule<ModuleOptions>({
if (moduleOptions.editorSupport || moduleOptions.addTwUtil) {
const editorSupportConfig = resolvers.resolveEditorSupportConfig(moduleOptions.editorSupport)

if ((editorSupportConfig.autocompleteUtil || moduleOptions.addTwUtil) && !isNuxt2()) {
if ((editorSupportConfig.autocompleteUtil || moduleOptions.addTwUtil) && !isNuxtMajorVersion(2, nuxt)) {
addImports({
name: 'autocompleteUtil',
from: createResolver(import.meta.url).resolve('./runtime/utils'),
Expand Down Expand Up @@ -100,12 +100,17 @@ export default defineNuxtModule<ModuleOptions>({
nuxt.options.css.splice(injectPosition, 0, resolvedCss)
}

// workaround for nuxt2 middleware race condition
let nuxt2ViewerConfig: Parameters<typeof setupViewer>[0] = join(nuxt.options.buildDir, 'tailwind.config.cjs')

nuxt.hook('modules:done', async () => {
const _config = await ctx.loadConfig()

const twConfig = ctx.generateConfig()
ctx.registerHooks()

nuxt2ViewerConfig = twConfig.dst || _config

// expose resolved tailwind config as an alias
if (moduleOptions.exposeConfig) {
const exposeConfig = resolvers.resolveExposeConfig({ level: moduleOptions.exposeLevel, ...(typeof moduleOptions.exposeConfig === 'object' ? moduleOptions.exposeConfig : {}) })
Expand All @@ -128,7 +133,7 @@ export default defineNuxtModule<ModuleOptions>({
}

// enabled only in development
if (nuxt.options.dev) {
if (nuxt.options.dev && !isNuxtMajorVersion(2, nuxt)) {
// add tailwind-config-viewer endpoint
if (moduleOptions.viewer) {
const viewerConfig = resolvers.resolveViewerConfig(moduleOptions.viewer)
Expand All @@ -150,13 +155,20 @@ export default defineNuxtModule<ModuleOptions>({
}
else {
// production only
if (!nuxt.options.dev) return

if (moduleOptions.viewer) {
const viewerConfig = resolvers.resolveViewerConfig(moduleOptions.viewer)

exportViewer(twConfig.dst || addTemplate({ filename: 'tailwind.config/viewer-config.cjs', getContents: () => `module.exports = ${JSON.stringify(_config)}`, write: true }).dst, viewerConfig)
}
}
})

if (nuxt.options.dev && moduleOptions.viewer && isNuxtMajorVersion(2, nuxt)) {
const viewerConfig = resolvers.resolveViewerConfig(moduleOptions.viewer)
setupViewer(nuxt2ViewerConfig, viewerConfig, nuxt)
}
},
})

Expand Down
7 changes: 3 additions & 4 deletions src/viewer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { colors } from 'consola/utils'
import { eventHandler, sendRedirect, H3Event } from 'h3'
import { addDevServerHandler, isNuxt2, isNuxt3, useNuxt } from '@nuxt/kit'
import { addDevServerHandler, isNuxtMajorVersion, useNuxt } from '@nuxt/kit'
import { withTrailingSlash, withoutTrailingSlash, joinURL, cleanDoubleSlashes } from 'ufo'
import loadConfig from 'tailwindcss/loadConfig.js'
import { relative } from 'pathe'
Expand All @@ -15,7 +15,7 @@ export const setupViewer = async (twConfig: string | TWConfig, config: ViewerCon
const viewerServer = (await import('tailwind-config-viewer/server/index.js').then(r => r.default || r))({ tailwindConfigProvider: typeof twConfig === 'string' ? () => loadConfig(twConfig) : () => twConfig }).asMiddleware()
const viewerDevMiddleware = eventHandler(event => viewerServer(event.node?.req || event.req, event.node?.res || event.res))

if (isNuxt3()) {
if (!isNuxtMajorVersion(2, nuxt)) {
addDevServerHandler({
handler: eventHandler((event) => {
if (event.path === routeWithoutSlash) {
Expand All @@ -25,8 +25,7 @@ export const setupViewer = async (twConfig: string | TWConfig, config: ViewerCon
})
addDevServerHandler({ route, handler: viewerDevMiddleware })
}

if (isNuxt2()) {
else {
// @ts-expect-error untyped nuxt2 property
nuxt.options.serverMiddleware.push(
// @ts-expect-error untyped handler parameters
Expand Down

0 comments on commit 9d42549

Please sign in to comment.