JSX h
function in ESM build?
#9231
Closed
stevefan1999-personal
started this conversation in
General Discussions
Replies: 1 comment 1 reply
-
Can you provide a minimum reproduction such as a playground or git repository? output.mp4<script setup lang="ts">
import * as babelcore from "@babel/standalone";
import vuebabelPluginJsx from "@vue/babel-plugin-jsx";
import { onMounted } from "vue";
import * as Vue from 'Full-Vue'
onMounted(() => {
let CustomComponent = null;
let globalApp = null;
const btnStartRender = document.querySelector('#btnStartRender')
const jsx = document.querySelector("#jsx") as HTMLInputElement
const out = `export default {
setup() {
const msg = ref('')
watch(msg, (val) => {
console.log(val)
})
return () => (
<div>
<h2>{ msg.value }</h2>
<input value={ msg.value } onInput={ (e) => msg.value = e.target.value } />
</div>
);
},
};
`;
jsx.value = out;
btnStartRender.addEventListener("click", () => {
compileAndGetUrl(jsx.value, (module, blobURL) => {
console.log(module.default);
CustomComponent = module.default;
URL.revokeObjectURL(blobURL);
globalApp._instance.exposed.refresh();
});
});
function compileAndGetUrl(codes, callback) {
const plugins = vuebabelPluginJsx;
let { code } = babelcore.transform(codes, {
// presets: ['react']
plugins: [plugins],
});
code = code.replace(
'from "vue"',
'from "https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.esm-browser.js"\n import { BaseTransition, BaseTransitionPropsValidators, Comment, EffectScope, Fragment, KeepAlive, ReactiveEffect, Static, Suspense, Teleport, Text, Transition, TransitionGroup, VueElement, assertNumber, callWithAsyncErrorHandling, callWithErrorHandling, camelize, capitalize, cloneVNode, compatUtils, compile, computed, createApp, createBlock, createCommentVNode, createElementBlock, createElementVNode, createHydrationRenderer, createPropsRestProxy, createRenderer, createSSRApp, createSlots, createStaticVNode, createTextVNode, createVNode, customRef, defineAsyncComponent, defineComponent, defineCustomElement, defineEmits, defineExpose, defineModel, defineOptions, defineProps, defineSSRCustomElement, defineSlots, devtools, effect, effectScope, getCurrentInstance, getCurrentScope, getTransitionRawChildren, guardReactiveProps, h, handleError, hasInjectionContext, hydrate, initCustomFormatter, initDirectivesForSSR, inject, isMemoSame, isProxy, isReactive, isReadonly, isRef, isRuntimeOnly, isShallow, isVNode, markRaw, mergeDefaults, mergeModels, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onActivated, onBeforeMount, onBeforeUnmount, onBeforeUpdate, onDeactivated, onErrorCaptured, onMounted, onRenderTracked, onRenderTriggered, onScopeDispose, onServerPrefetch, onUnmounted, onUpdated, openBlock, popScopeId, provide, proxyRefs, pushScopeId, queuePostFlushCb, reactive, readonly, ref, registerRuntimeCompiler, render, renderList, renderSlot, resolveComponent, resolveDirective, resolveDynamicComponent, resolveFilter, resolveTransitionHooks, setBlockTracking, setDevtoolsHook, setTransitionHooks, shallowReactive, shallowReadonly, shallowRef, ssrContextKey, ssrUtils, stop, toDisplayString, toHandlerKey, toHandlers, toRaw, toRef, toRefs, toValue, transformVNodeArgs, triggerRef, unref, useAttrs, useCssModule, useCssVars, useModel, useSSRContext, useSlots, useTransitionState, vModelCheckbox, vModelDynamic, vModelRadio, vModelSelect, vModelText, vShow, version, warn, watch, watchEffect, watchPostEffect, watchSyncEffect, withAsyncContext, withCtx, withDefaults, withDirectives, withKeys, withMemo, withModifiers, withScopeId } from "https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.esm-browser.js"'
);
const blob = new Blob([code], { type: "text/javascript" });
const blobURL = URL.createObjectURL(blob);
import(blobURL).then((module) => {
callback(module, blobURL)
});
}
function mountApp() {
compileAndGetUrl(`export default {
setup(__props, { expose: __expose }) {
const show = ref(true)
__expose({
refresh() {
show.value = false
nextTick(() => {
show.value = true
})
}
})
return () => (<>
{ show.value ? <CustomComponent /> : null }
</>
);
},
};`, (_module, _blobURL) => {
// console.log(_module.default);
const app = Vue.createApp(_module.default);
globalApp = app;
app.component("CustomComponent", () => Vue.h(CustomComponent));
app.mount("#myApp");
URL.revokeObjectURL(_blobURL);
})
}
compileAndGetUrl(jsx.value, (module, blobURL) => {
console.log(module.default);
CustomComponent = module.default;
URL.revokeObjectURL(blobURL);
mountApp()
});
})
</script>
<template>
<div style="width: 100%; padding: 8px;">
<textarea style="
width: 100%;
height: 50vh;
border: 0;
outline: 1px solid #888;
" id="jsx"></textarea>
</div>
<button style="margin-left: 8px; font-size: 20px; margin-bottom: 8px;" id="btnStartRender">Render JSX</button>
<div style="margin-left: 8px" id="app"></div>
<div style="border: 1px gray solid;padding: 8px;margin: 8PX;">
<div id="myApp" style="margin-left: 8px"></div>
<div style="margin-top: 50px;margin-left: 8px;">JSX Render Part</div>
</div>
</template>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
</style> |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I'm writing a runtime that can import Vue and transform JSX to corresponding source code on the fly.
I know most people out here would likely suggest going for the Babel React transform to precompile, but I'm directly against that since I'm directly embedding SWC into my program, there is no need to precompile JSX and I want it to happen in runtime (so like Parcel but for CLI program).
However, I was not able to import it due to the Vue package in esm.sh being the runtime one. This will help both my custom runtime (development ongoing recently) and Deno, which also suffer from the same problem.
I'm not sure if Vue just straight up accept the JSX transformed by the default SWC handler to JS object:
Beta Was this translation helpful? Give feedback.
All reactions