-
-
Notifications
You must be signed in to change notification settings - Fork 760
[WIP] allow nicegui SFC script section to use ESM / import syntax #4673
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
base: main
Are you sure you want to change the base?
Conversation
…pendencies.py similarly to js component (+ handler in nicegui.py) by importing it as a module and then registering the component, with template property set to the elm id of the component
5e5ae7c
to
1dd3070
Compare
Hi @xaptronic, If I understand correctly, this adds support for newer import syntax, but doesn't add full Vue 3 support, right? Since you patched vbuild, would it make sense to create a PR over at https://github.com/manatlan/vbuild to get these changes merged upstream? There are related discussions in manatlan/vbuild#8 and manatlan/vbuild#11 |
I think more specifically what this does is allow ESM syntax in SFC. I would pose you the question "what do you mean by <full Vue 3 support>" ? For example, I saw in another discussion that ChatGPT says
I think that this is incorrect. Use of import is ESM related. What is Vue3 related is So I don't know for sure that this would enable you to build full blown Vue 3 applications, e.g.; with router and other features. I think that all it does over all is allow you to use more normal / expected JS syntax when building components. We could make the component object registered via
I could try opening a PR, maybe the approach is to add another component type (along side pscript and js components) - however, thinking through it a bit:
|
I added a demo of "Vue3 component approach". What I see is that Vue3 has a compiler macro that rewrites JS written in a <script setup>
const count = ref(0);
function increment() {
count.value++;
}
</script> ESM variation: export default {
setup () {
const count = ref(0);
function increment() {
count.value++;
}
return { count, increment };
} so - this approach would not be fully Vue3 compatible in the sense that it doesn't translate |
To be honest, I don't know. I got in touch with Vue when creating NiceGUI on the basis of JustPy and never used Vue outside of NiceGUI. So this repo is a pretty accurate representation of my Vue knowledge. I thought Vue 2/3 behaves similarly like Python 2/3, so I didn't expect a tool like "vbuild" to be easily adopted for Vue 3. But this might be wrong.
👍🏻
No, it is only use in one place.
As far as I can tell it supports scoped CSS. So if a Vue component defines I'd be very happy with moving vbuild over to NiceGUI, allowing for various improvements without depending on a pretty stale third-party repo. |
In doing some research, it sounds to me that what we refer to as "vue2" is actually components built based on "Options API", where as a Vue3 component might be based on the Composition API (and makes use of According to this and the references within, Options API is still relevant in Vue3 and isn't going anywhere: So my understanding is that we are already using Vue3 (we use a Vue3 UMD rollup) but just that components use Options API syntax. vbuild is effectively parsing the This doesn't preclude eventual support for Vue3 If you are good with moving vbuild in, and moving towards ESM capable Options API components, I will take a stab at a deep dive into the code there to see if there's option for perf improvement. I'd also like to explore more of composition API and if it can be used outside of Do you have any preferences around pscript? Noted for scoped styles - that functionality looks quite simple. |
Sounds good to me.
I think I never heard of it. If we get it for free, why not. But be aware that once we add a feature, we need to document, test, and maintain it and can hardly change or remove it without potentially breaking user code. If nobody needs it, maybe save it for later. 🙂 In any case, your work might be a good opportunity to update the section about custom Vue components to describe what exactly is supported and what is not: Vue 2, Vue 3, ESM imports, Composition API, Options API, scoped styles, maybe PScript etc. At least it would help me to get things straight in my head. 😄 |
Ah, this is going to be a brain teaser to understand... @xaptronic correct me if I am wrong, but the only change from your ![]() I am not sure how that one change in VBuild enables "Support Vue 3 for Single-File Components (SFC)", "Enable the use of Compositions API". Perhaps I can work backwards by running the PR's code and inspecting what's generated to the browser. |
OK so I have made sense of this now. @xaptronic See if what I write makes sense. TL-DR: This PR brings how we load Vue SFCs much more inline with how we load any other Vue component. With the full leverage of ES Module import, we can avoid cluttering up the index.html with the JavaScript. Benefits which occur from this PR occur on the basis of this modified load procedure (and is kinda accidental if you ask me) As we all know, the basics of web, HTML, CSS and JS. Let's evaluate, of the 2 elements (yes, 2, only plotly and joystick uses .vue in the entire NiceGUI codebase), where does the HTML, CSS, and JS go. HTMLStill inside the served index.html. Before: ![]() After: ![]() Look at only the first 2 lines. It's the same. CSSStill inside the served index.html Before: ![]() After: ![]() It's literally the same, again. JSWe move away from serving it in index.html, but rather separately. Before: ![]() After: ![]() ![]() Comparing Vue SFCs and Option API Vue components, we see: ![]() At this point, the only difference being:
Which is a good thing! We can deprecate |
Given that the tests (beside the code quality one) are actually passing https://github.com/xaptronic/nicegui/actions/runs/14734725239 Do we want to move this out of WIP and review this? I am also kind of lost as to what work is in progress: This seems pretty complete? |
Any updates? It would be great if you can leave a list of to-do items, or we can probably proceed with a review otherwise, since frontend code wise it's a small change. |
Summary of changes:
vbuild returns: html template, script and style sections
-- vbuild script is the full contents of the script section rather than 1) parsing out the content between
{
/}
; 2) does not returnVue.component("component_name", {template: "#id", <script>})
dependencies.py - when setting up template resources (
generate_resources
) we don't change handling of the html / css sections, but for script, add js_imports thatimport default as {vue_component.name} from "{url}";
{vue_component.name}.template = "#tpl-{vue_component.name}
app.component("{vue_component.name}", vue_component.name)
so all in all - parse the SFC, import the script part as ESM and set the template property to the corresponding ID.
OnOff
vue component demoimport
syntax to pull in an ESM from a CDN to make a fireworks component (just for fun lol).You can also do
const { ref } = Vue
to access various vue3 functions / utilities which will get a reference to the global Vue object - one could also choose to use vue via ESM, but this would I think duplicate code for not really any reason.
I tried for little while to also make NiceGUI use Vue via ESM, but it does not appear that Quasar currently supports being run as ESM from a CDN (although there appear to be files there?) - but the UMD version does a bunch of automatic configuration that I didn't have time to untangle, so I stopped pursuing that for the moment.
Feature request: #1992