Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support decorators in .vue file. #430

Closed
5 of 6 tasks
ruojianll opened this issue Jul 24, 2024 · 9 comments
Closed
5 of 6 tasks

Support decorators in .vue file. #430

ruojianll opened this issue Jul 24, 2024 · 9 comments

Comments

@ruojianll
Copy link

ruojianll commented Jul 24, 2024

Related plugins

Description

In newest npm create vue@latest project, we could use decorators after set "experimentalDecorators": true in standalone .ts files. But it couldn't be transformed in .vue files in <script lang="ts"></script>.

I advice to support decorators in .vue files directly or with "experimentalDecorators": true.

Suggested solution

Support decorators in .vue files.

Alternative

No response

Additional context

No response

Validations

@sxzz
Copy link
Member

sxzz commented Jul 24, 2024

Considering it as a bug. Please provide a minimal reproduction to continue the issue.
Thanks.

Why reproduction is required

@ruojianll
Copy link
Author

  1. npm create vue@latest
  2. cd your-project
  3. npm install
  4. Set "experimentalDecorators": true in tsconfig.app.json
  5. npm run dev
  6. Change src/HomeView.vue's script block.
<script setup lang="ts">
import TheWelcome from '../components/TheWelcome.vue'

function deco(){
  console.log('deco works')
}
@deco
class MyClass{}
</script>

There is an error in browser console Uncaught SyntaxError: Invalid or unexpected token.
It should show deco works.

@sxzz
Copy link
Member

sxzz commented Jul 24, 2024

It could be related to Vite dev server, since it works on build mode vite build.

@sxzz
Copy link
Member

sxzz commented Jul 24, 2024

This is because Vite's esbuild syntax transformation occurs before the Vue plugin, and esbuild does not recognize Vue SFC, so it is ignored.

@sxzz sxzz added bug Something isn't working and removed enhancement: pending triage labels Jul 24, 2024
@ruojianll
Copy link
Author

How about this going?

alamhubb added a commit to alamhubb/vite-plugin-vue that referenced this issue Sep 15, 2024
issues: vitejs#430

More thoughts:

So should we not hard-code loader:'ts' and target:'es2020;

      {
        target: 'esnext',
        // vitejs#430 Support decorators in .vue file. vitejs#430
        // target can be overridden by esbuild config target
        ...options.devServer?.config.esbuild,
        loader: 'ts',
        sourcemap: options.sourceMap,
      },

Just for fault tolerance and compatibility considerations

vite is the basic component of vite-plugin-vue. When vite-plugin-vue calls the transformWithEsbuild function provided by vite:esbuild in the vite project, should it be consistent with the parameters of vite:esbuild calling transformWithEsbuild, that is, esbuildTransformOptions, that is, options.devServer?.config.esbuild in the development environment

transformWithEsbuild(
    resolvedCode,
    filename,
    options.devServer?.config.esbuild || {},
    resolvedMap,
)

Because the running results of vite in the development environment and the production environment should be consistent, it is also necessary to keep it consistent with the parameters passed in when vite:esbuild calls the transformWithEsbuild function

This code will only be triggered in the development environment, so it is correct to use options.devServer?.config.esbuild
@alamhubb
Copy link
Contributor

When I used the decorator function of ts, I also encountered a problem

When I used the decorator in the dev environment of vite, an exception occurred, but it was normal in the build environment

So I checked the differences between the dev and build environments

I found that in the build environment, the target of esbuild can be replaced by esbuild:{target}, esbuildTransformOptions in vite.config.ts, while in the dev environment, it is hard-coded, target:esnext, and esbuildTransformOptions does not replace target:esnext

Logic executed when vite:esbuild builds

https://github.com/vitejs/vite/blob/main/packages/vite/src/node/plugins/esbuild.ts (238)

image

vite-plugin-vue Logic executed in dev environment

https://github.com/vitejs/vite-plugin-vue/blob/main/packages/plugin-vue/src/main.ts (253)

image

This leads to inconsistency between dev environment and build environment, which I find strange

vite is the basic component of vite-plugin-vue.

In the vite project, when vite-plugin-vue calls the transformWithEsbuild function provided by vite:esbuild, the parameters passed in should be consistent with the parameters of transformWithEsbuild called by vite:esbuild itself when building.

That is, esbuildTransformOptions should be used to replace and merge target:esnext

And this code will only be triggered in the development environment, so options.devServer?.config.esbuild can be used

This way, the results of dev environment and build environment can be consistent

So I submitted a PR #444

@alamhubb
Copy link
Contributor

alamhubb commented Sep 15, 2024

relate pr #222

@sxzz
Copy link
Member

sxzz commented Sep 16, 2024

Fixed via #444

@sxzz sxzz closed this as completed Sep 16, 2024
@sxzz
Copy link
Member

sxzz commented Sep 16, 2024

It will automatically read tsconfig.json and transform decorators. In the default vue template, Vite cannot find the correct tsconfig.json via App.vue.

Try copying the content from tsconfig.app.json to your main tsconfig.json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants