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

Inconsistent behaviour for @click handler: works in dev, production build produces TypeError: class constructors must be invoked with 'new' #97

Closed
7 tasks done
morfav opened this issue Jan 31, 2023 · 4 comments
Labels
bug: upstream Bug in a dependency of this repository Inconsistency Inconsistency between dev & build p3-minor-bug 🔨 An edge case that only affects very specific usage (priority)

Comments

@morfav
Copy link

morfav commented Jan 31, 2023

Describe the bug

This is perhaps a misuse of the @click handler, however the inconsistency in behaviour between dev and build mode was quite confusing.

I did something like this in the click handler (this is in App.vue in my reproduction example):

<script setup lang="ts">

import Message from "./Message";


function showMessage(msg: Message) {
  console.log(msg.message);
}
</script>

<template>
  <button @click="showMessage(new Message('hello'))">Click me</button>
</template>

Message.ts looks like this:

export default class Message {
    message: string

    constructor(message: string) {
        this.message = message;
    }
}

When running npm run dev the code logs the 'hello' message in the console.

However if a build is made (npm run build then npm run preview) clicking on the button produces an error:
TypeError: class constructors must be invoked with 'new'

Reproduction

https://github.com/morfav/vitejs-demo

Steps to reproduce

No response

System Info

System:
    OS: macOS 13.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 73.09 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 19.5.0 - /opt/homebrew/bin/node
    npm: 9.3.1 - /opt/homebrew/bin/npm
  Browsers:
    Chrome: 109.0.5414.119
    Firefox: 109.0
    Safari: 16.2
  npmPackages:
    @vitejs/plugin-vue: ^4.0.0 => 4.0.0 
    vite: ^4.0.0 => 4.0.4

Used Package Manager

npm

Logs

vite build --debug

vue-project@0.0.0 type-check
vue-tsc --noEmit

vite:config bundled config file loaded in 69.27ms +0ms
vite:esbuild init tsconfck (root: /Users/Vlad/Downloads/vue-project) +0ms
vite:esbuild init tsconfck (root: /Users/Vlad/Downloads/vue-project) +1ms
vite:esbuild init tsconfck (root: /Users/Vlad/Downloads/vue-project) +0ms
vite:esbuild init tsconfck (root: /Users/Vlad/Downloads/vue-project) +0ms
vite:esbuild init tsconfck end +1ms
vite:esbuild init tsconfck end +0ms
vite:esbuild init tsconfck end +0ms
vite:esbuild init tsconfck end +0ms
vite:config using resolved config: {
vite:config plugins: [
vite:config 'vite:build-metadata',
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vite:vue',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:build-html',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:force-systemjs-wrap-complete',
vite:config 'vite:watch-package-data',
vite:config 'commonjs',
vite:config 'vite:data-uri',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vite:build-import-analysis',
vite:config 'vite:esbuild-transpile',
vite:config 'vite:terser',
vite:config 'vite:reporter',
vite:config 'vite:load-fallback'
vite:config ],
vite:config resolve: {
vite:config mainFields: [ 'module', 'jsnext:main', 'jsnext' ],
vite:config browserField: true,
vite:config conditions: [],
vite:config extensions: [
vite:config '.mjs', '.js',
vite:config '.mts', '.ts',
vite:config '.jsx', '.tsx',
vite:config '.json'
vite:config ],
vite:config dedupe: [ 'vue' ],
vite:config preserveSymlinks: false,
vite:config alias: [ [Object], [Object], [Object] ]
vite:config },
vite:config optimizeDeps: {
vite:config disabled: 'build',
vite:config force: undefined,
vite:config esbuildOptions: { preserveSymlinks: false }
vite:config },
vite:config build: {
vite:config target: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ],
vite:config cssTarget: [ 'es2020', 'edge88', 'firefox78', 'chrome87', 'safari14' ],
vite:config outDir: 'dist',
vite:config assetsDir: 'assets',
vite:config assetsInlineLimit: 4096,
vite:config cssCodeSplit: true,
vite:config sourcemap: false,
vite:config rollupOptions: {},
vite:config minify: 'esbuild',
vite:config terserOptions: {},
vite:config write: true,
vite:config emptyOutDir: null,
vite:config copyPublicDir: true,
vite:config manifest: false,
vite:config lib: false,
vite:config ssr: false,
vite:config ssrManifest: false,
vite:config reportCompressedSize: true,
vite:config chunkSizeWarningLimit: 500,
vite:config watch: null,
vite:config commonjsOptions: { include: [Array], extensions: [Array] },
vite:config dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] },
vite:config modulePreload: { polyfill: true }
vite:config },
vite:config define: { VUE_OPTIONS_API: true, VUE_PROD_DEVTOOLS: false },
vite:config ssr: {
vite:config format: 'esm',
vite:config target: 'node',
vite:config external: [],
vite:config optimizeDeps: { disabled: true, esbuildOptions: [Object] }
vite:config },
vite:config configFile: '/Users/Vlad/Downloads/vue-project/vite.config.ts',
vite:config configFileDependencies: [ '/Users/Vlad/Downloads/vue-project/vite.config.ts' ],
vite:config inlineConfig: {
vite:config root: undefined,
vite:config base: undefined,
vite:config mode: undefined,
vite:config configFile: undefined,
vite:config logLevel: undefined,
vite:config clearScreen: undefined,
vite:config optimizeDeps: { force: undefined },
vite:config build: {}
vite:config },
vite:config root: '/Users/Vlad/Downloads/vue-project',
vite:config base: '/',
vite:config rawBase: '/',
vite:config publicDir: '/Users/Vlad/Downloads/vue-project/public',
vite:config cacheDir: '/Users/Vlad/Downloads/vue-project/node_modules/.vite',
vite:config command: 'build',
vite:config mode: 'production',
vite:config isWorker: false,
vite:config mainConfig: null,
vite:config isProduction: true,
vite:config server: {
vite:config preTransformRequests: true,
vite:config middlewareMode: false,
vite:config fs: { strict: true, allow: [Array], deny: [Array] }
vite:config },
vite:config preview: {
vite:config port: undefined,
vite:config strictPort: undefined,
vite:config host: undefined,
vite:config https: undefined,
vite:config open: undefined,
vite:config proxy: undefined,
vite:config cors: undefined,
vite:config headers: undefined
vite:config },
vite:config env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true },
vite:config assetsInclude: [Function: assetsInclude],
vite:config logger: {
vite:config hasWarned: false,
vite:config info: [Function: info],
vite:config warn: [Function: warn],
vite:config warnOnce: [Function: warnOnce],
vite:config error: [Function: error],
vite:config clearScreen: [Function: clearScreen],
vite:config hasErrorLogged: [Function: hasErrorLogged]
vite:config },
vite:config packageCache: Map(0) { set: [Function (anonymous)] },
vite:config createResolver: [Function: createResolver],
vite:config worker: {
vite:config format: 'iife',
vite:config plugins: [
vite:config 'vite:build-metadata',
vite:config 'vite:pre-alias',
vite:config 'alias',
vite:config 'vite:modulepreload-polyfill',
vite:config 'vite:resolve',
vite:config 'vite:html-inline-proxy',
vite:config 'vite:css',
vite:config 'vite:esbuild',
vite:config 'vite:json',
vite:config 'vite:wasm-helper',
vite:config 'vite:worker',
vite:config 'vite:asset',
vite:config 'vite:wasm-fallback',
vite:config 'vite:define',
vite:config 'vite:css-post',
vite:config 'vite:build-html',
vite:config 'vite:worker-import-meta-url',
vite:config 'vite:asset-import-meta-url',
vite:config 'vite:force-systemjs-wrap-complete',
vite:config 'vite:watch-package-data',
vite:config 'commonjs',
vite:config 'vite:data-uri',
vite:config 'vite:dynamic-import-vars',
vite:config 'vite:import-glob',
vite:config 'vite:build-import-analysis',
vite:config 'vite:esbuild-transpile',
vite:config 'vite:terser',
vite:config 'vite:load-fallback'
vite:config ],
vite:config rollupOptions: {},
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config },
vite:config appType: 'spa',
vite:config experimental: { importGlobRestoreExtension: false, hmrPartialAccept: false },
vite:config getSortedPlugins: [Function: getSortedPlugins],
vite:config getSortedPluginHooks: [Function: getSortedPluginHooks]
vite:config } +5ms
vite v4.0.4 building for production...
transforming (10) node_modules/@vue/shared/dist/shared.esm-bundler.js vite:resolve 1.08ms ./base.css -> /Users/Vlad/Downloads/vue-project/src/assets/base.css +0ms
✓ 14 modules transformed.
dist/index.html 0.42 kB
dist/assets/index-9e356910.css 2.35 kB │ gzip: 0.88 kB
dist/assets/index-75f900e6.js 52.61 kB │ gzip: 21.26 kB

Validations

@sapphi-red sapphi-red transferred this issue from vitejs/vite Jan 31, 2023
@sapphi-red
Copy link
Member

This is a bug in vue as this can be reproduced with SFC Playground: reproduction.
Please report to vuejs/core.

@sapphi-red sapphi-red added bug: upstream Bug in a dependency of this repository p3-minor-bug 🔨 An edge case that only affects very specific usage (priority) Inconsistency Inconsistency between dev & build and removed pending triage labels Jan 31, 2023
@morfav
Copy link
Author

morfav commented Jan 31, 2023

Thank you, raised issue in vuejs/core

@cmanrique-surtec
Copy link

Workaround:

<script setup lang="ts">

import Message from "./Message";


function showMessage(msg: Message) {
  console.log(msg.message);
}
</script>

<template>
  <button @click="showMessage(Message.instance('hello'))">Click me</button>
</template>
export default class Message {
    message: string

    constructor(message: string) {
        this.message = message
    }

   static instance(message: string) {
      return new Message(message)
   }
}

@sapphi-red
Copy link
Member

Closing as this is a bug in Vue: vuejs/core#6483

@sapphi-red sapphi-red closed this as not planned Won't fix, can't repro, duplicate, stale Apr 22, 2023
@github-actions github-actions bot locked and limited conversation to collaborators May 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug: upstream Bug in a dependency of this repository Inconsistency Inconsistency between dev & build p3-minor-bug 🔨 An edge case that only affects very specific usage (priority)
Projects
None yet
Development

No branches or pull requests

3 participants