I'm roughly trying to follow this article to import vue components dynamically from my asp.net core webapi
MyComponent.vue
<template>
<h2>Hello from the Distribution Server!</h2>
</template>
Which I converted to a .umd.min.js with this command:
npx vue-cli-service build --target lib --formats umd-min --no-clean --dest server/components/MyComponent --name "MyComponent.[chunkhash]" server/components/MyComponent/MyComponent.vue
Everythnig seems to run fine when imporing the component, but it doesn't appear in the app and i can see this error in the console:
Uncaught (in promise) TypeError: Cannot read property '__esModule' of undefined
at ensureCtor (vue.js:3595)
at vue.js:3668
at vue.js:351
What am I doing wrong?
umd.min.js output:
(function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t():"function"===typeof define&&define.amd?define([],t):"object"===typeof exports?exports["MyComponent.c9b7fae39bb9d71ad3e7"]=t():e["MyComponent.c9b7fae39bb9d71ad3e7"]=t()})("undefined"!==typeof self?self:this,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="fb15")}({f6fd:function(e,t){(function(e){var t="currentScript",n=e.getElementsByTagName("script");t in e||Object.defineProperty(e,t,{get:function(){try{throw new Error}catch(r){var e,t=(/.*at [^\(]*\((.*):.+:.+\)$/gi.exec(r.stack)||[!1])[1];for(e in n)if(n[e].src==t||"interactive"==n[e].readyState)return n[e];return null}}})})(document)},fb15:function(e,t,n){"use strict";var r;(n.r(t),"undefined"!==typeof window)&&(n("f6fd"),(r=window.document.currentScript)&&(r=r.src.match(/(.+\/)[^/]+\.js(\?.*)?$/))&&(n.p=r[1]));var o=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("h2",[e._v("Hello from the Distribution Server!")])},i=[];function f(e,t,n,r,o,i,f,u){var c,a="function"===typeof e?e.options:e;if(t&&(a.render=t,a.staticRenderFns=n,a._compiled=!0),r&&(a.functional=!0),i&&(a._scopeId="data-v-"+i),f?(c=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),o&&o.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(f)},a._ssrRegister=c):o&&(c=u?function(){o.call(this,(a.functional?this.parent:this).$root.$options.shadowRoot)}:o),c)if(a.functional){a._injectStyles=c;var s=a.render;a.render=function(e,t){return c.call(t),s(e,t)}}else{var d=a.beforeCreate;a.beforeCreate=d?[].concat(d,c):[c]}return{exports:e,options:a}}var u={},c=f(u,o,i,!1,null,null,null),a=c.exports;t["default"]=a}})["default"]}));
//# sourceMappingURL=https://localhost:44385/api/DistributedComponent/TestSourceMap
Main vue component
<script lang="ts">
import { Vue, Component, Mixins } from "vue-property-decorator";
import externalComponent from '../../js/util/external-component';
@Component({
name: "Dashboard",
components: {
MyComponent: async () => await externalComponent('https://localhost:44385/api/DistributedComponent/Test')
}
})
export default class Dashboard extends Vue {
constructor() {
super();
}
}
</script>
external-component.js
export default async function externalComponent(url) {
const name = 'MyComponent';
if (window[name]) return window[name];
window[name] = await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.async = true;
script.addEventListener('load', () => {
resolve(window[name]);
});
script.addEventListener('error', () => {
reject(new Error(`Error loading ${url}`));
});
script.src = url;
document.head.appendChild(script);
});
return window[name];
}
The problem here was in external-component.js
It seems that the name
variable should match the name of the actual file passed from the server
This can't just match the name string passed in to the File(bytes, file, "name")
call, but the actual file name in the file system (excluding the .vue
extension)
After setting that value properly it's working fine