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

refactor: use new onPrehydrate hook for implementation #251

Merged
merged 4 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
14 changes: 0 additions & 14 deletions build.config.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
import { promises as fsp } from 'node:fs'

import { defineBuildConfig } from 'unbuild'
import { transform } from 'esbuild'

export default defineBuildConfig({
rollup: { emitCJS: true },
externals: ['node:url'],
hooks: {
async 'build:done'() {
const script = await fsp.readFile('./src/script.mjs', 'utf-8')
const { code } = await transform(script, {
loader: 'js',
format: 'esm',
minify: true,
})
await fsp.writeFile('./dist/script.mjs', code, 'utf-8')
},
},
})
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
"@vitest/coverage-v8": "2.1.1",
"@vue/test-utils": "2.4.6",
"bumpp": "9.5.2",
"esbuild": "0.23.1",
"eslint": "9.10.0",
"expect-type": "0.20.0",
"get-port-please": "3.1.2",
Expand All @@ -75,6 +74,9 @@
"vitest-environment-nuxt": "1.0.1",
"vue": "3.5.6"
},
"peerDependencies": {
"nuxt": ">=3.12.0"
},
"resolutions": {
"@nuxt/kit": "3.13.2",
"nuxt-time": "link:."
Expand Down
1,160 changes: 87 additions & 1,073 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

15 changes: 4 additions & 11 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { promises as fsp } from 'node:fs'
import { defineNuxtModule, createResolver, addComponentsDir, addTemplate } from '@nuxt/kit'
import { defineNuxtModule, createResolver, addComponentsDir } from '@nuxt/kit'

// eslint-disable-next-line @typescript-eslint/no-empty-object-type
export interface ModuleOptions {}
Expand All @@ -8,20 +7,14 @@ export default defineNuxtModule<ModuleOptions>({
meta: {
configKey: 'time',
name: 'nuxt-time',
compatibility: {
nuxt: '>=3.12.0',
},
},
async setup() {
const resolver = createResolver(import.meta.url)

// Add <NuxtTime> component
addComponentsDir({ path: resolver.resolve('./runtime/components') })

const script = await fsp.readFile(resolver.resolve('./script.mjs'), 'utf-8')

addTemplate({
filename: 'nuxt-time-script.mjs',
getContents() {
return `export default ${JSON.stringify(script.trim())}`
},
})
},
})
31 changes: 21 additions & 10 deletions src/runtime/components/NuxtTime.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<script setup lang='ts'>
import { computed, getCurrentInstance, useNuxtApp, useHead } from '#imports'
import scriptContents from '#build/nuxt-time-script.mjs'
import { computed, getCurrentInstance, onPrehydrate, useNuxtApp } from '#imports'

const props = withDefaults(defineProps<{
locale?: string
Expand Down Expand Up @@ -59,20 +58,32 @@ if (import.meta.server) {
dataset[`data-${propInKebabCase}`] = props?.[prop as keyof typeof props]
}
}
useHead({
script: [{
tagPosition: 'bodyClose',
tagPriority: -20,
key: 'nuxt-time',
innerHTML: scriptContents,
}],
onPrehydrate((el) => {
const toCamelCase = (name: string, index: number) => {
if (index > 0) {
return name[0].toUpperCase() + name.slice(1)
}
return name
}

const date = new Date(el.getAttribute('datetime')!)
const options: Intl.DateTimeFormatOptions & { locale?: Intl.LocalesArgument } = {}
for (const name of el.getAttributeNames()) {
if (name.startsWith('data-')) {
const optionName = name.slice(5).split('-').map(toCamelCase).join('') as keyof Intl.DateTimeFormatOptions
// eslint-disable-next-line @typescript-eslint/no-explicit-any
options[optionName] = el.getAttribute(name) as any
}
}

const formatter = new Intl.DateTimeFormat(options.locale, options)
el.textContent = formatter.format(date)
})
}
</script>

<template>
<time
data-n-time
v-bind="dataset"
:datetime="isoDate"
>{{ formattedDate }}</time>
Expand Down
20 changes: 0 additions & 20 deletions src/script.mjs

This file was deleted.

8 changes: 4 additions & 4 deletions test/e2e.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fileURLToPath } from 'node:url'
import { describe, it, expect } from 'vitest'
import { setup, $fetch, createPage, url } from '@nuxt/test-utils/e2e'
import { anyOf, createRegExp, exactly } from 'magic-regexp'
import { createRegExp, exactly } from 'magic-regexp'

await setup({
server: true,
Expand All @@ -12,16 +12,16 @@ await setup({
describe('nuxt-time', async () => {
it('ssr', async () => {
const html = await $fetch('/')
const snap = html.match(/<time[^>]*data-testid="fixed"[^>]*>([^<]*)<\/time>/)?.[0]
const snap = html.match(/<time[^>]*data-testid="fixed"[^>]*>([^<]*)<\/time>/)?.[0].replace(/ data-prehydrate-id="[^"]*"/g, '')
expect(snap).toContain(
'<time data-n-time data-month="long" data-day="numeric" datetime="2023-02-11T08:24:08.396Z" data-testid="fixed">',
'<time data-month="long" data-day="numeric" datetime="2023-02-11T08:24:08.396Z" data-testid="fixed">',
)
})

it('injects one script', async () => {
const html = await $fetch('/')

const string = createRegExp(exactly('document.querySelectorAll(').and(anyOf('"', '\'')).and('[data-n-time]'), ['g'])
const string = createRegExp(exactly('document.querySelectorAll'), ['g'])
expect(html.match(string)?.length).toEqual(1)
})

Expand Down
2 changes: 1 addition & 1 deletion test/unit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('<NuxtTime>', () => {
}),
)
expect(thing.html()).toMatchInlineSnapshot(
`"<time data-n-time="" datetime="2023-02-11T18:26:41.058Z">11 February at 41</time>"`,
`"<time datetime="2023-02-11T18:26:41.058Z">11 February at 41</time>"`,
)
})
})
Loading