diff --git a/README.md b/README.md
index 0fafafd..662f239 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ interface NuxtRuntimeCompilerOptions {
You can specify the node_modules root directory if your `node_modules` directory is not at your `process.cwd()`.
-Default value is `./`
+- Default value is `./`
For example if you are running `nuxt build` from a project in `root/packages/{YOUR_WORKSPACE}` while your `node_modules` is in `root/`
then the nodeModulesRoot should be
@@ -39,3 +39,27 @@ export default defineNuxtConfig({
}]
})
```
+
+## RuntimeCompilerOptions
+
+See [app.config documentation](https://nuxt.com/docs/examples/app/app-config)
+This module overloads the `AppConfig` exported by `app.config.ts` to pass the [RuntimeCompilerOptions](https://github.com/vuejs/core/blob/dbe7109c8f6417770129dc92313f05feac0c0edb/packages/runtime-core/src/componentOptions.ts#L213-L218) to your VueApp in runtime.
+
+Compatible options from [RuntimeCompilerOptions](https://github.com/vuejs/core/blob/dbe7109c8f6417770129dc92313f05feac0c0edb/packages/runtime-core/src/componentOptions.ts#L213-L218) in `app.config` will also be used by the builder during build time.
+
+`app.config.ts`
+
+```ts
+export default defineAppConfig({
+ vue: {
+ compilerOptions: {
+ isCustomElement: (tag) => {
+ return [
+ 'math',
+ 'maction',
+ ].includes(tag)
+ }
+ }
+ }
+})
+```
\ No newline at end of file
diff --git a/package.json b/package.json
index 2d41a2c..82cd63a 100644
--- a/package.json
+++ b/package.json
@@ -25,12 +25,12 @@
"dev": "nuxi dev playground",
"dev:build": "nuxi build playground",
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
- "test": "vitest --dir test",
+ "test": "yarn nuxi prepare ./test/fixtures/basic && vitest --dir test",
"test:dev": "npx cross-env NUXT_TEST_DEV=true yarn test",
- "test:webpack": "npx cross-env BUILDER=webpack vitest --dir test",
+ "test:webpack": "npx cross-env BUILDER=webpack vitest --dir test",
"test:external-vue-disabled": "npx cross-env FIXTURE=external-vue-disabled yarn test",
"test:external-vue-disabled:dev": "npx cross-env NUXT_TEST_DEV=true FIXTURE=external-vue-disabled yarn test",
- "test:external-vue-disabled:webpack": "npx cross-env BUILDER=webpack FIXTURE=external-vue-disabled yarn test",
+ "test:external-vue-disabled:webpack": "npx cross-env BUILDER=webpack FIXTURE=external-vue-disabled yarn test",
"lint": "eslint --ext .vue,.js,.ts ./"
},
"dependencies": {
diff --git a/playground/app.config.ts b/playground/app.config.ts
new file mode 100644
index 0000000..f47cfdd
--- /dev/null
+++ b/playground/app.config.ts
@@ -0,0 +1,94 @@
+export default defineAppConfig({
+ vue: {
+ compilerOptions: {
+ isCustomElement: (tag) => {
+ return ['math',
+ 'maction',
+ 'maligngroup',
+ 'malignmark',
+ 'menclose',
+ 'merror',
+ 'mfenced',
+ 'mfrac',
+ 'mi',
+ 'mlongdiv',
+ 'mmultiscripts',
+ 'mn',
+ 'mo',
+ 'mover',
+ 'mpadded',
+ 'mphantom',
+ 'mroot',
+ 'mrow',
+ 'ms',
+ 'mscarries',
+ 'mscarry',
+ 'mscarries',
+ 'msgroup',
+ 'mstack',
+ 'mlongdiv',
+ 'msline',
+ 'mstack',
+ 'mspace',
+ 'msqrt',
+ 'msrow',
+ 'mstack',
+ 'mstack',
+ 'mstyle',
+ 'msub',
+ 'msup',
+ 'msubsup',
+ 'mtable',
+ 'mtd',
+ 'mtext',
+ 'mtr',
+ 'munder',
+ 'munderover',
+ 'semantics',
+ 'math',
+ 'mi',
+ 'mn',
+ 'mo',
+ 'ms',
+ 'mspace',
+ 'mtext',
+ 'menclose',
+ 'merror',
+ 'mfenced',
+ 'mfrac',
+ 'mpadded',
+ 'mphantom',
+ 'mroot',
+ 'mrow',
+ 'msqrt',
+ 'mstyle',
+ 'mmultiscripts',
+ 'mover',
+ 'mprescripts',
+ 'msub',
+ 'msubsup',
+ 'msup',
+ 'munder',
+ 'munderover',
+ 'none',
+ 'maligngroup',
+ 'malignmark',
+ 'mtable',
+ 'mtd',
+ 'mtr',
+ 'mlongdiv',
+ 'mscarries',
+ 'mscarry',
+ 'msgroup',
+ 'msline',
+ 'msrow',
+ 'mstack',
+ 'maction',
+ 'semantics',
+ 'annotation',
+ 'annotation-xml'
+ ].includes(tag)
+ }
+ }
+ }
+})
diff --git a/src/module.ts b/src/module.ts
index 909fbbb..4d8fbad 100644
--- a/src/module.ts
+++ b/src/module.ts
@@ -1,5 +1,7 @@
-import { defineNuxtModule, isNuxt2, isNuxt3 } from '@nuxt/kit'
-import { resolve } from 'pathe'
+import { resolve } from 'path'
+import { existsSync } from 'fs'
+import { addPlugin, createResolver, defineNuxtModule, isNuxt2, isNuxt3, resolvePath } from '@nuxt/kit'
+import type { AppConfig } from '@nuxt/schema'
interface NuxtRuntimeCompilerOptions {
nodeModulesRoot?: string
@@ -10,9 +12,7 @@ export default defineNuxtModule({
name: 'nuxt-runtime-compiler',
configKey: 'nuxtRuntimeCompiler'
},
- setup (options: NuxtRuntimeCompilerOptions, nuxt) {
- const { nodeModulesRoot = './' } = options
-
+ async setup ({ nodeModulesRoot = './' } : NuxtRuntimeCompilerOptions, nuxt) {
if (isNuxt2(nuxt)) {
/** override all nuxt default vue aliases to force uses of the full bundle of VueJS */
const vueFullCommonPath = 'vue/dist/vue.common.js'
@@ -124,6 +124,52 @@ export default defineNuxtModule({
}
})
})
+
+ const resolver = createResolver(import.meta.url)
+ const runtimeDir = await resolver.resolve('./runtime')
+ nuxt.options.build.transpile.push(runtimeDir)
+
+ addPlugin(resolve(runtimeDir, 'nuxt-runtime-compiler.plugin.ts'))
+
+ nuxt.hook('prepare:types', ({ references }) => {
+ references.push({ path: resolve(runtimeDir, 'types.d.ts') })
+ })
+
+ const appConfigPath = await resolvePath('app.config')
+
+ // use AppConfig to define vue compiler options at build time
+ if (existsSync(appConfigPath)) {
+ const globalDefineAppConfig = (globalThis as any).defineAppConfig
+
+ if (!globalDefineAppConfig) {
+ // allow defineAppConfig
+ (globalThis as any).defineAppConfig = (c: any) => c
+ }
+ const appConfig = await import(appConfigPath) as AppConfig
+
+ nuxt.options.vite.vue = {
+ ...nuxt.options.vite.vue,
+ template: {
+ ...nuxt.options.vite.vue?.template,
+ compilerOptions: {
+ ...nuxt.options.vite.vue?.template?.compilerOptions,
+ ...appConfig.vue?.compilerOptions
+ }
+ }
+ }
+
+ nuxt.options.webpack.loaders.vue = {
+ ...nuxt.options.webpack.loaders.vue,
+ compilerOptions: {
+ ...nuxt.options.webpack.loaders.vue.compilerOptions,
+ ...appConfig.vue?.compilerOptions
+ }
+ }
+
+ if (!globalDefineAppConfig) {
+ delete (globalThis as any).defineAppConfig
+ }
+ }
}
}
})
diff --git a/src/runtime/nuxt-runtime-compiler.plugin.ts b/src/runtime/nuxt-runtime-compiler.plugin.ts
new file mode 100644
index 0000000..818cfa9
--- /dev/null
+++ b/src/runtime/nuxt-runtime-compiler.plugin.ts
@@ -0,0 +1,6 @@
+import { defineNuxtPlugin, useAppConfig } from '#imports'
+
+export default defineNuxtPlugin((nuxtApp) => {
+ const appConfig = useAppConfig()
+ nuxtApp.vueApp.config.compilerOptions.isCustomElement = appConfig.vue?.compilerOptions?.isCustomElement
+})
diff --git a/src/runtime/types.d.ts b/src/runtime/types.d.ts
new file mode 100644
index 0000000..3fb663c
--- /dev/null
+++ b/src/runtime/types.d.ts
@@ -0,0 +1,16 @@
+
+import { RuntimeCompilerOptions } from 'vue'
+
+declare module '@nuxt/schema' {
+ interface AppConfig {
+ vue?: {
+ compilerOptions?: RuntimeCompilerOptions
+ }
+ }
+
+ interface AppConfigInput {
+ vue?: {
+ compilerOptions?: RuntimeCompilerOptions
+ }
+ }
+}
diff --git a/test/fixtures/basic/app.config.ts b/test/fixtures/basic/app.config.ts
new file mode 100644
index 0000000..0becd28
--- /dev/null
+++ b/test/fixtures/basic/app.config.ts
@@ -0,0 +1,95 @@
+export default defineAppConfig({
+ vue: {
+ compilerOptions: {
+ isCustomElement: (tag) => {
+ return [
+ 'math',
+ 'maction',
+ 'maligngroup',
+ 'malignmark',
+ 'menclose',
+ 'merror',
+ 'mfenced',
+ 'mfrac',
+ 'mi',
+ 'mlongdiv',
+ 'mmultiscripts',
+ 'mn',
+ 'mo',
+ 'mover',
+ 'mpadded',
+ 'mphantom',
+ 'mroot',
+ 'mrow',
+ 'ms',
+ 'mscarries',
+ 'mscarry',
+ 'mscarries',
+ 'msgroup',
+ 'mstack',
+ 'mlongdiv',
+ 'msline',
+ 'mstack',
+ 'mspace',
+ 'msqrt',
+ 'msrow',
+ 'mstack',
+ 'mstack',
+ 'mstyle',
+ 'msub',
+ 'msup',
+ 'msubsup',
+ 'mtable',
+ 'mtd',
+ 'mtext',
+ 'mtr',
+ 'munder',
+ 'munderover',
+ 'semantics',
+ 'math',
+ 'mi',
+ 'mn',
+ 'mo',
+ 'ms',
+ 'mspace',
+ 'mtext',
+ 'menclose',
+ 'merror',
+ 'mfenced',
+ 'mfrac',
+ 'mpadded',
+ 'mphantom',
+ 'mroot',
+ 'mrow',
+ 'msqrt',
+ 'mstyle',
+ 'mmultiscripts',
+ 'mover',
+ 'mprescripts',
+ 'msub',
+ 'msubsup',
+ 'msup',
+ 'munder',
+ 'munderover',
+ 'none',
+ 'maligngroup',
+ 'malignmark',
+ 'mtable',
+ 'mtd',
+ 'mtr',
+ 'mlongdiv',
+ 'mscarries',
+ 'mscarry',
+ 'msgroup',
+ 'msline',
+ 'msrow',
+ 'mstack',
+ 'maction',
+ 'semantics',
+ 'annotation',
+ 'annotation-xml'
+ ].includes(tag)
+ }
+ }
+ }
+})
diff --git a/test/fixtures/basic/nuxt.config.ts b/test/fixtures/basic/nuxt.config.ts
index cca2e73..cc65f6c 100644
--- a/test/fixtures/basic/nuxt.config.ts
+++ b/test/fixtures/basic/nuxt.config.ts
@@ -1,4 +1,3 @@
-import { defineNuxtConfig } from 'nuxt/config'
import nuxtRuntimeCompiler from '../../../src/module'
export default defineNuxtConfig({
diff --git a/test/fixtures/basic/pages/index.vue b/test/fixtures/basic/pages/index.vue
index 865a88e..084627c 100644
--- a/test/fixtures/basic/pages/index.vue
+++ b/test/fixtures/basic/pages/index.vue
@@ -41,11 +41,45 @@ const Interactive = h({
},
props: data.value?.interactiveComponent.props
}) as Component
+
+const CustomElementComponent = defineComponent({
+ template: ` `
+})
+
diff --git a/tsconfig.json b/tsconfig.json
index 62575cf..0d4eaf3 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -12,6 +12,9 @@
"resolveJsonModule": true,
"types": [
"node"
- ]
+ ],
+ "paths": {
+ "#imports": ["./node_modules/nuxt/app.d.ts"],
+ }
}
}
\ No newline at end of file