Dynamic Component gives TypeError: Cannot read property '__esModule' of undefined
Dynamic Component gives TypeError: Cannot read property '__esModule' of undefined
我大致尝试按照 this article 从我的 asp.net 核心 webapi
动态导入 vue 组件
MyComponent.vue
<template>
<h2>Hello from the Distribution Server!</h2>
</template>
我使用以下命令将其转换为 .umd.min.js:
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 在导入组件时似乎 运行 正常,但它没有出现在应用程序中,我可以在控制台中看到此错误:
Uncaught (in promise) TypeError: Cannot read property '__esModule' of undefined
at ensureCtor (vue.js:3595)
at vue.js:3668
at vue.js:351
我做错了什么?
umd.min.js 输出:
(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
主要vue组件
<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>
外部-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];
}
这里的问题在external-component.js
看来 name
变量应该匹配从服务器传来的实际文件的名称
这不能只匹配传递给 File(bytes, file, "name")
调用的名称字符串,而是文件系统中的实际文件名(不包括 .vue
扩展名)
正确设置该值后它工作正常
我大致尝试按照 this article 从我的 asp.net 核心 webapi
动态导入 vue 组件MyComponent.vue
<template>
<h2>Hello from the Distribution Server!</h2>
</template>
我使用以下命令将其转换为 .umd.min.js:
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 在导入组件时似乎 运行 正常,但它没有出现在应用程序中,我可以在控制台中看到此错误:
Uncaught (in promise) TypeError: Cannot read property '__esModule' of undefined
at ensureCtor (vue.js:3595)
at vue.js:3668
at vue.js:351
我做错了什么?
umd.min.js 输出:
(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
主要vue组件
<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>
外部-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];
}
这里的问题在external-component.js
看来 name
变量应该匹配从服务器传来的实际文件的名称
这不能只匹配传递给 File(bytes, file, "name")
调用的名称字符串,而是文件系统中的实际文件名(不包括 .vue
扩展名)
正确设置该值后它工作正常