Typescript:如何从源代码导入而不是文件

时间:2018-11-02 11:11:20

标签: angular typescript

我使用以下代码段:

  loadComponent(name) {
    var url = this.configurationService.configuration.api_url+"/generator/dynamic-loading/component/"+name;
    this.http.get(url, {responseType: 'text'}).subscribe(componentCode => {
      let result = ts.transpile(componentCode);
      console.log("### Component",result);
    });
  }

,我想从“ <结果>结果导入名称

怎么可能?

1 个答案:

答案 0 :(得分:1)

如果我正确理解,result是模块的JavaScript源代码(我将其称为“动态模块”),并且您想加载此模块并访问其导出。假设动态模块可以导入的模块列表很小,那么将动态模块转换为CommonJS格式并编写一个迷你模块加载器(将正确的上下文设置为eval JavaScript源代码。

function evalCommonjsModule(moduleSource: string, requireMap: Map<string, {}>) {
    let moduleFunc = eval("(module, exports, require) => {" + moduleSource + "}");
    let module = {exports: {}};
    moduleFunc(module, module.exports, (requireName) => {
        let requireModule = requireMap.get(requireName);
        if (requireModule === undefined)
            throw new Error(`Attempted to require(${requireName}), which was not in requireMap`);
        return requireModule;
    });
    return module.exports;
}


import * as AllowedImport1 from "allowed-import-1";
import * as AllowedImport2 from "allowed-import-2";

// In loadComponent:

// Example from https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#a-simple-transform-function
let result = ts.transpileModule(componentCode, {
  compilerOptions: { module: ts.ModuleKind.CommonJS }
});
let resultModule = evalCommonjsModule(result, new Map([
    ["allowed-import-1", AllowedImport1],
    ["allowed-import-2", AllowedImport2]
]));
let name = resultModule.name;

如果动态模块的导入不限于预先已知的简短列表,则您的选择将取决于用于主项目的模块捆绑器或装载器。由于loadComponent已经是异步的,因此如果捆绑程序/加载程序支持动态导入,则可以将动态模块转换为AMD格式,并让小型加载程序在执行之前动态导入模块的所有依赖项加载它的身体。可能有现有的库可以帮助您解决此问题,但我对它们并不熟悉。其他人应该随时添加有关他们的信息。