Control what gets generated - Transpilation/Compilation Time version of *ngIf

Viewed 151

The goal is to generate 2 different apps from the same codebase, one for the user and another for the admin. They are very similar, and I just want to disable some blocks. The way I'm tackling this right now via *ngIf and an environment variable

User stuff

<div *ngIf="environment.adminVersion">
   Admin stuff
   <div (click)="adminFunction()"></div>
</div>

The whole point is that I want to make the user version lighter, and all the admin stuff is not required for the user in order to use the app. My question is, are those blocks being removed from the transpiled verson at all?

Is there also a way to achieve this en the logic?

class welcomePage() {
   userFunction() {
   }

   adminFunction() {
      if (environment.adminVersion) { 
         Do admin stuff...
      }
   }
}

Is there a C-preprocessor control equivalent in angular/typescript? What would be the best approach? I guess what I guess I'm looking for is something like this, which gets removed or added before it even compiles:

#define version admin

User stuff

#if version==admin

   Admin stuff
   <div (click)="adminFunction()"></div>

#endif
#if version==admin

class welcomePage() {
   userFunction() {
   }

   #if version==admin
   adminFunction() {
      if (environment.adminVersion) { 
         Do admin stuff...
      }
   }
   #endif
}
4 Answers

This doesn't specifically answer your question, but I believe it solves the same problem.

We use grunt as part of our build process, and we use the grunt-preprocess module to allow us to do exactly what you are attempting to do. It preprocesses your templates and source code to strip out code wrapped in @ifdef/@endif comments based on build variables.

https://github.com/jsoverson/grunt-preprocess

Examples from the docs:

<body>
  <!-- @ifdef DEBUG -->
  <h1>Debugging mode - <!-- @echo RELEASE_TAG --> </h1>
  <!-- @endif -->
  <p>
  <!-- @include welcome_message.txt -->
  </p>
</body>

var configValue = '/* @echo FOO */' || 'default value';

// @ifdef DEBUG
someDebuggingCall()
// @endif

The example is around debugging, but it could easily be used for admin builds as well.

Not sure if you use grunt, but if not, perhaps there is something similar for your build tools.

Hi these are some thought on what you need these might be helpful for you and or for some other therefor I'm leaving this here

  1. If you need to do this with *ngIf the bundle size will not reduce. Because to work *ngIf the code should be there for preparation for both conditions (true/false).

  2. You can use separate modules for both admin and user. Can use lazy modules to reduce bundle size on the first load. (Bundle size in here means what downloads to the browser in the first load)

  3. Still you need to specify which bundle to download first according to the environment variable. Using Auth Guards you can set conditions on your routing or when login you can redirect to specific module part

  4. In this approach, this will not reduce the size of the bundle which get builds but the chunk which downloads to the browser will has an considerable impact on the performance as you desire.

useful links,

Auth Gurds Lazy Loading

This is another solution which is more suitable for your requirement, I was doing this for template based project which was more efficient

As you want to control your templates according to your environment variable I suggest you split your HTML into two parts without *ngIf

For example,

  <div> user </div> <-- user/common.html
  <div> admin </div> <-- admin/common.html

Now you can keep this HTMLs inside your project and before you are building you can copy desired html and build your project. That's it. But there are few complication to achieve.

Complications resolved,

  1. If you are having more than 1 HTML to replace this would make it a exhausting process to copy single one of them. For this you can keep your HTMLs in a different folder but in same file structure as the project. So you can copy and replace. (Replace in the sense you can keep a default template inside the project)
  2. Also you can automate copy/replace scenario with little bit of shell script coding.

This maybe look time consuming but you only have to do this once. And you can keep clean HTML and you would not need to implement separate components or modules only HTMLs would be sufficient.

This is little bit of our of box but suitable for template driven projects that you would not need to change your component files only the HTMLs

If you did not get this method I would love to explain it more.

Related