Importing from source code instead of a file in TypeScript: How to do it

I found this code snippet to help with dynamic component loading:

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

I am trying to figure out how to import "name" from the resulting transpiled code. Can anyone guide me on how to achieve this?

Answer №1

It seems like the variable result contains the JavaScript source code of a module, referred to as the "dynamic module," and you aim to load this module to access its exports. Assuming there is a predefined set of modules that the dynamic module can import, the easiest approach would be to transpile the dynamic module into CommonJS format and create a small module loader to properly configure the context for evaluating the JavaScript code using eval.

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 dynamic module's imports are not limited to a predefined list, your options will rely on the main project's module bundler or loader capabilities. If your bundler/loader supports dynamic imports and since loadComponent is already asynchronous, consider transpiling the dynamic module into AMD format and have your mini-loader handle dynamic imports of all dependencies before loading its content. There might be existing libraries that can assist with this process, but I'm not well-versed in them; others are encouraged to share relevant information.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error in TypeScript: The property "component" is not found on the React MUI MenuItem

I am currently working with the react mui MenuItem component and I am trying to turn a menu item into a link. Here is how I have attempted to achieve this: <MenuItem component={<Link href={`/backend/api/exam/${row.id}/result`} />} className={c ...

Is it possible to maintain the Spring default login page while turning off CSRF protection?

I have been working on a Spring+Angular site and the default login page was functioning well for me initially. The issue arose when I needed to turn off CRLF validation to be able to make POST requests from my Angular application, so I disabled it. Unfor ...

The FullCalendar does not appear as expected on Angular version 16

https://i.stack.imgur.com/DTAKr.pngI followed the steps to install FullCalendar in my Ionic 6 Angular 16 app as outlined on https://fullcalendar.io/docs/angular. However, nothing is showing up in the browser (chrome). The Inspector tool shows that the Ful ...

What is the best method to retrieve the nested value in this JavaScript/HTML code?

Can anyone help me extract the value "Yes, I am a Speaker" from this code using Javascript DOM element with getElementById? The challenge is that the value is nested inside a list element without any specific attributes. Each block of code has a unique l ...

Choosing the default drop-down option in Angular based on a falsy value

Within this template, the "Select Military Status" choice will be selected if the underlying model.militaryStatus property is null. <select [(ngModel)]="model.militaryStatus"> <option [ngValue]="null">Select Military Status</option> ...

Exploring nullish coalescing with undefined values

My function is set up to make API calls: interface getEventsPropsShape { eventId?: string; accountId?: string; eventsStartAfter?: string; } const getEvents = async ({ eventId, accountId, eventsStartAfter, }: getEventsPropsSha ...

How can I iterate over a specific range in Angular (version 12 and higher) instead of looping through the entire array?

I need help with working with an array called bars stored in a foo property. In my HTML template, I am able to loop through the array like this: <div *ngFor="let bar of foo.bars"> <!-- do something with bar --> </div> Howeve ...

The Angular-Chart.js chart fails to display when data is automatically inserted

I came across this sample code at https://stackblitz.com/edit/angular-chartjs-multiple-charts and tried using it. Everything was working well with static data, but when I attempted to push data retrieved from the Firebase Realtime Database into the chart, ...

Unable to associate ngModel because it is not recognized as a valid property of the "Component"

Currently, I am in the process of creating a custom form component using Angular 4. I have included all necessary components for ngModel to function properly, but unfortunately, it is not working as expected. Below is an example of my child component: ex ...

Encountered "Function undefined error when invoking within a map in TypeScript"

In my function, there is a map that looks like this: mainFunc(){ // other logics data.map(function (item) { item.number = Math.round(item.number); item.total = item.last - item.first; item.quantity= item?.quantity ? quantityRange(ite ...

The type 'string' cannot be assigned to the type 'T[keyof T]' within this context

I have a function that processes an array of Episodes and assigns data from an external file to the corresponding Episode based on a specified keyName: const assignDataFromExternalFile = (arrayToProcess: Episode[], filePath: string, keyName: keyof Episode) ...

What steps should I take to plan a collaborative code-sharing project?

As I develop various applications utilizing a core framework of my own creation, I am looking for a way to easily manage updates across all these applications. I have structured the code by creating a GitHub project where the main branch consists of the co ...

The Angular2 application was constructed using angular-cli, incorporating a directive, and optimized with the ng build

I am working on an angular-cli app and my environment details are: npm -v 3.10.8 node -v v6.9.1 angular2 ^2.4.0 angular/cli 1.0.0-beta.32.3 Recently, I added the following line to my package.json: "angular2-auto-scroll": "1.0.12" You can find more info ...

refresh the React component without having to refresh the entire webpage

Hey there, I have a component with a function called "handleAvatarUpload". Currently, when there is a change, the entire page reloads instead of just the component. Is there a way to reload only the component without refreshing the whole page? import { us ...

Errors related to Angular are now being displayed in VS Code following an update, although the build process itself

After updating Angular, I've noticed that VS Code is showing errors in my HTML files even though there are no actual errors present. Interestingly, ng build and ng serve are both working without any issues. Below are some screenshots for reference. Ca ...

Using the className prop in React with TypeScript

How can the className prop be properly typed and utilized in a custom component? In the past, it was possible to do the following: class MyComponent extends React.Component<MyProps, {}> { ... } and then include the component using: <MyCompone ...

Issue with Angular2 formBuilder: two validators are not functioning as expected

Need help with a text input that is required and must be longer than 3 characters. When clicking on the input, if a user types something shorter than 3 characters and then clicks out, a red border should be added. Otherwise, the border should be green. ...

Issue with Angular 9 Json pipe not showing decimal values

My JSON data looks like this: this.data = {"eoiStatistics": [ { "dateRange": { "explicitStartDate": "1997-01-01T00:00:00", "explicitEndDate": "2019-07-01T00:00:00" }, "outstandingApplicationCount": 0.0, "pendingApplicationCount": 24.0, " ...

Tips for Disabling ML5 Posenet

Looking to halt Posenet after completing app task private sketch(p: any) { p.setup = () => { this.poseNet = ml5.poseNet(p.createCapture(p.VIDEO), { outputStride: 8 }); this.poseNet.on(&apos ...

Utilize the term "export const" twice when declaring variables to assign value

const foobar = { foo: 'hello', bar: this.foo }; The code isn't working as expected, returning "undefined". Any suggestions on how to properly access it? ...