簡體   English   中英

如何從運行時已知的文件加載 Typescript 模塊(在 angular2+electron 中)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM