Skip to content

Commit

Permalink
feat: implement vue-query module
Browse files Browse the repository at this point in the history
  • Loading branch information
Hebilicious committed May 31, 2023
1 parent 1accf36 commit 1b049a2
Show file tree
Hide file tree
Showing 24 changed files with 6,436 additions and 885 deletions.
105 changes: 99 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,117 @@
# ⚗️ My Module Nuxt
# ⚗️ Vue Query Nuxt

[![CI](https://github.com/Hebilicious/authjs-nuxt/actions/workflows/ci.yaml/badge.svg)](https://github.com/Hebilicious/authjs-nuxt/actions/workflows/ci.yaml)
[![npm version](https://badge.fury.io/js/@hebilicious%2Fauthjs-nuxt.svg)](https://badge.fury.io/js/@hebilicious%2Fauthjs-nuxt)
[![CI](https://github.com/Hebilicious/vue-query-nuxt/actions/workflows/ci.yaml/badge.svg)](https://github.com/Hebilicious/vue-query-nuxt/actions/workflows/ci.yaml)
[![npm version](https://badge.fury.io/js/@hebilicious%2Fvue-query-nuxt.svg)](https://badge.fury.io/js/@hebilicious%2Fvue-query-nuxt)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

🚀 Welcome to __Hebilicious Nuxt Module Starter Template__!
🚀 Welcome to __Vue Query Nuxt__!

This Nuxt Module automatically installs and configure Vue Query for your Nuxt application.
It has 0 config out-of-the box and extremely lightweight.

## ⚠️ Disclaimer

_🧪 This module is really unstable and is not recommended for production use. It is intended for those who want to experiment with the edge._
_🧪 This module is in active development._

Refer to the [Vue Query documentation](https://tanstack.com/query/latest/docs/vue/quick-start) for more information about Vue Query.

## 📦 Installation


1. Use npm, pnpm or yarn to install the dependencies.

```bash
npm i @hebilicious/vue-query-nuxt @tanstack/vue-query
```

```bash
npm i
pnpm i @hebilicious/vue-query-nuxt @tanstack/vue-query
```

```bash
yarn i @hebilicious/vue-query-nuxt @tanstack/vue-query
```

2. Add the modules to your Nuxt modules

```ts
// In nuxt.config.ts
export default defineNuxtConfig({
modules: ["@hebilicious/vue-query-nuxt"],
// These are the default values, you do not need to specify them.
// Refer to the vue-query docs for more information.
vueQuery: {
stateKey: "vue-query-nuxt",
queryClientOptions: {
defaultOptions: { queries: { staleTime: 5000 } } // default
},
vueQueryPluginOptions: {}
}
})
```

3. Use right away

```html
<script setup>
import { useQueryClient, useQuery, useMutation } from '@tanstack/vue-query'
// Access QueryClient instance
const queryClient = useQueryClient()
// Define a fetching function
const getTodos = () => $fetch("/api/todos")
// Query
const { isLoading, isError, data, error } = useQuery({
queryKey: ['todos'],
queryFn: getTodos,
})
// Mutation
const mutation = useMutation({
mutationFn: postTodo,
onSuccess: () => {
// Invalidate and refetch
queryClient.invalidateQueries({ queryKey: ['todos'] })
},
})
function onButtonClick() {
mutation.mutate({
id: Date.now(),
title: 'Do Laundry',
})
}
</script>

<template>
<span v-if="isLoading">Loading...</span>
<span v-else-if="isError">Error: {{ error.message }}</span>
<!-- We can assume by this point that `isSuccess === true` -->
<ul v-else>
<li v-for="todo in data" :key="todo.id">{{ todo.title }}</li>
</ul>
<button @click="onButtonClick">Add Todo</button>
</template>
```

4. Advanced configuration

Create a `vue-query.config.ts` file at the root of your project.

```ts
// vue-query.config.ts
import { library } from "@example/libray"

export default defineVueQueryPluginCallback((vueQueryOptions) => {
console.log(vueQueryOptions) // You can access the queryClient here
return { provide: { library, test: console } }
})
```

This callback will be run *directly* after the Vue Query plugin is installed, so you can use it to provide something here.
This can be useful if you want to configure something that needs the queryClient or you want to provide a library.

## 📦 Contributing

Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "@hebilicious/authjs-nuxt",
"name": "@hebilicious/vue-query-nuxt",
"type": "module",
"version": "0.1.0-beta.4",
"version": "0.0.1",
"private": true,
"packageManager": "[email protected]",
"scripts": {
"build": "rimraf packages/*/dist && pnpm -r --filter=./packages/* run build",
"nx:build": "nx run-many --target=build --p my-module",
"nx:build": "nx run-many --target=build --p vue-query-nuxt",
"lint": "eslint --cache .",
"lint:fix": "nr lint --fix",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
Expand All @@ -23,7 +23,7 @@
"eslint": "8.41.0",
"esno": "^0.16.3",
"lint-staged": "^13.2.2",
"nx": "^16.2.2",
"nx": "^16.3.0",
"pnpm": "8.6.0",
"prettier": "^2.8.8",
"rimraf": "^5.0.1",
Expand All @@ -32,7 +32,7 @@
"tsup": "^6.7.0",
"typescript": "^5.0.4",
"unbuild": "^1.2.1",
"vitest": "^0.31.2"
"vitest": "^0.31.3"
},
"simple-git-hooks": {
"pre-commit": "npx lint-staged"
Expand Down
24 changes: 0 additions & 24 deletions packages/my-module/build.config.ts

This file was deleted.

57 changes: 0 additions & 57 deletions packages/my-module/src/module.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/my-module/src/runtime/client.ts

This file was deleted.

6 changes: 0 additions & 6 deletions packages/my-module/src/runtime/composables/useSomething.ts

This file was deleted.

12 changes: 0 additions & 12 deletions packages/my-module/src/runtime/plugin.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/my-module/src/runtime/server.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/vue-query-nuxt/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shamefully-hoist=true
6 changes: 6 additions & 0 deletions packages/vue-query-nuxt/build.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { defineBuildConfig } from "unbuild"

export default defineBuildConfig({
entries: ["src/module"],
externals: ["@tanstack/vue-query"]
})
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "my-module",
"name": "@hebilicious/vue-query-nuxt",
"type": "module",
"version": "0.1.0-beta.4",
"version": "0.0.1",
"license": "MIT",
"repository": "Hebilicious/nuxt-module-template",
"repository": "Hebilicious/vue-query-nuxt",
"exports": {
".": {
"types": "./dist/module.d.ts",
Expand All @@ -26,15 +26,16 @@
"dev": "nuxi dev"
},
"peerDependencies": {
"nuxt": "latest",
"vite": "*"
"@tanstack/vue-query": "^4.29.11",
"nuxt": "3.5.2"
},
"dependencies": {
"@nuxt/kit": "3.4.2",
"defu": "^6.1.2"
"@nuxt/kit": "3.5.2",
"defu": "^6.1.2",
"esbuild": "^0.17.19",
"magicast": "^0.2.9"
},
"devDependencies": {
"@nuxt/module-builder": "^0.3.1",
"h3": "^1.6.5"
"@nuxt/module-builder": "^0.3.1"
}
}
File renamed without changes.
84 changes: 84 additions & 0 deletions packages/vue-query-nuxt/src/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { existsSync, promises as fsp } from "node:fs"
import { addImports, addPlugin, createResolver, defineNuxtModule, useLogger } from "@nuxt/kit"
import { defu } from "defu"
import { generateCode, loadFile } from "magicast"
import { transform } from "esbuild"
import { NAME, type VueQueryOptions, configKey, defaults } from "./runtime/utils"

export default defineNuxtModule<VueQueryOptions>({
meta: {
name: NAME,
configKey,
compatibility: {
nuxt: "^3"
}
},
defaults,
async setup(userOptions, nuxt) {
const logger = useLogger(NAME)
const { resolve } = createResolver(import.meta.url)

logger.info(`Adding ${NAME} module...`)

const { ...options } = userOptions
// 1. Set up runtime configuration
nuxt.options.runtimeConfig.public[configKey] = defu(nuxt.options.runtimeConfig.public[configKey], options, {})

// 2. Add plugin
addPlugin(resolve("./runtime/plugin"))

// 3. Add composable
addImports([{ name: "defineVueQueryPluginCallback", from: resolve("./runtime/composables/defineVueQueryPluginCallback") }])

const filename = "internal.vue-query-plugin-callback.mjs"

// 4. Write pluginCallback() to .nuxt
const writeFile = async () => {
let getContents = async () => "export default function pluginCallback() {}"
if (existsSync(resolve(nuxt.options.rootDir, "vue-query.config.ts"))) {
const configFile = resolve(nuxt.options.rootDir, "vue-query.config.ts")
const file = await loadFile(configFile)
if (file.exports.pluginCallback || file.exports.default) {
logger.success("Found vue-query.config.ts file")
if (!file.exports.pluginCallback) file.exports.pluginCallback = file.exports.default
delete file.exports.default
const { code } = generateCode(file) // We extract it with magicast...
const shaked = await transform(code, { treeShaking: true, loader: "ts" }) // ...we clean it with esbuild.
getContents = async () => `${shaked.code}`
}
else {
logger.error("Found vue-query.config.ts file, but it does not export a `pluginCallback`.")
}
}
else {
logger.info("No vue-query.config.ts file found.")
}
// Create file in .nuxt
const filePath = resolve(nuxt.options.buildDir, filename)
if (existsSync(filePath)) await fsp.rm(filePath)
await fsp.writeFile(filePath, await getContents())
}
writeFile()

// 4. Add types at the end of plugins.d.ts
nuxt.hook("build:before", async () => {
await fsp.appendFile(resolve(nuxt.options.buildDir, "types/plugins.d.ts"),
`declare module '#app' {
interface NuxtApp extends InjectionType<typeof import(".nuxt/${filename}").pluginCallback> { }
}`

)
})

// 5. Auto - reload the config
nuxt.hook("builder:watch", async (event, path) => {
if (path.includes("vue-query.config.ts")) {
logger.info(`[vue-query] config changed '@${event}'`, path)
writeFile()
logger.success("[vue-query] config reloaded.")
}
})

logger.success(`Added ${NAME} module successfully.`)
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import type { PluginCallbackParameters, ReturnedByPlugin } from "#build/internal.vue-query-plugin-callback"

export const defineVueQueryPluginCallback = (callback: (pluginCallbackParameters: PluginCallbackParameters) => ReturnedByPlugin): typeof callback => callback
Loading

0 comments on commit 1b049a2

Please sign in to comment.