Open phobetron opened 2 years ago
Here's the compiled JS:
import { defineComponent } from "vue-demi";
import { openBlock, createElementBlock } from "vue";
var _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _sfc_main = defineComponent({
methods: {
action() {
console.log("Button Clicked");
}
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("button", {
onClick: _cache[0] || (_cache[0] = (...args) => _ctx.action && _ctx.action(...args))
}, "Click");
}
var HelloWorld = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export { HelloWorld };
But I'm not sure this has any bearing on anything. It seems to be more of a Vite and/or Yarn workspace dependency issue.
I think it more likely that vue-template-compiler
is grabing the v3 of vue
due to the yarn workspace hoisting. Maybe you can try adding this to your package.json
"installConfig": {
"hoistingLimits": "workspaces"
}
@antfu For some reason, that had no effect, but placing nmHoistingLimits: workspaces
in .yarnrc.yml
worked. After also adding a missing dependency, the Vue2 app builds and loads in the browser. However, the dependency from line 2 in the compiled JS causes an error, as it is still Vue3-specific.
The new error in the browser is:
Uncaught SyntaxError: The requested module '/node_modules/.vite/vue.js?v=c2bff7da' does not provide an export named 'createElementBlock'
Here's the new JS after adding the hoisting limits:
import { defineComponent } from "/node_modules/.vite/vue-demi.js?v=c2bff7da";
import { openBlock, createElementBlock } from "/node_modules/.vite/vue.js?v=c2bff7da";
var _export_sfc = (sfc, props) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props) {
target[key] = val;
}
return target;
};
const _sfc_main = defineComponent({
methods: {
action() {
console.log("Button Clicked");
}
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createElementBlock("button", {
onClick: _cache[0] || (_cache[0] = (...args) => _ctx.action && _ctx.action(...args))
}, "Click");
}
var HelloWorld = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export { HelloWorld };
I think these are referenced in the Vue SFC compiler. Is there any way to get vue-demi
to pick these up during the compilation process, or is it not possible to use SFCs in a vue-demi
project?
I've updated the PoC repo, if you would like to poke at it.
I just found one project, vue3-sketch-ruler, uses a build process that creates separate libraries for 2 & 3, combined into a single package with a postinstall
process that determines which library should be used.
My best current working solution is in the PoC repo. It has the following:
vue-demi
My only other thought to simplify this process is to have one library package that uses multiple build files, but that would require additional tooling like yarn-plugin-conditions (which currently does to seem to work with Vue3) to switch dependencies in the package manager itself.
I've been having a difficult time working out how to build a universal component library with SFCs that can be used by both Vue2 and Vue3 apps bundled together in a Yarn 3 workspaces monorepo.
I have created a (failing) proof of concept project. The library builds, and the Vue3 app renders it correctly. However, the Vue 2 app will not build, and gives the following error:
I've attempted various arrangements of
vue-demi-switch
calls, but this exact error occurs regardless, so I've left that out of the PoC.The library, as well as both Vue apps, are built using Vite. Is there an incompatibility with
vue-demi
SFCs and Yarn workspaces, or maybe in how Vite loads Vue?