fix(vite): respect isCustomElement config for jsx transform (#19053)

This commit is contained in:
Nick Williams 2023-02-16 12:45:08 +00:00 committed by GitHub
parent 96b09ea982
commit 9dc5413cbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 70 additions and 20 deletions

View File

@ -30,6 +30,7 @@ export default defineBuildConfig({
'rollup-plugin-visualizer', 'rollup-plugin-visualizer',
'vite', 'vite',
'@vitejs/plugin-vue', '@vitejs/plugin-vue',
'@vitejs/plugin-vue-jsx',
'mini-css-extract-plugin', 'mini-css-extract-plugin',
'terser-webpack-plugin', 'terser-webpack-plugin',
'css-minimizer-webpack-plugin', 'css-minimizer-webpack-plugin',

View File

@ -18,6 +18,7 @@
"@types/semver": "^7.3.13", "@types/semver": "^7.3.13",
"@unhead/schema": "^1.0.22", "@unhead/schema": "^1.0.22",
"@vitejs/plugin-vue": "^4.0.0", "@vitejs/plugin-vue": "^4.0.0",
"@vitejs/plugin-vue-jsx": "^3.0.0",
"nitropack": "^2.2.1", "nitropack": "^2.2.1",
"unbuild": "latest", "unbuild": "latest",
"vite": "~4.1.1" "vite": "~4.1.1"

View File

@ -43,6 +43,14 @@ export default defineUntypedSchema({
} }
} }
}, },
vueJsx: {
$resolve: async (val, get) => {
return {
isCustomElement: (await get('vue')).compilerOptions?.isCustomElement,
...(val || {})
}
}
},
optimizeDeps: { optimizeDeps: {
exclude: { exclude: {
$resolve: async (val, get) => [ $resolve: async (val, get) => [

View File

@ -2,6 +2,7 @@ import type { KeepAliveProps, TransitionProps } from 'vue'
import type { ConfigSchema } from '../../schema/config' import type { ConfigSchema } from '../../schema/config'
import type { ServerOptions as ViteServerOptions, UserConfig as ViteUserConfig } from 'vite' import type { ServerOptions as ViteServerOptions, UserConfig as ViteUserConfig } from 'vite'
import type { Options as VuePluginOptions } from '@vitejs/plugin-vue' import type { Options as VuePluginOptions } from '@vitejs/plugin-vue'
import type { Options as VueJsxPluginOptions } from '@vitejs/plugin-vue-jsx'
import type { AppHeadMetaObject } from './meta' import type { AppHeadMetaObject } from './meta'
import type { Nuxt } from './nuxt' import type { Nuxt } from './nuxt'
import type { SchemaDefinition } from 'untyped' import type { SchemaDefinition } from 'untyped'
@ -95,10 +96,16 @@ export interface NuxtOptions extends Omit<ConfigSchema, 'builder'> {
export interface ViteConfig extends ViteUserConfig { export interface ViteConfig extends ViteUserConfig {
/** /**
* Options passed to @vitejs/plugin-vue * Options passed to @vitejs/plugin-vue
* @see https://github.com/vitejs/vite/tree/main/packages/plugin-vue * @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue
*/ */
vue?: VuePluginOptions vue?: VuePluginOptions
/**
* Options passed to @vitejs/plugin-vue-jsx
* @see https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue-jsx
*/
vueJsx?: VueJsxPluginOptions
/** /**
* Bundler for dev time server-side rendering. * Bundler for dev time server-side rendering.
* @default 'vite-node' * @default 'vite-node'

View File

@ -61,7 +61,7 @@ export async function buildClient (ctx: ViteBuildContext) {
plugins: [ plugins: [
cacheDirPlugin(ctx.nuxt.options.rootDir, 'client'), cacheDirPlugin(ctx.nuxt.options.rootDir, 'client'),
vuePlugin(ctx.config.vue), vuePlugin(ctx.config.vue),
viteJsxPlugin(), viteJsxPlugin(ctx.config.vueJsx),
devStyleSSRPlugin({ devStyleSSRPlugin({
srcDir: ctx.nuxt.options.srcDir, srcDir: ctx.nuxt.options.srcDir,
buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir) buildAssetsURL: joinURL(ctx.nuxt.options.app.baseURL, ctx.nuxt.options.app.buildAssetsDir)

View File

@ -110,7 +110,7 @@ export async function buildServer (ctx: ViteBuildContext) {
plugins: [ plugins: [
cacheDirPlugin(ctx.nuxt.options.rootDir, 'server'), cacheDirPlugin(ctx.nuxt.options.rootDir, 'server'),
vuePlugin(ctx.config.vue), vuePlugin(ctx.config.vue),
viteJsxPlugin() viteJsxPlugin(ctx.config.vueJsx)
] ]
} as ViteOptions) } as ViteOptions)

View File

@ -3,7 +3,8 @@ import { join, resolve } from 'pathe'
import type { Nuxt } from '@nuxt/schema' import type { Nuxt } from '@nuxt/schema'
import type { InlineConfig, SSROptions } from 'vite' import type { InlineConfig, SSROptions } from 'vite'
import { logger, isIgnored, resolvePath, addVitePlugin } from '@nuxt/kit' import { logger, isIgnored, resolvePath, addVitePlugin } from '@nuxt/kit'
import type { Options } from '@vitejs/plugin-vue' import type { Options as VueOptions } from '@vitejs/plugin-vue'
import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx'
import replace from '@rollup/plugin-replace' import replace from '@rollup/plugin-replace'
import { sanitizeFilePath } from 'mlly' import { sanitizeFilePath } from 'mlly'
import { withoutLeadingSlash } from 'ufo' import { withoutLeadingSlash } from 'ufo'
@ -17,7 +18,8 @@ import { resolveCSSOptions } from './css'
import { composableKeysPlugin } from './plugins/composable-keys' import { composableKeysPlugin } from './plugins/composable-keys'
export interface ViteOptions extends InlineConfig { export interface ViteOptions extends InlineConfig {
vue?: Options vue?: VueOptions
vueJsx?: VueJsxOptions
ssr?: SSROptions ssr?: SSROptions
devBundler?: 'vite-node' | 'legacy' devBundler?: 'vite-node' | 'legacy'
} }

View File

@ -513,6 +513,7 @@ importers:
'@types/semver': ^7.3.13 '@types/semver': ^7.3.13
'@unhead/schema': ^1.0.22 '@unhead/schema': ^1.0.22
'@vitejs/plugin-vue': ^4.0.0 '@vitejs/plugin-vue': ^4.0.0
'@vitejs/plugin-vue-jsx': ^3.0.0
c12: ^1.1.0 c12: ^1.1.0
create-require: ^1.1.1 create-require: ^1.1.1
defu: ^6.1.2 defu: ^6.1.2
@ -548,6 +549,7 @@ importers:
'@types/semver': 7.3.13 '@types/semver': 7.3.13
'@unhead/schema': 1.0.22 '@unhead/schema': 1.0.22
'@vitejs/plugin-vue': 4.0.0_vite@4.1.1 '@vitejs/plugin-vue': 4.0.0_vite@4.1.1
'@vitejs/plugin-vue-jsx': 3.0.0_vite@4.1.1
nitropack: 2.2.1 nitropack: 2.2.1
unbuild: 1.1.1 unbuild: 1.1.1
vite: 4.1.1 vite: 4.1.1
@ -849,7 +851,6 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.20.7
dev: false
/@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12: /@babel/helper-compilation-targets/7.20.7_@babel+core@7.20.12:
resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==} resolution: {integrity: sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==}
@ -881,7 +882,6 @@ packages:
'@babel/helper-split-export-declaration': 7.18.6 '@babel/helper-split-export-declaration': 7.18.6
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: false
/@babel/helper-environment-visitor/7.18.9: /@babel/helper-environment-visitor/7.18.9:
resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
@ -905,7 +905,6 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.20.7
dev: false
/@babel/helper-module-imports/7.18.6: /@babel/helper-module-imports/7.18.6:
resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
@ -933,12 +932,10 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.20.7
dev: false
/@babel/helper-plugin-utils/7.20.2: /@babel/helper-plugin-utils/7.20.2:
resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dev: false
/@babel/helper-replace-supers/7.20.7: /@babel/helper-replace-supers/7.20.7:
resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==}
@ -952,7 +949,6 @@ packages:
'@babel/types': 7.20.7 '@babel/types': 7.20.7
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: false
/@babel/helper-simple-access/7.20.2: /@babel/helper-simple-access/7.20.2:
resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==}
@ -965,7 +961,6 @@ packages:
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
dependencies: dependencies:
'@babel/types': 7.20.7 '@babel/types': 7.20.7
dev: false
/@babel/helper-split-export-declaration/7.18.6: /@babel/helper-split-export-declaration/7.18.6:
resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
@ -1018,7 +1013,6 @@ packages:
dependencies: dependencies:
'@babel/core': 7.20.12 '@babel/core': 7.20.12
'@babel/helper-plugin-utils': 7.20.2 '@babel/helper-plugin-utils': 7.20.2
dev: false
/@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.20.12: /@babel/plugin-syntax-typescript/7.20.0_@babel+core@7.20.12:
resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==}
@ -1028,7 +1022,6 @@ packages:
dependencies: dependencies:
'@babel/core': 7.20.12 '@babel/core': 7.20.12
'@babel/helper-plugin-utils': 7.20.2 '@babel/helper-plugin-utils': 7.20.2
dev: false
/@babel/plugin-transform-typescript/7.20.13_@babel+core@7.20.12: /@babel/plugin-transform-typescript/7.20.13_@babel+core@7.20.12:
resolution: {integrity: sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==} resolution: {integrity: sha512-O7I/THxarGcDZxkgWKMUrk7NK1/WbHAg3Xx86gqS6x9MTrNL6AwIluuZ96ms4xeDe6AVx6rjHbWHP7x26EPQBA==}
@ -1042,7 +1035,6 @@ packages:
'@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.12 '@babel/plugin-syntax-typescript': 7.20.0_@babel+core@7.20.12
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: false
/@babel/standalone/7.20.15: /@babel/standalone/7.20.15:
resolution: {integrity: sha512-B3LmZ1NHlTb2eFEaw8rftZc730Wh9MlmsH8ubb6IjsNoIk9+SQ2aAA0nrm/1806+PftPRAACPClmKTu8PG7Tew==} resolution: {integrity: sha512-B3LmZ1NHlTb2eFEaw8rftZc730Wh9MlmsH8ubb6IjsNoIk9+SQ2aAA0nrm/1806+PftPRAACPClmKTu8PG7Tew==}
@ -2764,6 +2756,21 @@ packages:
- encoding - encoding
- supports-color - supports-color
/@vitejs/plugin-vue-jsx/3.0.0_vite@4.1.1:
resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==}
engines: {node: ^14.18.0 || >=16.0.0}
peerDependencies:
vite: ^4.0.0
vue: ^3.0.0
dependencies:
'@babel/core': 7.20.12
'@babel/plugin-transform-typescript': 7.20.13_@babel+core@7.20.12
'@vue/babel-plugin-jsx': 1.1.1_@babel+core@7.20.12
vite: 4.1.1
transitivePeerDependencies:
- supports-color
dev: true
/@vitejs/plugin-vue-jsx/3.0.0_vite@4.1.1+vue@3.2.47: /@vitejs/plugin-vue-jsx/3.0.0_vite@4.1.1+vue@3.2.47:
resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==} resolution: {integrity: sha512-vurkuzgac5SYuxd2HUZqAFAWGTF10diKBwJNbCvnWijNZfXd+7jMtqjPFbGt7idOJUn584fP1Ar9j/GN2jQ3Ew==}
engines: {node: ^14.18.0 || >=16.0.0} engines: {node: ^14.18.0 || >=16.0.0}
@ -2874,7 +2881,6 @@ packages:
/@vue/babel-helper-vue-transform-on/1.0.2: /@vue/babel-helper-vue-transform-on/1.0.2:
resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==} resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==}
dev: false
/@vue/babel-plugin-jsx/1.1.1_@babel+core@7.20.12: /@vue/babel-plugin-jsx/1.1.1_@babel+core@7.20.12:
resolution: {integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==} resolution: {integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==}
@ -2891,7 +2897,6 @@ packages:
transitivePeerDependencies: transitivePeerDependencies:
- '@babel/core' - '@babel/core'
- supports-color - supports-color
dev: false
/@vue/compiler-core/3.2.47: /@vue/compiler-core/3.2.47:
resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==} resolution: {integrity: sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==}
@ -3573,7 +3578,6 @@ packages:
/camelcase/6.3.0: /camelcase/6.3.0:
resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
engines: {node: '>=10'} engines: {node: '>=10'}
dev: false
/caniuse-api/3.0.0: /caniuse-api/3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
@ -5545,7 +5549,6 @@ packages:
/html-tags/3.2.0: /html-tags/3.2.0:
resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==} resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==}
engines: {node: '>=8'} engines: {node: '>=8'}
dev: false
/htmlparser2/3.10.1: /htmlparser2/3.10.1:
resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
@ -8069,7 +8072,6 @@ packages:
/svg-tags/1.0.0: /svg-tags/1.0.0:
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
dev: false
/svgo/2.8.0: /svgo/2.8.0:
resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==}

View File

@ -76,6 +76,15 @@ describe('pages', () => {
await expectNoClientErrors('/') await expectNoClientErrors('/')
}) })
// TODO: support jsx with webpack
it.runIf(!isWebpack)('supports jsx', async () => {
const html = await $fetch('/jsx')
// should import JSX/TSX components with custom elements
expect(html).toContain('TSX component')
expect(html).toContain('<custom-component>custom</custom-component>')
})
it('respects aliases in page metadata', async () => { it('respects aliases in page metadata', async () => {
const html = await $fetch('/some-alias') const html = await $fetch('/some-alias')
expect(html).toContain('Hello Nuxt 3!') expect(html).toContain('Hello Nuxt 3!')

View File

@ -0,0 +1,8 @@
export default defineComponent({
render () {
return <div>
TSX component
<custom-component>custom</custom-component>
</div>
}
})

View File

@ -148,6 +148,13 @@ export default defineNuxtConfig({
}) })
} }
}, },
vue: {
compilerOptions: {
isCustomElement: (tag) => {
return tag === 'custom-component'
}
}
},
experimental: { experimental: {
emitRouteChunkError: 'reload', emitRouteChunkError: 'reload',
inlineSSRStyles: id => !!id && !id.includes('assets.vue'), inlineSSRStyles: id => !!id && !id.includes('assets.vue'),

5
test/fixtures/basic/pages/jsx.vue vendored Normal file
View File

@ -0,0 +1,5 @@
<template>
<div>
<Tsx />
</div>
</template>