N
Nuxt16h ago
Gus

Add a Nuxt module on top of an existing vue plugin library (without the official module-builder)

Hi everyone! I have a TypeScript library which has its core implemented as a framework agnostic components (it's actually a repository pattern to connect with my APIs). Inside of this same library I built a Vue Plugin to be able to use this library out of the box inside of any of my Vue SPA applications (I use Vite as bundler btw). So I can use import { anyRepo } from "my-lib" or import { installVuePlugin, useMyLib } from "my-lib/vue" - I could do this by adding Vue as peer deps and externalizing it as I build the library with Vite and I have 2 outputs being the root generic one and the Vue-ish one. Know, as nuxt as a few other constraints that I have to handle like I need to keep the requests within the request context in SSR and manage cookies properly there, I wanted to create a module similarly to what I did with Vue to use like // nuxtconfig -> modules: ['my-lib/nuxt']. My problem is that I could not manage to build the library as soon as I add nuxt! I used @nuxt/kit, installed nuxt and @nuxt/schema as dev-deps but it fails while building as inside of my module I need to use things like useRequestFetch and useCookie among others that I need to import from nuxt/app - which leads to an error like nuxt.config.mjs missing... error. Do you guys know any repo that I could get inspired to make this work? Or would anyone be able to guide me trhough that? I considered on creating a new library using the module builder with the my-lib being used under the hood but this is not a good option for me at the moment! I really appreciate if anyone could shed some light. The error I was getting while trying to build the application:
> vite build && tsc --emitDeclarationOnly
x Build failed in 146ms
error during build:
[commonjs--resolver] Missing "#build/nuxt.config.mjs" specifier in "nuxt" package
at e (.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/vite/dist/node/chunks/dep-BJP6rrE_.js:15287:25)
> vite build && tsc --emitDeclarationOnly
x Build failed in 146ms
error during build:
[commonjs--resolver] Missing "#build/nuxt.config.mjs" specifier in "nuxt" package
at e (.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/vite/dist/node/chunks/dep-BJP6rrE_.js:15287:25)
5 Replies
kapa.ai
kapa.ai16h ago
Hi @Gus. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To create a Nuxt module on top of an existing Vue plugin library without using the official module builder, you can follow these steps: 1. First, make sure you have @nuxt/kit installed as a dev dependency in your project. 2. Create a new file for your Nuxt module, for example, nuxt.js or module.ts in your library's root directory. 3. In this file, use defineNuxtModule from @nuxt/kit to define your module. Here's a basic structure:
import { defineNuxtModule, createResolver } from '@nuxt/kit'

export default defineNuxtModule({
meta: {
name: 'my-lib',
configKey: 'myLib'
},
defaults: {
// Your default options
},
setup(options, nuxt) {
const { resolve } = createResolver(import.meta.url)

// Your module setup logic here
}
})
import { defineNuxtModule, createResolver } from '@nuxt/kit'

export default defineNuxtModule({
meta: {
name: 'my-lib',
configKey: 'myLib'
},
defaults: {
// Your default options
},
setup(options, nuxt) {
const { resolve } = createResolver(import.meta.url)

// Your module setup logic here
}
})
4. To use Nuxt-specific composables like useRequestFetch and useCookie, you should not import them directly in your module file. Instead, you can create a plugin that will be added to the Nuxt app, where these composables are available. 5. Create a plugin file, for example, plugin.ts:
import { defineNuxtPlugin } from '#app'
import { useRequestFetch, useCookie } from '#app'
import { installVuePlugin, useMyLib } from 'my-lib/vue'

export default defineNuxtPlugin((nuxtApp) => {
// Install your Vue plugin
installVuePlugin(nuxtApp.vueApp)

// Use Nuxt-specific composables and your library
const fetch = useRequestFetch()
const cookie = useCookie('my-cookie')
const myLib = useMyLib()

// Your plugin logic here

return {
provide: {
myLib
}
}
})
import { defineNuxtPlugin } from '#app'
import { useRequestFetch, useCookie } from '#app'
import { installVuePlugin, useMyLib } from 'my-lib/vue'

export default defineNuxtPlugin((nuxtApp) => {
// Install your Vue plugin
installVuePlugin(nuxtApp.vueApp)

// Use Nuxt-specific composables and your library
const fetch = useRequestFetch()
const cookie = useCookie('my-cookie')
const myLib = useMyLib()

// Your plugin logic here

return {
provide: {
myLib
}
}
})
6. In your module setup, add this plugin to Nuxt:
setup(options, nuxt) {
const { resolve } = createResolver(import.meta.url)

// Add your plugin
nuxt.options.plugins.push(resolve('./plugin'))

// Other setup logic...
}
setup(options, nuxt) {
const { resolve } = createResolver(import.meta.url)

// Add your plugin
nuxt.options.plugins.push(resolve('./plugin'))

// Other setup logic...
}
7. To handle SSR-specific logic, you can use the nitro:config hook in your module:
nuxt.hook('nitro:config', (nitroConfig) => {
// SSR-specific configuration
})
nuxt.hook('nitro:config', (nitroConfig) => {
// SSR-specific configuration
})
By following these steps, you should be able to create a Nuxt module that wraps your existing Vue plugin library without using the official module builder. This approach allows you to use Nuxt-specific features while keeping your core library framework-agnostic. For more detailed information on creating Nuxt modules, you can refer to the Nuxt Module Author Guide. If you encounter any specific errors or issues while implementing this, please provide more details, and I'll be happy to help further. Docs > Guide > Concepts > Modules Docs > Api > Kit > Modules ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai16h ago
<@288791131234238466> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Gus
GusOP12h ago
I tried that already but it doesn't build =/ @kapa.ai the problem is that when I try to build it with a regular vite setup, it just fails with the following:
> vite build && tsc --emitDeclarationOnly
x Build failed in 146ms
error during build:
[commonjs--resolver] Missing "#build/nuxt.config.mjs" specifier in "nuxt" package
at e (.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/vite/dist/node/chunks/dep-BJP6rrE_.js:15287:25)
> vite build && tsc --emitDeclarationOnly
x Build failed in 146ms
error during build:
[commonjs--resolver] Missing "#build/nuxt.config.mjs" specifier in "nuxt" package
at e (.pnpm/[email protected]_@[email protected][email protected][email protected][email protected]/node_modules/vite/dist/node/chunks/dep-BJP6rrE_.js:15287:25)
It seems to me that it happens because if the import from nuxt/app
kapa.ai
kapa.ai12h ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the error message you've provided, it appears that the issue is related to how Vite is trying to resolve imports from the nuxt package during the build process. This is a common problem when trying to build a Nuxt module outside of a Nuxt project context. The error suggests that Vite is looking for a #build/nuxt.config.mjs file within the nuxt package, which doesn't exist in a standalone build environment. This is because Nuxt-specific imports like nuxt/app are typically resolved within a Nuxt project's context. To address this issue, you have a few options: 1. Use externalize in your Vite config: You can tell Vite to treat nuxt and related packages as external dependencies. This way, Vite won't try to resolve or bundle them during the build process. Add the following to your vite.config.js or vite.config.ts:
export default {
build: {
lib: {
entry: 'path/to/your/entry/file.ts',
formats: ['es', 'cjs'],
},
rollupOptions: {
external: ['nuxt', 'nuxt/app', '@nuxt/kit', '#app']
}
}
}

export default {
build: {
lib: {
entry: 'path/to/your/entry/file.ts',
formats: ['es', 'cjs'],
},
rollupOptions: {
external: ['nuxt', 'nuxt/app', '@nuxt/kit', '#app']
}
}
}

2. Use unjs/jiti for development: If you need to use Nuxt-specific imports during development, you can use jiti to run your module in a Node.js environment that can resolve these imports. Install jiti as a dev dependency and create a dev.js file:
import jiti from 'jiti'

const jitiRequire = jiti(import.meta.url, { interopDefault: true })
jitiRequire('./your-module-file')

import jiti from 'jiti'

const jitiRequire = jiti(import.meta.url, { interopDefault: true })
jitiRequire('./your-module-file')

Then run this file with Node.js for development purposes. 3. Separate Nuxt-specific code: Consider separating your Nuxt-specific code (like the plugin that uses useRequestFetch and useCookie) from your main module logic. Build your core functionality without Nuxt dependencies, and then create a thin wrapper that includes the Nuxt-specific parts. This wrapper can be distributed separately or included in your package but not built with Vite. 4. Use @nuxt/module-builder: Although you mentioned not wanting to use the official module builder, it's worth reconsidering as it's designed to handle these exact scenarios. It sets up the build process to correctly handle Nuxt-specific imports and configurations.
npx nuxi init my-module -t module

npx nuxi init my-module -t module

Nuxt Module Author Guide Remember, when your module is used in a Nuxt project, these imports will be resolved correctly. The challenge is in the standalone build and development process. If you decide to keep your current setup, option 1 (externalizing Nuxt dependencies in Vite) is likely the simplest solution to your immediate build error. However, you may need to combine this with option 3 (separating Nuxt-specific code) for a more robust long-term solution. Docs > Guide > Concepts > ES Modules > Troubleshooting ESM Issues ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai12h ago
<@288791131234238466> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?