[英]How to load Typescript module from a file known at runtime (in angular2+electron)
我正在嘗試編寫一些概念證明,以了解“打字稿 + 電子中的 Angular2”是否會滿足未來桌面應用程序項目的要求。
但是我遇到了麻煩……我是想實現不可能的目標還是有辦法做到這一點? 這是我的上下文:
精簡版:
我怎樣才能讓這個運行:
@Injectable()
export class PluginManager {
getPluginComponentForEventType(eventtype: string): Type {
//return is angular "Type", later consumed by Dynamic Loader
var externalModule = require('../mtplugins/' + eventtype + 'plugin.ts');
return externalModule.TheRenderer;
}
}
沒有收到此錯誤:
"../mtplugins/foorendererplugin.ts not declared as a dependency"
帶上下文的長版本:
核心需求是一種我稱之為“動態前端插件系統”的系統。 這意味着:我的 UI 的一部分必須在運行時可替換 - 但我不知道將提前插入那里的組件。
示例場景:
我的應用程序收到一個“foo”事件:
leEvent: { eventtype: 'foo', payload: '...' }
所以它會告訴它的插件管理器:嘿,我需要一個 UI 組件來呈現一個 'foo' 事件。
插件管理器搜索包含組件的“fooplugin.ts”文件,從該文件動態加載組件類並返回類型。 如果它現在沒有 foo 插件,用戶可以從插件市場下載這個文件到插件文件夾,然后再試一次。
然后我的應用程序使用 DynamicComponentLoader.loadIntoLocation 將這個動態加載的類型集成到 dom 中,然后告訴組件渲染(leEvent)。
最后一部分在 angular 中動態加載組件沒問題,我的痛點是從文件加載類的插件管理器方法......到目前為止我得到的最好的東西是:
@Injectable()
export class PluginManager {
getPluginComponentForEventType(eventtype: string): Type {
//return is angular "Type", later consumed by Dynamic Loader
var externalModule = require('../mtplugins/' + eventtype + 'plugin.ts');
return externalModule.TheRenderer;
}
}
我使用“--module commonjs”運行我的 tsc。
當我調用該方法時,它告訴我“../mtplugins/foorendererplugin.ts 未聲明為依賴項”……好吧,我無法提前聲明依賴項,因為它僅在運行時才知道。
那么,有沒有辦法從僅在運行時已知的文件中加載 typescript 類? 在 Java 中,我想我會用一個類加載器來做,所以我覺得我需要打字稿的那個東西。 我實際上認為我已經閱讀了帶有 commonjs 和 require() 的打字稿會支持這一點,所以也許這種機制和 angular 的 system.js 集成正在相互咬合?
我是 angular2 和 typescript 以及電子和節點的新手,所以如果我忽略了一些基本的東西,請原諒。
編輯
正如 Louy 所指出的,錯誤信息並不是打字稿特有的。 它是由 System.js 拋出的...
再次證明,多花一點時間學習您想要使用的技術總是一項不錯的投資。 事實上,我在這里犯了一個新手錯誤:混合不同的模塊加載系統。 我以為我必須使用 CommonJS 才能在運行時加載外部模塊,但 System.js 也很好地支持運行時加載 - 這意味着:
代替
require(..)
我只是不得不使用
declare var System: any; //System.js Loader
...
System.import('./app/' + eventtype+ 'plugin.js');
然后你所要做的就是讓插件獨立於應用程序核心的實際代碼(因為這會導致模塊混亂......無論哪種方式都是一種架構氣味),而只依賴於接口(Typescript ftw!)。
這就是您的可插拔 angular2 UI 所需的全部內容:)
為什么不制作一個對象字典? 您不會以這種方式丟失類型。
// import all of them...
import pluginA from '../mtplugins/Aplugin.ts'
// add all here
const plugins: {[name: string]: /*typeof plugin*/} = {
a: pluginA,
// ...
}
// and then...
var externalModule = plugins[eventtype];
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.