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

export static functions in compile to component #125

Open
rien-vroom-cquential opened this issue May 27, 2024 · 2 comments
Open

export static functions in compile to component #125

rien-vroom-cquential opened this issue May 27, 2024 · 2 comments

Comments

@rien-vroom-cquential
Copy link

rien-vroom-cquential commented May 27, 2024

In the old vue class components we could define a public static function which would be callable from other components/locations.
This original functionality is defined here i believe: https://github.com/vuejs/vue-class-component/blob/master/src/component.ts#L119

Anyhow i think public static functions should be added to the exported class/object in https://github.com/facing-dev/vue-facing-decorator/blob/master/src/component.ts#L74
However i'm not capable enough to make a sane solution for this (e.g. im not sure how to handle inheritance and other side effects).

Normally you can use a seperate ts class or something. But we want to use this for a lib and its really helpfull to have these kind of functions included in the component instead of a "random" other ts file/object/class

Minimal reproducable code:

### App.vue
<script lang="ts">
import { Component, Vue } from 'vue-facing-decorator'
import HelloWorld from './components/HelloWorld.vue'

@Component({
    components: {HelloWorld}
})
export default class App extends Vue {
    public get failingMsg(): string {
        return HelloWorld.staticFunctionCall('test');
    }
}
</script>
<template>
  <main>
    <HelloWorld :msg="failingMsg" />
  </main>
</template>

### HelloWorld.vue
<script lang="ts">
import { Component, Vue, Prop } from 'vue-facing-decorator'

@Component
export default class HelloWorld extends Vue {
    @Prop() public msg!: string;

    public static staticFunctionCall(changeA: string): string {
        // Do something
        return changeA;
    }
}
</script>
<template>
    {{ msg }}
</template>

Error received in the browser:

App.vue:9 Uncaught TypeError: HelloWorld.staticFunctionCall is not a function
    at get refMsg (App.vue:9:27)
    at ReactiveEffect.fn (chunk-U6BEPC57.js?v=e33feee7:1236:13)
    at ReactiveEffect.run (chunk-U6BEPC57.js?v=e33feee7:435:19)
    at get value (chunk-U6BEPC57.js?v=e33feee7:1248:107)
    at Object.get [as refMsg] (chunk-U6BEPC57.js?v=e33feee7:4970:22)
    at Object.get (chunk-U6BEPC57.js?v=e33feee7:4530:19)
    at Proxy._sfc_render (App.vue:21:25)
    at renderComponentRoot (chunk-U6BEPC57.js?v=e33feee7:2350:17)
    at ReactiveEffect.componentUpdateFn [as fn] (chunk-U6BEPC57.js?v=e33feee7:7466:46)
    at ReactiveEffect.run (chunk-U6BEPC57.js?v=e33feee7:435:19)

The code above is perfectly valid by (vue-)tsc and eslint, but fails in the browser.

@ruojianll
Copy link
Contributor

ruojianll commented Jun 15, 2024

### HelloWorld.vue
<script lang="ts">
import { Component, Vue, Prop } from 'vue-facing-decorator'

@Component
export default class HelloWorld extends Vue {
    @Prop() public msg!: string;
}

export function staticFunctionCall(changeA: string): string {
    // Do something
    return changeA;
}
</script>
<template>
    {{ msg }}
</template>

Try export static functions as module values.

@rien-vroom-cquential
Copy link
Author

@ruojianll that does work for this case.
It is somewhat impractical when building a lib with many components.

For example:

We export all the components in one go (aka all the default exports) so we can use the following:

import {MyComponent1, MyComponent2} from '@mycompany/ui-library';

They would both have a staticFunctionCall that does something slightly different. E.g. sorting data a certain way.
Since we are importing from the combined export function from the ui-library we can't really have this functionality.

We are following the example given by vite: https://vitejs.dev/guide/build#library-mode so we export all components from the entrypoint in the lib. So basically we have to use (if we follow the example in the initial post) in the lib:

import {HelloWorld, staticFunctionCall as HelloWorldStaticFunctionCall } from './HelloWorld.vue';

export {HelloWorld, HelloWorldStaticFunctionCall}

And this is the exact example we try to avoid, since the function itself is really tied to the HelloWorld class, why should we need to export something extra for this?

This suggestion might fix the TS errors, but is such a shift in the way the ui-library will work, its something we really would like to avoid.

Anyhow I'm still of the opinion that a static function should be exported/accesible from the outside, as that is what TS is also exporting.

SIdenote: thanks for the amazing work you've done here!

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

2 participants