script-setup dismisses local component starting with lowercase in dev
Version
3.2.1
Reproduction link
Steps to reproduce
This can't be demonstrated in SFC playground because it only happens in dev-mode, not build-mode.
- In script-setup, import a local component starting with a lowercase, e.g.
styledLogin
. - Use
<styled-login>
in template. - Test the page in dev mode (not build)
For reference, here's the case I've used locally:
<template>
<styled-login value="test" />
</template>
<script setup lang="ts">
import { styledLogin } from "@/Components/Formatters/user";
</script>
What is expected?
Works
What is actually happening?
styled-login
is undefined
.
In dev this happens because it's been dropped and was not included in $setup
.
My local test case is compiled to this:
import { createHotContext as __vite__createHotContext } from "/@vite/client";import.meta.hot = __vite__createHotContext("/Modules/Dev/bug.vue");import { defineComponent as _defineComponent } from "/node_modules/.vite/vue.js?v=c5083fb6";
const _sfc_main = _defineComponent({
setup(__props, { expose }) {
expose();
// ----- NOTICE: styledLogin is not included in $setup
const __returned__ = {};
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
return __returned__;
}
});
import { openBlock as _openBlock, createBlock as _createBlock } from "/node_modules/.vite/vue.js?v=c5083fb6"
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
// ------ FAILS because $setup["styledLogin"] is undefined
return (_openBlock(), _createBlock($setup["styledLogin"], { value: "test" }))
}
import block0 from "/Modules/Dev/bug.vue?vue&type=route&index=0&lang.route"
if (typeof block0 === 'function') block0(_sfc_main)
_sfc_main.render = _sfc_render
_sfc_main.__file = "bug.vue"
_sfc_main.__hmrId = "f489aed8"
typeof __VUE_HMR_RUNTIME__ !== 'undefined' && __VUE_HMR_RUNTIME__.createRecord(_sfc_main.__hmrId, _sfc_main)
export const _rerender_only = true
import.meta.hot.accept(({ default: updated, _rerender_only }) => {
if (_rerender_only) {
__VUE_HMR_RUNTIME__.rerender(updated.__hmrId, updated.render)
} else {
__VUE_HMR_RUNTIME__.reload(updated.__hmrId, updated)
}
})
export default _sfc_main
This can be worked-around by Pascal-casing the imported component: StyledLogin
works.
Codegen for build is different and doesn't have the problem, here's what the SFC explorer generates:
/* Analyzed bindings: {
"styledLogin": "setup-const"
} */
import { openBlock as _openBlock, createBlock as _createBlock } from "vue"
import styledLogin from "./Comp.vue"
const __sfc__ = {
setup(__props) {
return (_ctx, _cache) => {
return (_openBlock(), _createBlock(styledLogin))
}
}
}
__sfc__.__file = "App.vue"
export default __sfc__