TypeScript powering the Bundler

A few versions back, TypeScript exposed the customTransformer API in its API.

I am interested in developing a transformer that can handle import statements (and maybe requires as well) in order to resolve bundle dependencies, similar to how webpack, browserify, or parcel operate.

Fortunately, TypeScript itself already utilizes a customTransformer API for a similar purpose:

transformAMDModule located at src/compiler/transformers/module/module.ts line 120

However, this code relies on internal fields/APIs and doesn't fully meet the requirements of my task.

Is it possible to accomplish this task using only public APIs, even if it's a simplified or partial version?


TO CLARIFY: I am referring to bundling the external dependencies of the application (such as react, moment, lodash) along with the application code into a single large JavaScript file. While TypeScript currently supports the --outFile argument, it only combines the application code and not the dependencies.

P.S. I have also posted the same question on Twitter/486timetable. Any helpful updates will be shared here for easier searchability.

Answer №1

No official solution has been provided, but I have embarked on my personal exploration on GitHub:

  1. You cannot solely rely on custom transformers to achieve it. Extensive work needs to be done before the emit/transform phase.
  2. The initial step involves gathering module dependencies. This is where findDependencies comes into play: by utilizing ts.Program and ts.TypeChecker, it identifies patterns in the AST. The goal is to capture:
    • import ... from "a-module" statements
    • synchronous require("a-module") calls
    • asynchronous import("a-module") calls
    • AMD define syntax
    • AMD require async calls (with a behavior different from global synchronous require)
    • potentially redirecting opted-in globals like React to import React from "react"
    • older TypeScript import statement formats
  3. Handle external dependencies -- bundling them recursively.
  4. Finally, trigger the emit process while managing or aliasing dependencies:
    • resolve locally for internal dependencies within the code
    • inject externally pre-bundled ones

While not without its complexities, this task is indeed achievable. It would be beneficial if someone from the #TypeScript team could provide any necessary corrections?

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

I'm looking to configure @types for a third-party React JavaScript module in order to use it with TypeScript and bundle it with webpack. How can I accomplish this?

Imagine you have a third-party npm package called @foo that is all Javascript and has a module named bar. Within your TypeScript .tsx file, you want to use the React component @foo/bar/X. However, when you attempt to import X from '@foo/bar/X', y ...

A more efficient method for refreshing Discord Message Embeds using a MessageComponentInteraction collector to streamline updates

Currently, I am working on developing a horse race command for my discord bot using TypeScript. The code is functioning properly; however, there is an issue with updating an embed that displays the race and the participants. To ensure the update works co ...

Angular II slash avoiding Pipe

I am working on developing a customized pipe in Angular 2 that will handle the replacement of the backslash ('\') character in a given string. This backslash is commonly used to escape special characters. What I have accomplished so far: T ...

Tips on setting up an npm package for automatic updates

I recently created a package called https://www.npmjs.com/package/nestjs-notifications After running npm install nestjs-notifications --save, I noticed that it installed successfully but saved the version as: "nestjs-notifications": "0.0.10 ...

Struggling to send information to the data layer on every page in Angular 9

Currently, I am in the process of integrating a GTM snippet into my Angular project. However, I have noticed that when the page is hard reloaded, it pushes data but does not do so during normal navigation. I have already added the GTM snippet provided by ...

How can RootStateOrAny be turned off in React with typescript?

Whenever I need to employ useSelector, I find myself repeating this pattern: const isLoading = useSelector( (state) => state.utils.isLoading ); Is there a shortcut to avoid typing out RootStateOrAny each time? It's starting to become a hassl ...

Move information from one page to another

I'm currently using Ionic 2 and attempting to pass data from one page to another. Specifically, I want to transfer the data of a selected list item from the first page (quickSearch) to the second page (quickSearchDetail). To illustrate this, refer to ...

The constant value being brought in from an internal npm package cannot be determined

I have developed an internal npm package containing shared types and constants. My project is built using TypeScript with "target": "ESNext" and "module": "NodeNext". Within one of my files, I define: export type Su ...

Exploring the syntax of typescript when using createContext

Just starting out with typescript and I have some questions. Could someone break down the syntax used in this code snippet for me? What is the significance of having two groups containing signIn, signOut, and user here? Is the first group responsible fo ...

Is the client component not initializing the fetch operation?

On my page, there is a sidebar that displays items by fetching data successfully. However, when I click on one of the sidebar items to pass props to another component for fetching data, it doesn't fetch any data until I manually click the refresh butt ...

For editing values that have been dynamically inserted

In my JSON data, there is a variable named address that contains multiple objects (i.e., multiple addresses). I am displaying these multiple addresses as shown in the following image: https://i.sstatic.net/1AG34.png When clicking on a specific address ( ...

Validating Date and Time in Angular 6 using ngIf within an HTML template

I am currently utilizing Angular6. Displayed below is the ngfor with a div. The API provides the meeting date and time along with the status, which is usually listed as upcoming. For example, if the date is 09/18/2018 and the time is 5.30 PM. <div cl ...

Customize Angular loaders for individual files

Our current codebase was originally built with Angular, utilizing the Angular CLI and its default webpack configuration. However, as we transition towards using web components, we are faced with the challenge of incorporating SCSS within our web component ...

Changing the appearance of a specific child component in React by referencing its id

There is an interface in my code. export interface DefaultFormList { defaultFormItems?: DefaultFormItems[]; } and export interface DefaultFormItems { id: string; name: string; formXml: string, isDefaultFormEnable: boolean; } I am looking ...

Undefined value is returned for Vue 3 object property

Is there a way to extract additional attributes from the Keycloak object ? Currently, If I try, console.log(keycloak) it will display the entire keycloak object. Even after reloading, it remains in the console. However, when I do, console.log(keycloak.t ...

Identifying Angular 2 templates post-file separation: a step-by-step guide

I am currently trying to figure out how to initiate a project in Angular 2 and have encountered an issue. Following the steps outlined in this Angular 2 guide, I was able to separate my .ts files from .js files by configuring my 'temp' directory ...

Storing user input as an object key in typescript: A comprehensive guide

When delving into Firestore for the first time, I quickly learned that the recommended modeling approach looks something like this: check out the model here members { id: xyz { name: Jones; ...

Issue with Angular UI Bootstrap accordion heading behavior when used in conjunction with a checkbox is causing

I have implemented a checkbox in the header of an accordion control using Bootstrap. However, I am facing an issue where the model only updates the first time the checkbox is clicked. Below is the HTML code for the accordion: <accordion ng-repeat="tim ...

What is the best method for combining two observables into one?

My goal is to initialize a list with 12 users using the URL ${this.url}/users?offset=${offset}&limit=12. As users scroll, the offset should increase by 8. I plan to implement infinite scrolling for this purpose. However, I am facing an issue with appen ...

What is the best way to set State conditionally based on two different objects, each with its own type, without resorting to

I am trying to create two different objects, each with slightly different types, in order for them to be compatible with a state object that contains values of both types. However, I am encountering the following error: Property 'dataA' does no ...