Subscribe on changes!

local directives imports in TS script-setup with a leading uppercase `V` are dropped in dev mode

avatar
Jul 30th 2021

Version

3.2.0-beta.7

Reproduction link

https://sfc.vuejs.org/#eyJBcHAudnVlIjoiPHRlbXBsYXRlPlxuXHQ8ZGl2IHYtZGlyPjwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdCBzZXR1cD5cbiAgaW1wb3J0IFZEaXIgZnJvbSBcIi4vRGlyLmpzXCJcbjwvc2NyaXB0PiIsIkRpci5qcyI6ImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICgpIHt9In0=

Steps to reproduce

Notice the repro in sfc.vuejs.org works because it compiles like build-mode with a lambda that captures local values. The bug happens in dev-mode where a more "classic" codegen is used. It'd be nice if sfc.vuejs.org had an option to choose the codegen mode, that'll help demonstrate bugs in dev-only (or explore the dev codegen).

What is expected?

Local directives work in dev-mode.

What is actually happening?

They don't work because they're not inside $setup object anymore.

When I look at the generated code, I can see that:

  • my import vDir from "./dir" is gone.
  • vDir is not in the setup __returned__ object.
  • but the template _withDirectives still refers to it as $setup["vDir"]

At runtime, since $setup["vDir"] does not exist, the application fails to load. There's a crash inside withDirectives, on the line where it does if (dir.deep) because dir is undefined.


I have not debugged Vue, but I strongly suspect this change caused the regression: https://github.com/vuejs/vue-next/commit/5a3ccfd9143700c7ca82d2911fe592d0658c5393 Probably directives are not taken into consideration when checking what locals are used in template.

Possibly related? https://github.com/johnsoncodehk/volar/issues/327

avatar
Jul 30th 2021

Kind of confirming my suspicion of 5a3ccfd being the cause: it last worked in beta.4 and is broken since beta.5 (where that changed was introduced). Doesn't work up to latest beta.7.

avatar
Jul 30th 2021

Couldn't reproduce on an epmty vite project. Please open a new issue with an actual reproduction.

avatar
Jul 30th 2021

@posva Please don't make me fill everything again... you could have kept the issue open just a day and given me a chance to append the repro here.

I tried a minimal JS repro (basically on npm init vite and it worked. Then I added lang="ts" on the script tag and it broke. That's the missing bit.

avatar
Jul 30th 2021

Well, I tried variations and it is a bit fiddly.

It reproduces with lang=ts but the only case that seems not to work is an import with a capital V, like so: import VDir from "./dir". If you try a small v it works. It you try a local function named VDir it works as well.

Here's a repro: https://github.com/jods4/bug-vue-directive

avatar
Jul 30th 2021

Please don't make me fill everything again... you could have kept the issue open just a day and given me a chance to append the repro here.

Then don't open an issue without a repro. Pinging me with a repro is fine, I still take a look 😉 . Using vDir is a workaround

avatar
Jul 30th 2021

Then don't open an issue without a repro.

It looks like every time I think there couldn't be "more" to the issue, every time I'm wrong and it's dependent on weird conditions I couldn't even imagine 😓

BTW I wanted to create a repro in the SFC explorer first (link in issue), but as I mentioned you can't choose if the generated code is dev- or build-mode. It would be neat to add this option in UI, that will help to provide repro with less work.

Using vDir is a workaround

Yup, first I reverted to beta.4, but after trying hard to build the repro I found out you can work around it!

avatar
Jul 30th 2021

It looks like every time I think there couldn't be "more" to the issue, every time I'm wrong and it's dependent on weird conditions I couldn't even imagine 😓

I've been there too, it's sometimes frustrating 😅

BTW I wanted to create a repro in the SFC explorer first (link in issue), but as I mentioned you can't choose if the generated code is dev- or build-mode. It would be neat to add this option in UI, that will help to provide repro with less work.

Absolutely, it could come in handy!