Is conditional compilation possible with ifdef-loader in combination with Angular 13 and Webpack?

My application built with Ionic heavily relies on conditional compilation, where I need to include or exclude code blocks based on specific config values, similar to the functionality of m4.

Previously, I successfully utilized https://github.com/nippur72/ifdef-loader for this purpose.

Now, I am faced with the task of updating this app from Angular 10 to 13 (and Ionic 5 to 6).

While ifdef-loader worked with Angular 10 after applying a patch (https://gist.github.com/tristanidoux/892469f2c345bd6c6551eb19c705a016) to @angular-dev-kit, the same patch does not seem to work with Angular 13 due to significant file changes.

Therefore, I have been exploring the use of "@angular-builders/custom-webpack": "^13.0.0" following a guide from https://medium.com/angular-in-depth/customizing-angular-cli-build-an-alternative-to-ng-eject-v2-c655768b48cc.

I have created a custom.webpack.config.js file based on the documentation from ifdef-loader:

// ifdef-loader config

const opts = {
   APP: false,
   WEB: true,
   DEBUG: true,
   version: 3,
   "ifdef-verbose": true,
   "ifdef-triple-slash": true,
   "ifdef-fill-with-blanks": true,
   "ifdef-uncomment-prefix": "// #code "
};

module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: [
          { loader: 'ts-loader' },
          { loader: 'ifdef-loader', options: opts }
        ]
      }
    ]
  },

Unfortunately, it seems that ifdef-loader is not being invoked with this setup.

Therefore, I have three questions:

  1. Am I missing something obvious in my configuration?

  2. Has anyone successfully used ifdef-loader with Angular 13? If so, how?

  3. Alternatively, is there another solution for conditionally including/excluding code blocks in an Angular 13 project?

Any advice or suggestions would be highly appreciated.

Answer №1

When exporting webpack configuration as a function from webpack.config.js, it functions properly:

module.exports = (config, options, targetOptions) => {
    const ifdef_opts = {
        DEBUG: config.mode === 'development',
        version: 3,
        "ifdef-verbose": true,                 // include this for detailed output
        "ifdef-triple-slash": false,           // use double slash comment instead of default triple slash
        "ifdef-fill-with-blanks": true,         // remove code with blank spaces instead of "//" comments
        "ifdef-uncomment-prefix": "// #code "  // uncomment code starting with "// #code "
    };
    config.module.rules.some(({test, use}) => {
        if (use && test && 'dummy.ts'.match(test)) {
            use.push({
                loader: "ifdef-loader",
                options: ifdef_opts
            })
            return true;
        }
        return false;
    })

    return config;
};

Answer №2

After struggling for a week, I was unable to figure out how to integrate a module into the typescript compilation process in Angular's webpack setup. As a workaround, I decided to develop a patch for @angular-devkit/build-angular/@ngtools/webpack to directly call ifdef-loader.

You can find the patch here: Angular Webpack Patch

Admittedly, it's not the most elegant solution, but it does the job.

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

Send information through a form by utilizing a personalized React hook

I'm having difficulty understanding how to implement a hook for submitting a form using fetch. Currently, this is what I have. The component containing the form: const MyForm = (): ReactElement => { const [status, data] = useSubmitForm('h ...

Can I assign a value from the tagModel to ngx-chips in an Angular project?

HTML code: <tag-input class="martop20 tag-adder width100 heightauto" [onAdding]="onAdding" (onAdd)="addInternalDomain($event)" type="text" Ts code: addInternalDomain(tagTex ...

TS2304: 'Omit' is a mysterious being that cannot be located

Encountered an issue while compiling my Angular project. This is a project that has remained unchanged for some time and is built daily by Jenkins. However, today it started failing and I'm struggling to determine the cause. ERROR in [at-loader] ./no ...

Parsing of the module has failed due to the presence of an unexpected character '' while attempting to import a video file

Trying to create a video player in NextJS using TS. I brought in a video file from my src/assets folder and encountered an error. Error - ./src/assets/video.mp4 Module parse failed: Unexpected character '' (1:0) You may need an appropriate load ...

What is the best way to globally incorporate tether or any other feature in my Meteor 1.3 TypeScript project?

I've been working hard to get my ng2-prototype up and running in a meteor1.3 environment. Previously, I was using webpack to build the prototype and utilized a provide plugin to make jQuery and Tether available during module building: plugins: [ ne ...

Typescript does not allow for extending an interface with a data property even if both interfaces have the same data type

I've encountered a peculiar problem with Typescript (using Visual Studio 2012 and TypeScript v0.9.5) that I could use some help clarifying. The code snippet below functions correctly: interface IA { data: any; } interface IB { data: any; } ...

Performance challenges with rendering SVG in ngFor due to the presence of a highly nested array structure - in

I'm currently developing a business application that requires me to dynamically render SVG images for displaying floor plans. The SVG elements are stored in a database and provided to the front-end in JSON format, allowing the graphics to be rendered ...

Encountering the "Maximum Update Depth Exceeded" error in React Typescript with hooks

I encountered this error: Uncaught Error: Maximum update depth exceeded. It seems to be related to calling setState multiple times within componentWillUpdate or componentDidUpdate. React limits nested updates to prevent infinite loops. I am unsure of what ...

Why is Typescript converting my keyof type to a never type and what steps can I take to resolve this issue?

Apologies if this question is repetitive, as I am new to TypeScript and struggling to identify related issues due to the complexity of some questions. The issue I'm facing involves TS coercing a type to never, which is confusing me. Here's the sc ...

Error! Element not found in cloned iframe #2460, promise unhandled

Can you help me troubleshoot this issue? This is the code I'm working with: const section = document.createElement("section"); const myHTMLCode = "<p>Greetings</p>"; section.insertAdjacentHTML("afterbegin", my ...

Generate a versatile Union type featuring a mapped property

I am currently working with different types of data enum DataTypes { Email = 'email', Checkbox = 'checkbox', } type DataTypeValues = { [DataTypes.Email]: string; [DataTypes.Checkbox]: boolean; }; type Type1<T extends DataTy ...

Difficulty encountered when converting objects into an array of a model within Angular

Below you will find the service code that I am using: export class ProductListService { constructor(private httpClient: HttpClient) { } getProducts(): Observable<IResponse> { return this.httpClient.get<IResponse>('https://local ...

What is preventing absolute paths from functioning properly in TurboRepo?

After setting up a fresh project on the most recent version of TurboRepo, I ventured into the 'apps' directory and established a new Vite project using the 'react-swc-ts' template. Making tweaks to the 'tsconfig.json' file wit ...

How can you utilize a JavaScript library that provides global variables in Typescript?

I am closely adhering to the guidance provided in the official manual for declaration. Global library // example.js example = 20; Declaration file // example.d.ts declare const let example: number; Implementing the declaration file and library // ind ...

Unable to transfer props object to React component using TypeScript

Apologies if this seems like a basic issue, but I've been struggling with it for the past two days. I'm currently working on writing a simple unit test in Vitest that involves rendering a component to the screen and then using screen.debug(). The ...

Emotion, material-ui, and typescript may lead to excessively deep type instantiation that could potentially be infinite

I encountered an issue when styling a component imported from the Material-UI library using the styled API (@emotion/styled). Error:(19, 5) TS2589: Type instantiation is excessively deep and possibly infinite. Despite attempting to downgrade to typescript ...

I'm baffled by how the community response is implemented in this particular TypeScript exercise on Exercism

I am currently learning TypeScript from scratch by working on exercises available on exercism Successfully completed the 5th exercise on Pangram. Below is my solution: class Pangram { alphabet = "abcdefghijklmnopqrstuvwxyz" constructor(privat ...

When switching tabs, Ion-select should not reload the selected name

Whenever I switch tabs and then return to the previous tab in Ionic, the select field that was previously set becomes null, even though the page is still loading and the variable is populated. <ion-header color="primary"> <ion-navbar> &l ...

NextAuth credentials are undefined and authentication is malfunctioning in React

I encountered the following issue: https://i.sstatic.net/3VBoJ.png This is the code snippet that I am using: return ( <> {Object.values(providers).map((provider) => { if (provider.id === "credentials") { ret ...

I am seeking advice on how to create an extension for a generic class in TypeScript specifically as a getter

Recently, I discovered how to create extensions in TypeScript: interface Array<T> { lastIndex(): number } Array.prototype.lastIndex = function (): number { return this.length - 1 } Now, I want to figure out how to make a getter from it. For exam ...