0

I use this snippet :

  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);
    });
  }

and i wouldlike "import name from result"

How it is possible ?

3
  • is this what you want ? ` let {name:result}= ts.transpile(componentCode);` Commented Nov 2, 2018 at 11:18
  • i download ts code of a component and i want import component in my application after transpile code Commented Nov 2, 2018 at 11:21
  • Can you explain bit more Commented Nov 2, 2018 at 12:57

1 Answer 1

1

If I understand correctly, result is the JavaScript source code of a module (which I'll call the "dynamic module"), and you want to load this module and access its exports. Assuming that there is a fixed, small list of modules that the dynamic module is allowed to import, it's probably easiest to transpile the dynamic module to CommonJS format and write a mini module loader that sets up the proper context to eval the JavaScript source code.

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;

If the imports of the dynamic module are not restricted to a short list known in advance, then your options will depend on the module bundler or loader that you are using for the main project. Since loadComponent is asynchronous already, if your bundler/loader supports dynamic import, then you may be able to transpile the dynamic module to AMD format and have your mini-loader perform dynamic imports of all the dependencies of the dynamic module before loading its body. There may be existing libraries that can help with this, but I'm not familiar with them; others should feel free to add information about them.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.